summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libc/bionic/libc_init_common.cpp8
-rw-r--r--libc/bionic/pthread.c42
-rw-r--r--libc/bionic/pthread_attr.cpp18
-rw-r--r--libc/bionic/pthread_internal.h4
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;