diff options
-rw-r--r-- | libc/bionic/libc_init_common.cpp | 8 | ||||
-rw-r--r-- | libc/bionic/pthread.c | 42 | ||||
-rw-r--r-- | libc/bionic/pthread_attr.cpp | 18 | ||||
-rw-r--r-- | libc/bionic/pthread_internal.h | 4 |
4 files changed, 31 insertions, 41 deletions
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp index 881b091..266d6fa 100644 --- a/libc/bionic/libc_init_common.cpp +++ b/libc/bionic/libc_init_common.cpp @@ -73,12 +73,10 @@ void __libc_init_tls(KernelArgumentBlock& args) { unsigned stack_size = 128 * 1024; unsigned stack_bottom = stack_top - stack_size; - pthread_attr_t thread_attr; - pthread_attr_init(&thread_attr); - pthread_attr_setstack(&thread_attr, (void*) stack_bottom, stack_size); - static pthread_internal_t thread; - _init_thread(&thread, gettid(), &thread_attr, (void*) stack_bottom, false); + pthread_attr_init(&thread.attr); + pthread_attr_setstack(&thread.attr, (void*) stack_bottom, stack_size); + _init_thread(&thread, gettid(), false); static void* tls_area[BIONIC_TLS_SLOTS]; __init_tls(tls_area, &thread); diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index bdf2b87..3564c73 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -181,20 +181,11 @@ void __thread_entry(int (*func)(void*), void *arg, void **tls) #include <private/logd.h> __LIBC_ABI_PRIVATE__ -int _init_thread(pthread_internal_t* thread, pid_t kernel_id, const pthread_attr_t* attr, - void* stack_base, bool add_to_thread_list) -{ +int _init_thread(pthread_internal_t* thread, pid_t kernel_id, bool add_to_thread_list) { int error = 0; - thread->attr = *attr; - thread->attr.stack_base = stack_base; thread->kernel_id = kernel_id; - // Make a note of whether the user supplied this stack (so we know whether or not to free it). - if (attr->stack_base == stack_base) { - thread->attr.flags |= PTHREAD_ATTR_FLAG_USER_STACK; - } - // Set the scheduling policy/priority of the thread. if (thread->attr.sched_policy != SCHED_NORMAL) { struct sched_param param; @@ -285,22 +276,29 @@ int pthread_create(pthread_t *thread_out, pthread_attr_t const * attr, thread->allocated_on_heap = true; if (attr == NULL) { - attr = &gDefaultPthreadAttr; + pthread_attr_init(&thread->attr); + } else { + thread->attr = *attr; + attr = NULL; // Prevent misuse below. } - // make sure the stack is PAGE_SIZE aligned - size_t stack_size = (attr->stack_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); - uint8_t* stack = attr->stack_base; - if (stack == NULL) { - stack = mkstack(stack_size, attr->guard_size); - if (stack == NULL) { + // Make sure the stack size is PAGE_SIZE aligned. + size_t stack_size = (thread->attr.stack_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 = mkstack(stack_size, thread->attr.guard_size); + 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; } - // Make room for TLS - void** tls = (void**)(stack + stack_size - BIONIC_TLS_SLOTS*sizeof(void*)); + // Make room for TLS. + void** tls = (void**)((uint8_t*)(thread->attr.stack_base) + stack_size - BIONIC_TLS_SLOTS * sizeof(void*)); // Create a mutex for the thread in TLS_SLOT_SELF to wait on once it starts so we can keep // it from doing anything until after we notify the debugger about it @@ -321,15 +319,15 @@ int pthread_create(pthread_t *thread_out, pthread_attr_t const * attr, if (tid < 0) { int clone_errno = errno; pthread_mutex_unlock(start_mutex); - if (stack != attr->stack_base) { - munmap(stack, stack_size); + if ((thread->attr.flags & PTHREAD_ATTR_FLAG_USER_STACK) == 0) { + munmap(thread->attr.stack_base, stack_size); } free(thread); errno = old_errno; return clone_errno; } - int init_errno = _init_thread(thread, tid, attr, stack, true); + int init_errno = _init_thread(thread, tid, true); if (init_errno != 0) { // Mark the thread detached and let its __thread_entry run to // completion. (It'll just exit immediately, cleaning up its resources.) diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp index 831a28e..c47f95e 100644 --- a/libc/bionic/pthread_attr.cpp +++ b/libc/bionic/pthread_attr.cpp @@ -30,19 +30,15 @@ #include "pthread_internal.h" -#define DEFAULT_STACKSIZE (1024 * 1024) - -const pthread_attr_t gDefaultPthreadAttr = { - .flags = 0, - .stack_base = NULL, - .stack_size = DEFAULT_STACKSIZE, - .guard_size = PAGE_SIZE, - .sched_policy = SCHED_NORMAL, - .sched_priority = 0 -}; +#define DEFAULT_STACK_SIZE (1024 * 1024) int pthread_attr_init(pthread_attr_t* attr) { - *attr = gDefaultPthreadAttr; + attr->flags = 0; + attr->stack_base = NULL; + attr->stack_size = DEFAULT_STACK_SIZE; + attr->guard_size = PAGE_SIZE; + attr->sched_policy = SCHED_NORMAL; + attr->sched_priority = 0; return 0; } diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h index 63071d9..a17c37d 100644 --- a/libc/bionic/pthread_internal.h +++ b/libc/bionic/pthread_internal.h @@ -55,8 +55,7 @@ typedef struct pthread_internal_t char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE]; } pthread_internal_t; -int _init_thread(pthread_internal_t* thread, pid_t kernel_id, const pthread_attr_t* attr, - void* stack_base, bool add_to_thread_list); +int _init_thread(pthread_internal_t* thread, pid_t kernel_id, bool add_to_thread_list); void _pthread_internal_add( pthread_internal_t* thread ); pthread_internal_t* __get_thread(void); @@ -65,7 +64,6 @@ __LIBC_HIDDEN__ void pthread_key_clean_all(void); #define PTHREAD_ATTR_FLAG_DETACHED 0x00000001 #define PTHREAD_ATTR_FLAG_USER_STACK 0x00000002 -extern __LIBC_HIDDEN__ const pthread_attr_t gDefaultPthreadAttr; extern pthread_internal_t* gThreadList; extern pthread_mutex_t gThreadListLock; |