am 991ee7d8
: Merge "Simplify pthread_create, using more public API."
# Via Elliott Hughes (1) and Gerrit Code Review (1) * commit '991ee7d89574e8d04c8863a2850613073a2f96b3': Simplify pthread_create, using more public API.
This commit is contained in:
commit
dde1d876b1
@ -73,12 +73,10 @@ void __libc_init_tls(KernelArgumentBlock& args) {
|
|||||||
unsigned stack_size = 128 * 1024;
|
unsigned stack_size = 128 * 1024;
|
||||||
unsigned stack_bottom = stack_top - stack_size;
|
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;
|
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];
|
static void* tls_area[BIONIC_TLS_SLOTS];
|
||||||
__init_tls(tls_area, &thread);
|
__init_tls(tls_area, &thread);
|
||||||
|
@ -181,20 +181,11 @@ void __thread_entry(int (*func)(void*), void *arg, void **tls)
|
|||||||
#include <private/logd.h>
|
#include <private/logd.h>
|
||||||
|
|
||||||
__LIBC_ABI_PRIVATE__
|
__LIBC_ABI_PRIVATE__
|
||||||
int _init_thread(pthread_internal_t* thread, pid_t kernel_id, const pthread_attr_t* attr,
|
int _init_thread(pthread_internal_t* thread, pid_t kernel_id, bool add_to_thread_list) {
|
||||||
void* stack_base, bool add_to_thread_list)
|
|
||||||
{
|
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
thread->attr = *attr;
|
|
||||||
thread->attr.stack_base = stack_base;
|
|
||||||
thread->kernel_id = kernel_id;
|
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.
|
// Set the scheduling policy/priority of the thread.
|
||||||
if (thread->attr.sched_policy != SCHED_NORMAL) {
|
if (thread->attr.sched_policy != SCHED_NORMAL) {
|
||||||
struct sched_param param;
|
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;
|
thread->allocated_on_heap = true;
|
||||||
|
|
||||||
if (attr == NULL) {
|
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
|
// Make sure the stack size is PAGE_SIZE aligned.
|
||||||
size_t stack_size = (attr->stack_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
|
size_t stack_size = (thread->attr.stack_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
|
||||||
uint8_t* stack = attr->stack_base;
|
|
||||||
if (stack == NULL) {
|
if (thread->attr.stack_base == NULL) {
|
||||||
stack = mkstack(stack_size, attr->guard_size);
|
// The caller didn't provide a stack, so allocate one.
|
||||||
if (stack == NULL) {
|
thread->attr.stack_base = mkstack(stack_size, thread->attr.guard_size);
|
||||||
|
if (thread->attr.stack_base == NULL) {
|
||||||
free(thread);
|
free(thread);
|
||||||
return EAGAIN;
|
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
|
// Make room for TLS.
|
||||||
void** tls = (void**)(stack + stack_size - BIONIC_TLS_SLOTS*sizeof(void*));
|
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
|
// 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
|
// 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) {
|
if (tid < 0) {
|
||||||
int clone_errno = errno;
|
int clone_errno = errno;
|
||||||
pthread_mutex_unlock(start_mutex);
|
pthread_mutex_unlock(start_mutex);
|
||||||
if (stack != attr->stack_base) {
|
if ((thread->attr.flags & PTHREAD_ATTR_FLAG_USER_STACK) == 0) {
|
||||||
munmap(stack, stack_size);
|
munmap(thread->attr.stack_base, stack_size);
|
||||||
}
|
}
|
||||||
free(thread);
|
free(thread);
|
||||||
errno = old_errno;
|
errno = old_errno;
|
||||||
return clone_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) {
|
if (init_errno != 0) {
|
||||||
// Mark the thread detached and let its __thread_entry run to
|
// Mark the thread detached and let its __thread_entry run to
|
||||||
// completion. (It'll just exit immediately, cleaning up its resources.)
|
// completion. (It'll just exit immediately, cleaning up its resources.)
|
||||||
|
@ -30,19 +30,15 @@
|
|||||||
|
|
||||||
#include "pthread_internal.h"
|
#include "pthread_internal.h"
|
||||||
|
|
||||||
#define DEFAULT_STACKSIZE (1024 * 1024)
|
#define DEFAULT_STACK_SIZE (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
|
|
||||||
};
|
|
||||||
|
|
||||||
int pthread_attr_init(pthread_attr_t* attr) {
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +55,7 @@ typedef struct pthread_internal_t
|
|||||||
char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
|
char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
|
||||||
} pthread_internal_t;
|
} pthread_internal_t;
|
||||||
|
|
||||||
int _init_thread(pthread_internal_t* thread, pid_t kernel_id, const pthread_attr_t* attr,
|
int _init_thread(pthread_internal_t* thread, pid_t kernel_id, bool add_to_thread_list);
|
||||||
void* stack_base, bool add_to_thread_list);
|
|
||||||
void _pthread_internal_add( pthread_internal_t* thread );
|
void _pthread_internal_add( pthread_internal_t* thread );
|
||||||
pthread_internal_t* __get_thread(void);
|
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_DETACHED 0x00000001
|
||||||
#define PTHREAD_ATTR_FLAG_USER_STACK 0x00000002
|
#define PTHREAD_ATTR_FLAG_USER_STACK 0x00000002
|
||||||
|
|
||||||
extern __LIBC_HIDDEN__ const pthread_attr_t gDefaultPthreadAttr;
|
|
||||||
extern pthread_internal_t* gThreadList;
|
extern pthread_internal_t* gThreadList;
|
||||||
extern pthread_mutex_t gThreadListLock;
|
extern pthread_mutex_t gThreadListLock;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user