记录一下最近看android bionic pthread相关源码的理解
这里以android kikat bionic为例
先看一下pthread_create函数源码
int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr,
void* (*start_routine)(void*), void* arg) {
ErrnoRestorer errno_restorer;
// Inform the rest of the C library that at least one thread
// was created. This will enforce certain functions to acquire/release
// locks (e.g. atexit()) to protect shared global structures.
// This works because pthread_create() is not called by the C library
// initialization routine that sets up the main thread's data structures.
__isthreaded = 1;
pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(calloc(sizeof(*thread), 1)); 使用calloc创建thread结构体,初始化为0
if (thread == NULL) {
__libc_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: couldn't allocate thread");
return EAGAIN;
}
thread->allocated_on_heap = true; 标记thread结构体是在heap上创建的,也提示了之后不使用的时候要用free去销毁
if (attr == NULL) {
pthread_attr_init(&thread->attr); 如果创建线程没有指定attr则使用default的attr
} else {
thread->attr = *attr; 如果有指定attr,则使用指定的attr
attr = NULL; // Prevent misuse below.
}
// Make sure the stack size and guard size are multiples of PAGE_SIZE.
thread->attr.stack_size = (thread->attr.stack_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
thread->attr.guard_size = (thread->attr.guard_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
if (thread->attr.stack_base == NULL) {
// The caller didn't provide a stack, so allocate one.
thread->attr.stack_base = __create_thread_stack(thread); 如果没有指定attr的stack_base,那么自己创建一个
if (thread->attr.stack_base == NULL) {
free(thread);
return EAGAIN;
}
} else {
// The caller did provide a stack, so remember we're not supposed to free it.
thread->attr.flags |= PTHREAD_ATTR_FLAG_USER_STACK; 指定一个flag,之后由user自己释放这块地址
}
// Make room for the TLS