فهرست منبع

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 12 سال پیش
والد
کامیت
14a835b386
3فایلهای تغییر یافته به همراه31 افزوده شده و 2 حذف شده
  1. 2 0
      src/internal/pthread_impl.h
  2. 8 2
      src/thread/pthread_create.c
  3. 21 0
      src/thread/pthread_getattr_np.c

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