Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/lib/libpthread/pthread.c,v rcsdiff: /ftp/cvs/cvsroot/src/lib/libpthread/pthread.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.145 retrieving revision 1.146 diff -u -p -r1.145 -r1.146 --- src/lib/libpthread/pthread.c 2014/12/16 20:05:54 1.145 +++ src/lib/libpthread/pthread.c 2015/05/29 07:37:31 1.146 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread.c,v 1.145 2014/12/16 20:05:54 pooka Exp $ */ +/* $NetBSD: pthread.c,v 1.146 2015/05/29 07:37:31 manu Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__RCSID("$NetBSD: pthread.c,v 1.145 2014/12/16 20:05:54 pooka Exp $"); +__RCSID("$NetBSD: pthread.c,v 1.146 2015/05/29 07:37:31 manu Exp $"); #define __EXPOSE_STACK 1 @@ -116,7 +116,8 @@ int pthread__dbg; /* set by libpthread_d */ size_t pthread__stacksize; size_t pthread__pagesize; -static struct __pthread_st pthread__main; +static struct __pthread_st *pthread__main; +static size_t __pthread_st_size; int _sys___sigprocmask14(int, const sigset_t *, sigset_t *); @@ -165,6 +166,22 @@ pthread__init(void) int i; extern int __isthreaded; + /* + * Allocate pthread_keys descriptors before + * reseting __uselibcstub because otherwise + * malloc() will call pthread_keys_create() + * while pthread_keys descriptors are not + * yet allocated. + */ + if (pthread_tsd_init() != 0) + err(EXIT_FAILURE, "Cannot allocate pthread_keys descriptors"); + + __pthread_st_size = sizeof(*pthread__main) + + pthread_keys_max * sizeof(pthread__main->pt_specific[0]); + + if ((pthread__main = calloc(1, __pthread_st_size)) == NULL) + err(EXIT_FAILURE, "Cannot allocate pthread__specific"); + __uselibcstub = 0; pthread__pagesize = (size_t)sysconf(_SC_PAGESIZE); @@ -179,7 +196,7 @@ pthread__init(void) /* Fetch parameters. */ i = (int)_lwp_unpark_all(NULL, 0, NULL); if (i == -1) - err(1, "_lwp_unpark_all"); + err(EXIT_FAILURE, "_lwp_unpark_all"); if (i < pthread__unpark_max) pthread__unpark_max = i; @@ -200,7 +217,7 @@ pthread__init(void) (void)rb_tree_insert_node(&pthread__alltree, first); if (_lwp_ctl(LWPCTL_FEATURE_CURCPU, &first->pt_lwpctl) != 0) { - err(1, "_lwp_ctl"); + err(EXIT_FAILURE, "_lwp_ctl"); } /* Start subsystems */ @@ -241,7 +258,7 @@ pthread__fork_callback(void) /* lwpctl state is not copied across fork. */ if (_lwp_ctl(LWPCTL_FEATURE_CURCPU, &self->pt_lwpctl)) { - err(1, "_lwp_ctl"); + err(EXIT_FAILURE, "_lwp_ctl"); } self->pt_lid = _lwp_self(); } @@ -299,7 +316,6 @@ pthread__initthread(pthread_t t) pthread_mutex_init(&t->pt_lock, NULL); PTQ_INIT(&t->pt_cleanup_stack); pthread_cond_init(&t->pt_joiners, NULL); - memset(&t->pt_specific, 0, sizeof(t->pt_specific)); } static void @@ -452,7 +468,7 @@ pthread_create(pthread_t *thread, const * and initialize it. */ if (newthread == NULL) { - newthread = malloc(sizeof(*newthread)); + newthread = calloc(1, __pthread_st_size); if (newthread == NULL) { free(name); return ENOMEM; @@ -559,7 +575,7 @@ pthread__create_tramp(void *cookie) } if (_lwp_ctl(LWPCTL_FEATURE_CURCPU, &self->pt_lwpctl)) { - err(1, "_lwp_ctl"); + err(EXIT_FAILURE, "_lwp_ctl"); } retval = (*self->pt_func)(self->pt_arg); @@ -1274,17 +1290,18 @@ pthread__initmainstack(void) _DIAGASSERT(_dlauxinfo() != NULL); if (getrlimit(RLIMIT_STACK, &slimit) == -1) - err(1, "Couldn't get stack resource consumption limits"); + err(EXIT_FAILURE, + "Couldn't get stack resource consumption limits"); size = slimit.rlim_cur; - pthread__main.pt_stack.ss_size = size; + pthread__main->pt_stack.ss_size = size; 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; + pthread__main->pt_stack.ss_sp = (void *)aux->a_v; #ifdef __MACHINE_STACK_GROWS_UP - pthread__main.pt_stack.ss_sp = (void *)aux->a_v; + pthread__main->pt_stack.ss_sp = (void *)aux->a_v; #else - pthread__main.pt_stack.ss_sp = (char *)aux->a_v - size; + pthread__main->pt_stack.ss_sp = (char *)aux->a_v - size; #endif break; } @@ -1306,26 +1323,26 @@ pthread__initmain(pthread_t *newt) value = pthread__getenv("PTHREAD_STACKSIZE"); if (value != NULL) { pthread__stacksize = atoi(value) * 1024; - if (pthread__stacksize > pthread__main.pt_stack.ss_size) - pthread__stacksize = pthread__main.pt_stack.ss_size; + if (pthread__stacksize > pthread__main->pt_stack.ss_size) + pthread__stacksize = pthread__main->pt_stack.ss_size; } if (pthread__stacksize == 0) - pthread__stacksize = pthread__main.pt_stack.ss_size; + pthread__stacksize = pthread__main->pt_stack.ss_size; pthread__stacksize += pthread__pagesize - 1; pthread__stacksize &= ~(pthread__pagesize - 1); if (pthread__stacksize < 4 * pthread__pagesize) errx(1, "Stacksize limit is too low, minimum %zd kbyte.", 4 * pthread__pagesize / 1024); - *newt = &pthread__main; + *newt = pthread__main; #if defined(_PTHREAD_GETTCB_EXT) - pthread__main.pt_tls = _PTHREAD_GETTCB_EXT(); + pthread__main->pt_tls = _PTHREAD_GETTCB_EXT(); #elif defined(__HAVE___LWP_GETTCB_FAST) - pthread__main.pt_tls = __lwp_gettcb_fast(); + pthread__main->pt_tls = __lwp_gettcb_fast(); #else - pthread__main.pt_tls = _lwp_getprivate(); + pthread__main->pt_tls = _lwp_getprivate(); #endif - pthread__main.pt_tls->tcb_pthread = &pthread__main; + pthread__main->pt_tls->tcb_pthread = pthread__main; } static signed int