浏览代码

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