Changeset View
Changeset View
Standalone View
Standalone View
lib/libthr/thread/thr_init.c
Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
#include <string.h> | #include <string.h> | ||||
#include <time.h> | #include <time.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include "un-namespace.h" | #include "un-namespace.h" | ||||
#include "libc_private.h" | #include "libc_private.h" | ||||
#include "thr_private.h" | #include "thr_private.h" | ||||
char *_stacktop; | char *_usrstack; | ||||
struct pthread *_thr_initial; | struct pthread *_thr_initial; | ||||
int _libthr_debug; | int _libthr_debug; | ||||
int _thread_event_mask; | int _thread_event_mask; | ||||
struct pthread *_thread_last_event; | struct pthread *_thread_last_event; | ||||
pthreadlist _thread_list = TAILQ_HEAD_INITIALIZER(_thread_list); | pthreadlist _thread_list = TAILQ_HEAD_INITIALIZER(_thread_list); | ||||
pthreadlist _thread_gc_list = TAILQ_HEAD_INITIALIZER(_thread_gc_list); | pthreadlist _thread_gc_list = TAILQ_HEAD_INITIALIZER(_thread_gc_list); | ||||
int _thread_active_threads = 1; | int _thread_active_threads = 1; | ||||
atfork_head _thr_atfork_list = TAILQ_HEAD_INITIALIZER(_thr_atfork_list); | atfork_head _thr_atfork_list = TAILQ_HEAD_INITIALIZER(_thr_atfork_list); | ||||
▲ Show 20 Lines • Show All 310 Lines • ▼ Show 20 Lines | init_main_thread(struct pthread *thread) | ||||
* Set up the thread stack. | * Set up the thread stack. | ||||
* | * | ||||
* Create a red zone below the main stack. All other stacks | * Create a red zone below the main stack. All other stacks | ||||
* are constrained to a maximum size by the parameters | * are constrained to a maximum size by the parameters | ||||
* passed to mmap(), but this stack is only limited by | * passed to mmap(), but this stack is only limited by | ||||
* resource limits, so this stack needs an explicitly mapped | * resource limits, so this stack needs an explicitly mapped | ||||
* red zone to protect the thread stack that is just beyond. | * red zone to protect the thread stack that is just beyond. | ||||
*/ | */ | ||||
if (mmap(_stacktop - _thr_stack_initial - | if (mmap(_usrstack - _thr_stack_initial - | ||||
_thr_guard_default, _thr_guard_default, 0, MAP_ANON, | _thr_guard_default, _thr_guard_default, 0, MAP_ANON, | ||||
-1, 0) == MAP_FAILED) | -1, 0) == MAP_FAILED) | ||||
PANIC("Cannot allocate red zone for initial thread"); | PANIC("Cannot allocate red zone for initial thread"); | ||||
/* | /* | ||||
* Mark the stack as an application supplied stack so that it | * Mark the stack as an application supplied stack so that it | ||||
* isn't deallocated. | * isn't deallocated. | ||||
* | * | ||||
* XXX - I'm not sure it would hurt anything to deallocate | * XXX - I'm not sure it would hurt anything to deallocate | ||||
* the main thread stack because deallocation doesn't | * the main thread stack because deallocation doesn't | ||||
* actually free() it; it just puts it in the free | * actually free() it; it just puts it in the free | ||||
* stack queue for later reuse. | * stack queue for later reuse. | ||||
*/ | */ | ||||
thread->attr.stackaddr_attr = _stacktop - _thr_stack_initial; | thread->attr.stackaddr_attr = _usrstack - _thr_stack_initial; | ||||
thread->attr.stacksize_attr = _thr_stack_initial; | thread->attr.stacksize_attr = _thr_stack_initial; | ||||
thread->attr.guardsize_attr = _thr_guard_default; | thread->attr.guardsize_attr = _thr_guard_default; | ||||
thread->attr.flags |= THR_STACK_USER; | thread->attr.flags |= THR_STACK_USER; | ||||
/* | /* | ||||
* Write a magic value to the thread structure | * Write a magic value to the thread structure | ||||
* to help identify valid ones: | * to help identify valid ones: | ||||
*/ | */ | ||||
thread->magic = THR_MAGIC; | thread->magic = THR_MAGIC; | ||||
thread->cancel_enable = 1; | thread->cancel_enable = 1; | ||||
thread->cancel_async = 0; | thread->cancel_async = 0; | ||||
/* Initialize the mutex queues */ | /* Initialize the mutex queues */ | ||||
for (i = 0; i < TMQ_NITEMS; i++) | for (i = 0; i < TMQ_NITEMS; i++) | ||||
TAILQ_INIT(&thread->mq[i]); | TAILQ_INIT(&thread->mq[i]); | ||||
thread->state = PS_RUNNING; | thread->state = PS_RUNNING; | ||||
_thr_getscheduler(thread->tid, &thread->attr.sched_policy, | _thr_getscheduler(thread->tid, &thread->attr.sched_policy, | ||||
&sched_param); | &sched_param); | ||||
thread->attr.prio = sched_param.sched_priority; | thread->attr.prio = sched_param.sched_priority; | ||||
#ifdef _PTHREAD_FORCED_UNWIND | #ifdef _PTHREAD_FORCED_UNWIND | ||||
thread->unwind_stackend = _stacktop; | thread->unwind_stackend = _usrstack; | ||||
#endif | #endif | ||||
/* Others cleared to zero by thr_alloc() */ | /* Others cleared to zero by thr_alloc() */ | ||||
} | } | ||||
static void | static void | ||||
init_private(void) | init_private(void) | ||||
{ | { | ||||
Show All 20 Lines | init_private(void) | ||||
* Avoid reinitializing some things if they don't need to be, | * Avoid reinitializing some things if they don't need to be, | ||||
* e.g. after a fork(). | * e.g. after a fork(). | ||||
*/ | */ | ||||
if (init_once == 0) { | if (init_once == 0) { | ||||
__thr_pshared_init(); | __thr_pshared_init(); | ||||
__thr_malloc_init(); | __thr_malloc_init(); | ||||
/* Find the stack top */ | /* Find the stack top */ | ||||
mib[0] = CTL_KERN; | mib[0] = CTL_KERN; | ||||
mib[1] = KERN_STACKTOP; | |||||
len = sizeof (_stacktop); | |||||
if (sysctl(mib, 2, &_stacktop, &len, NULL, 0) == -1) { | |||||
mib[1] = KERN_USRSTACK; | mib[1] = KERN_USRSTACK; | ||||
if (sysctl(mib, 2, &_stacktop, &len, NULL, 0) == -1) | len = sizeof (_usrstack); | ||||
if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1) | |||||
PANIC("Cannot get kern.usrstack from sysctl"); | PANIC("Cannot get kern.usrstack from sysctl"); | ||||
} | |||||
env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN"); | env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN"); | ||||
env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN"); | env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN"); | ||||
if (env_bigstack != NULL || env_splitstack == NULL) { | if (env_bigstack != NULL || env_splitstack == NULL) { | ||||
if (getrlimit(RLIMIT_STACK, &rlim) == -1) | if (getrlimit(RLIMIT_STACK, &rlim) == -1) | ||||
PANIC("Cannot get stack rlimit"); | PANIC("Cannot get stack rlimit"); | ||||
_thr_stack_initial = rlim.rlim_cur; | _thr_stack_initial = rlim.rlim_cur; | ||||
} | } | ||||
_thr_is_smp = sysconf(_SC_NPROCESSORS_CONF); | _thr_is_smp = sysconf(_SC_NPROCESSORS_CONF); | ||||
Show All 20 Lines |