Procházet zdrojové kódy

implement pthread_getattr_np

this function is mainly (purely?) for obtaining stack address
information, but we also provide the detach state since it's easy to
do anyway.
Rich Felker před 12 roky
rodič
revize
14a835b386

+ 2 - 0
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;

+ 8 - 2
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;

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