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; +} | 
