diff options
-rw-r--r-- | src/internal/pthread_impl.h | 2 | ||||
-rw-r--r-- | src/thread/pthread_create.c | 10 | ||||
-rw-r--r-- | src/thread/pthread_getattr_np.c | 21 |
3 files changed, 31 insertions, 2 deletions
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index 2086048d..78b69cde 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -23,6 +23,8 @@ struct pthread { int detached; unsigned char *map_base; size_t map_size; + void *stack; + size_t stack_size; void *start_arg; void *(*start)(void *); void *result; diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 059c20e7..6163f509 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -101,7 +101,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp int ret; size_t size, guard; struct pthread *self = pthread_self(), *new; - unsigned char *map = 0, *stack = 0, *tsd = 0; + unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit; unsigned flags = 0x7d8f00; int do_sched = 0; pthread_attr_t attr = {0}; @@ -123,6 +123,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp size_t need = libc.tls_size + __pthread_tsd_size; size = attr._a_stacksize + DEFAULT_STACK_SIZE; stack = (void *)(attr._a_stackaddr & -16); + stack_limit = attr._a_stackaddr - size; /* Use application-provided stack for TLS only when * it does not take more than ~12% or 2k of the * application's stack space. */ @@ -152,12 +153,17 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp if (map == MAP_FAILED) goto fail; } tsd = map + size - __pthread_tsd_size; - if (!stack) stack = tsd - libc.tls_size; + if (!stack) { + stack = tsd - libc.tls_size; + stack_limit = map + guard; + } } new = __copy_tls(tsd - libc.tls_size); new->map_base = map; new->map_size = size; + new->stack = stack; + new->stack_size = stack - stack_limit; new->pid = self->pid; new->errno_ptr = &new->errno_val; new->start = entry; diff --git a/src/thread/pthread_getattr_np.c b/src/thread/pthread_getattr_np.c new file mode 100644 index 00000000..945242b7 --- /dev/null +++ b/src/thread/pthread_getattr_np.c @@ -0,0 +1,21 @@ +#include "pthread_impl.h" +#include <sys/mman.h> + +int pthread_getattr_np(pthread_t t, pthread_attr_t *a) +{ + *a = (pthread_attr_t){0}; + a->_a_detach = !!t->detached; + if (t->stack) { + a->_a_stackaddr = (uintptr_t)t->stack; + a->_a_stacksize = t->stack_size - DEFAULT_STACK_SIZE; + } else { + char *p = (void *)libc.auxv; + size_t l = PAGE_SIZE; + p += -(uintptr_t)p & PAGE_SIZE-1; + a->_a_stackaddr = (uintptr_t)p; + while (!posix_madvise(p-l-PAGE_SIZE, PAGE_SIZE, POSIX_MADV_NORMAL)) + l += PAGE_SIZE; + a->_a_stacksize = l - DEFAULT_STACK_SIZE; + } + return 0; +} |