Changeset View
Changeset View
Standalone View
Standalone View
lib/libthr/thread/thr_stack.c
Show First 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | mprotect((char *)thrd->attr.stackaddr_attr + | ||||
_rtld_get_stack_prot()); | _rtld_get_stack_prot()); | ||||
} | } | ||||
static void | static void | ||||
singlethread_map_stacks_exec(void) | singlethread_map_stacks_exec(void) | ||||
{ | { | ||||
int mib[2]; | int mib[2]; | ||||
struct rlimit rlim; | struct rlimit rlim; | ||||
u_long stacktop; | u_long usrstack; | ||||
size_t len; | size_t len; | ||||
mib[0] = CTL_KERN; | mib[0] = CTL_KERN; | ||||
mib[1] = KERN_STACKTOP; | |||||
len = sizeof(stacktop); | |||||
if (sysctl(mib, nitems(mib), &stacktop, &len, NULL, 0) == -1) { | |||||
mib[1] = KERN_USRSTACK; | mib[1] = KERN_USRSTACK; | ||||
if (sysctl(mib, nitems(mib), &stacktop, &len, NULL, 0) == -1) | len = sizeof(usrstack); | ||||
if (sysctl(mib, nitems(mib), &usrstack, &len, NULL, 0) == -1) | |||||
return; | return; | ||||
} | |||||
if (getrlimit(RLIMIT_STACK, &rlim) == -1) | if (getrlimit(RLIMIT_STACK, &rlim) == -1) | ||||
return; | return; | ||||
mprotect((void *)(uintptr_t)(stacktop - rlim.rlim_cur), | mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur), | ||||
rlim.rlim_cur, _rtld_get_stack_prot()); | rlim.rlim_cur, _rtld_get_stack_prot()); | ||||
} | } | ||||
void | void | ||||
__thr_map_stacks_exec(void) | __thr_map_stacks_exec(void) | ||||
{ | { | ||||
struct pthread *curthread, *thrd; | struct pthread *curthread, *thrd; | ||||
struct stack *st; | struct stack *st; | ||||
Show All 36 Lines | _thr_stack_alloc(struct pthread_attr *attr) | ||||
stacksize = round_up(attr->stacksize_attr); | stacksize = round_up(attr->stacksize_attr); | ||||
guardsize = round_up(attr->guardsize_attr); | guardsize = round_up(attr->guardsize_attr); | ||||
attr->stackaddr_attr = NULL; | attr->stackaddr_attr = NULL; | ||||
attr->flags &= ~THR_STACK_USER; | attr->flags &= ~THR_STACK_USER; | ||||
/* | /* | ||||
* Use the garbage collector lock for synchronization of the | * Use the garbage collector lock for synchronization of the | ||||
* spare stack lists and allocations from stacktop. | * spare stack lists and allocations from usrstack. | ||||
*/ | */ | ||||
THREAD_LIST_WRLOCK(curthread); | THREAD_LIST_WRLOCK(curthread); | ||||
/* | /* | ||||
* If the stack and guard sizes are default, try to allocate a stack | * If the stack and guard sizes are default, try to allocate a stack | ||||
* from the default-size stack cache: | * from the default-size stack cache: | ||||
*/ | */ | ||||
if ((stacksize == THR_STACK_DEFAULT) && | if ((stacksize == THR_STACK_DEFAULT) && | ||||
(guardsize == _thr_guard_default)) { | (guardsize == _thr_guard_default)) { | ||||
Show All 19 Lines | else { | ||||
} | } | ||||
} | } | ||||
if (attr->stackaddr_attr != NULL) { | if (attr->stackaddr_attr != NULL) { | ||||
/* A cached stack was found. Release the lock. */ | /* A cached stack was found. Release the lock. */ | ||||
THREAD_LIST_UNLOCK(curthread); | THREAD_LIST_UNLOCK(curthread); | ||||
} | } | ||||
else { | else { | ||||
/* | /* | ||||
* Allocate a stack from or below stacktop, depending | * Allocate a stack from or below usrstack, depending | ||||
* on the LIBPTHREAD_BIGSTACK_MAIN env variable. | * on the LIBPTHREAD_BIGSTACK_MAIN env variable. | ||||
*/ | */ | ||||
if (last_stack == NULL) | if (last_stack == NULL) | ||||
last_stack = _stacktop - _thr_stack_initial - | last_stack = _usrstack - _thr_stack_initial - | ||||
_thr_guard_default; | _thr_guard_default; | ||||
/* Allocate a new stack. */ | /* Allocate a new stack. */ | ||||
stackaddr = last_stack - stacksize - guardsize; | stackaddr = last_stack - stacksize - guardsize; | ||||
/* | /* | ||||
* Even if stack allocation fails, we don't want to try to | * Even if stack allocation fails, we don't want to try to | ||||
* use this location again, so unconditionally decrement | * use this location again, so unconditionally decrement | ||||
▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines |