Module Name: src Committed By: joerg Date: Fri Mar 2 18:06:06 UTC 2012
Modified Files: src/lib/libpthread: pthread.c pthread_attr.c pthread_int.h Log Message: Separate pthread_t from thread stack. Drop additional alignment restrictions on the thread stack. Remove remaining parts of stackid. To generate a diff of this commit: cvs rdiff -u -r1.125 -r1.126 src/lib/libpthread/pthread.c cvs rdiff -u -r1.15 -r1.16 src/lib/libpthread/pthread_attr.c cvs rdiff -u -r1.82 -r1.83 src/lib/libpthread/pthread_int.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libpthread/pthread.c diff -u src/lib/libpthread/pthread.c:1.125 src/lib/libpthread/pthread.c:1.126 --- src/lib/libpthread/pthread.c:1.125 Sun Oct 2 18:18:56 2011 +++ src/lib/libpthread/pthread.c Fri Mar 2 18:06:05 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread.c,v 1.125 2011/10/02 18:18:56 christos Exp $ */ +/* $NetBSD: pthread.c,v 1.126 2012/03/02 18:06:05 joerg Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -30,16 +30,19 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread.c,v 1.125 2011/10/02 18:18:56 christos Exp $"); +__RCSID("$NetBSD: pthread.c,v 1.126 2012/03/02 18:06:05 joerg Exp $"); #define __EXPOSE_STACK 1 #include <sys/param.h> +#include <sys/exec_elf.h> #include <sys/mman.h> #include <sys/sysctl.h> #include <sys/lwpctl.h> #include <sys/tls.h> +#include <assert.h> +#include <dlfcn.h> #include <err.h> #include <errno.h> #include <lwp.h> @@ -66,8 +69,6 @@ RB_PROTOTYPE_STATIC(__pthread__alltree, static void pthread__create_tramp(void *); static void pthread__initthread(pthread_t); static void pthread__scrubthread(pthread_t, char *, int); -static int pthread__stackid_setup(void *, size_t, pthread_t *); -static int pthread__stackalloc(pthread_t *); static void pthread__initmain(pthread_t *); static void pthread__fork_callback(void); static void pthread__reap(pthread_t); @@ -105,14 +106,9 @@ int pthread__dbg; /* set by libpthread_d * pointer to the thread data, it is safe to change the mapping from * stack pointer to thread data afterwards. */ -#define _STACKSIZE_LG 18 -int pthread__stacksize_lg = _STACKSIZE_LG; -size_t pthread__stacksize = 1 << _STACKSIZE_LG; -vaddr_t pthread__stackmask = (1 << _STACKSIZE_LG) - 1; -vaddr_t pthread__threadmask = (vaddr_t)~((1 << _STACKSIZE_LG) - 1); -vaddr_t pthread__mainbase = 0; -vaddr_t pthread__mainstruct = 0; -#undef _STACKSIZE_LG +size_t pthread__stacksize; +size_t pthread__pagesize; +static struct __pthread_st pthread__main; int _sys___sigprocmask14(int, const sigset_t *, sigset_t *); @@ -162,6 +158,8 @@ pthread__init(void) size_t len; extern int __isthreaded; + pthread__pagesize = (size_t)sysconf(_SC_PAGESIZE); + mib[0] = CTL_HW; mib[1] = HW_NCPU; @@ -318,6 +316,28 @@ pthread__scrubthread(pthread_t t, char * t->pt_lid = 0; } +static int +pthread__newstack(pthread_t newthread) +{ + void *stackbase, *redzone; + + stackbase = mmap(NULL, pthread__stacksize, + PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, (off_t)0); + if (stackbase == MAP_FAILED) + return ENOMEM; + newthread->pt_stack.ss_size = pthread__stacksize - pthread__pagesize; + newthread->pt_stack.ss_sp = stackbase; +#ifdef __MACHINE_STACK_GROWS_UP + redzone = (char *)stackbase + newthread->pt_stack.ss_size; +#else + redzone = (char *)stackbase; +#endif + if (mprotect(redzone, pthread__pagesize, PROT_NONE) == -1) { + munmap(stackbase, pthread__stacksize); + return EPERM; + } + return 0; +} int pthread_create(pthread_t *thread, const pthread_attr_t *attr, @@ -385,18 +405,20 @@ pthread_create(pthread_t *thread, const * and initialize it. */ if (newthread == NULL) { - ret = pthread__stackalloc(&newthread); - if (ret != 0) { - if (name) - free(name); - return ret; + newthread = malloc(sizeof(*newthread)); + if (newthread == NULL) { + free(name); + return ENOMEM; + } + + if (pthread__newstack(newthread)) { + free(newthread); + free(name); + return ENOMEM; } /* This is used only when creating the thread. */ _INITCONTEXT_U(&newthread->pt_uc); -#ifdef PTHREAD_MACHINE_HAS_ID_REGISTER - pthread__uc_id(&newthread->pt_uc) = newthread; -#endif newthread->pt_uc.uc_stack = newthread->pt_stack; newthread->pt_uc.uc_link = NULL; #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II) @@ -1175,28 +1197,26 @@ pthread__unpark_all(pthread_queue_t *que #undef OOPS -/* - * Allocate a stack for a thread, and set it up. It needs to be aligned, so - * that a thread can find itself by its stack pointer. - */ -static int -pthread__stackalloc(pthread_t *newt) +static void +pthread__initmainstack(void) { - void *addr; - - addr = mmap(NULL, pthread__stacksize, PROT_READ|PROT_WRITE, - MAP_ANON|MAP_PRIVATE | MAP_ALIGNED(pthread__stacksize_lg), - -1, (off_t)0); + struct rlimit slimit; + const AuxInfo *aux; - if (addr == MAP_FAILED) - return ENOMEM; + _DIAGASSERT(_dlauxinfo() != NULL); - pthread__assert(((intptr_t)addr & pthread__stackmask) == 0); + if (getrlimit(RLIMIT_STACK, &slimit) == -1) + err(1, "Couldn't get stack resource consumption limits"); + pthread__main.pt_stack.ss_size = slimit.rlim_cur; - return pthread__stackid_setup(addr, pthread__stacksize, newt); + for (aux = _dlauxinfo(); aux->a_type != AT_NULL; ++aux) { + if (aux->a_type == AT_STACKBASE) { + pthread__main.pt_stack.ss_sp = (void *)aux->a_v; + break; + } + } } - /* * Set up the slightly special stack for the "initial" thread, which * runs on the normal system stack, and thus gets slightly different @@ -1205,102 +1225,33 @@ pthread__stackalloc(pthread_t *newt) static void pthread__initmain(pthread_t *newt) { - struct rlimit slimit; - size_t pagesize; - pthread_t t; - void *base; - size_t size; - int error, ret; char *value; - pagesize = (size_t)sysconf(_SC_PAGESIZE); - pthread__stacksize = 0; - ret = getrlimit(RLIMIT_STACK, &slimit); - if (ret == -1) - err(1, "Couldn't get stack resource consumption limits"); + pthread__initmainstack(); value = pthread__getenv("PTHREAD_STACKSIZE"); if (value != NULL) { pthread__stacksize = atoi(value) * 1024; - if (pthread__stacksize > slimit.rlim_cur) - pthread__stacksize = (size_t)slimit.rlim_cur; + if (pthread__stacksize > pthread__main.pt_stack.ss_size) + pthread__stacksize = pthread__main.pt_stack.ss_size; } if (pthread__stacksize == 0) - pthread__stacksize = (size_t)slimit.rlim_cur; - if (pthread__stacksize < 4 * pagesize) + pthread__stacksize = pthread__main.pt_stack.ss_size; + pthread__stacksize += pthread__pagesize - 1; + pthread__stacksize &= ~pthread__pagesize; + if (pthread__stacksize < 4 * pthread__pagesize) errx(1, "Stacksize limit is too low, minimum %zd kbyte.", - 4 * pagesize / 1024); - - pthread__stacksize_lg = -1; - while (pthread__stacksize) { - pthread__stacksize >>= 1; - pthread__stacksize_lg++; - } - - pthread__stacksize = (1 << pthread__stacksize_lg); - pthread__stackmask = pthread__stacksize - 1; - pthread__threadmask = ~pthread__stackmask; + 4 * pthread__pagesize / 1024); - base = (void *)(pthread__sp() & pthread__threadmask); - if ((pthread__sp() - (uintptr_t)base) < 4 * pagesize) { - pthread__mainbase = (vaddr_t)base; - base = STACK_GROW(base, pthread__stacksize); - pthread__mainstruct = (vaddr_t)base; - if (mprotect(base, pthread__stacksize, - PROT_READ|PROT_WRITE) == -1) - err(1, "mprotect stack"); - } - size = pthread__stacksize; - - error = pthread__stackid_setup(base, size, &t); - if (error) { - /* XXX */ - errx(2, "failed to setup main thread: error=%d", error); - } - - *newt = t; + *newt = &pthread__main; #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II) # ifdef __HAVE___LWP_GETTCB_FAST - t->pt_tls = __lwp_gettcb_fast(); + pthread__main.pt_tls = __lwp_gettcb_fast(); # else - t->pt_tls = _lwp_getprivate(); + pthread__main.pt_tls = _lwp_getprivate(); # endif - t->pt_tls->tcb_pthread = t; -#else - _lwp_setprivate(t); -#endif -} - -static int -/*ARGSUSED*/ -pthread__stackid_setup(void *base, size_t size, pthread_t *tp) -{ - pthread_t t; - void *redaddr; - size_t pagesize; - int ret; - - t = base; - pagesize = (size_t)sysconf(_SC_PAGESIZE); - - /* - * Put a pointer to the pthread in the bottom (but - * redzone-protected section) of the stack. - */ - redaddr = STACK_SHRINK(STACK_MAX(base, size), pagesize); - t->pt_stack.ss_size = size - 2 * pagesize; -#ifdef __MACHINE_STACK_GROWS_UP - t->pt_stack.ss_sp = (char *)(void *)base + pagesize; -#else - t->pt_stack.ss_sp = (char *)(void *)base + 2 * pagesize; + pthread__main.pt_tls->tcb_pthread = &pthread__main; #endif - /* Protect the next-to-bottom stack page as a red zone. */ - ret = mprotect(redaddr, pagesize, PROT_NONE); - if (ret == -1) { - return errno; - } - *tp = t; - return 0; } #ifndef lint Index: src/lib/libpthread/pthread_attr.c diff -u src/lib/libpthread/pthread_attr.c:1.15 src/lib/libpthread/pthread_attr.c:1.16 --- src/lib/libpthread/pthread_attr.c:1.15 Fri Aug 6 15:21:50 2010 +++ src/lib/libpthread/pthread_attr.c Fri Mar 2 18:06:05 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_attr.c,v 1.15 2010/08/06 15:21:50 christos Exp $ */ +/* $NetBSD: pthread_attr.c,v 1.16 2012/03/02 18:06:05 joerg Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_attr.c,v 1.15 2010/08/06 15:21:50 christos Exp $"); +__RCSID("$NetBSD: pthread_attr.c,v 1.16 2012/03/02 18:06:05 joerg Exp $"); #include <errno.h> #include <stdio.h> @@ -107,7 +107,7 @@ pthread_attr_get_np(pthread_t thread, pt p->ptap_namearg = thread->pt_name; p->ptap_stackaddr = thread->pt_stack.ss_sp; p->ptap_stacksize = thread->pt_stack.ss_size; - p->ptap_guardsize = (size_t)sysconf(_SC_PAGESIZE); + p->ptap_guardsize = pthread__pagesize; return pthread_getschedparam(thread, &p->ptap_policy, &p->ptap_sp); } Index: src/lib/libpthread/pthread_int.h diff -u src/lib/libpthread/pthread_int.h:1.82 src/lib/libpthread/pthread_int.h:1.83 --- src/lib/libpthread/pthread_int.h:1.82 Tue Jan 17 20:34:57 2012 +++ src/lib/libpthread/pthread_int.h Fri Mar 2 18:06:05 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_int.h,v 1.82 2012/01/17 20:34:57 joerg Exp $ */ +/* $NetBSD: pthread_int.h,v 1.83 2012/03/02 18:06:05 joerg Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -175,10 +175,8 @@ struct __pthread_st { #define PT_ATTR_MAGIC 0x22220002 #define PT_ATTR_DEAD 0xDEAD0002 -extern int pthread__stacksize_lg; extern size_t pthread__stacksize; -extern vaddr_t pthread__stackmask; -extern vaddr_t pthread__threadmask; +extern size_t pthread__pagesize; extern int pthread__nspins; extern int pthread__concurrency; extern int pthread__osrev;