Module Name: src Committed By: christos Date: Fri May 29 16:05:13 UTC 2015
Modified Files: src/lib/libpthread: pthread.c pthread_int.h pthread_tsd.c Log Message: Fix previous: Can't use calloc/malloc before we complete initialization of the thread library, because malloc uses pthread_foo_specific, and it will end up initializing itself incorrectly. To generate a diff of this commit: cvs rdiff -u -r1.146 -r1.147 src/lib/libpthread/pthread.c cvs rdiff -u -r1.91 -r1.92 src/lib/libpthread/pthread_int.h cvs rdiff -u -r1.12 -r1.13 src/lib/libpthread/pthread_tsd.c 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.146 src/lib/libpthread/pthread.c:1.147 --- src/lib/libpthread/pthread.c:1.146 Fri May 29 03:37:31 2015 +++ src/lib/libpthread/pthread.c Fri May 29 12:05:13 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread.c,v 1.146 2015/05/29 07:37:31 manu Exp $ */ +/* $NetBSD: pthread.c,v 1.147 2015/05/29 16:05:13 christos Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread.c,v 1.146 2015/05/29 07:37:31 manu Exp $"); +__RCSID("$NetBSD: pthread.c,v 1.147 2015/05/29 16:05:13 christos Exp $"); #define __EXPOSE_STACK 1 @@ -173,14 +173,9 @@ pthread__init(void) * 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"); + pthread__main = pthread_tsd_init(&__pthread_st_size); + if (pthread__main == NULL) + err(EXIT_FAILURE, "Cannot allocate pthread storage"); __uselibcstub = 0; Index: src/lib/libpthread/pthread_int.h diff -u src/lib/libpthread/pthread_int.h:1.91 src/lib/libpthread/pthread_int.h:1.92 --- src/lib/libpthread/pthread_int.h:1.91 Fri May 29 03:37:31 2015 +++ src/lib/libpthread/pthread_int.h Fri May 29 12:05:13 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_int.h,v 1.91 2015/05/29 07:37:31 manu Exp $ */ +/* $NetBSD: pthread_int.h,v 1.92 2015/05/29 16:05:13 christos Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -292,7 +292,7 @@ pthread__self(void) } \ } while (/*CONSTCOND*/0) -int pthread_tsd_init(void) PTHREAD_HIDE; +void *pthread_tsd_init(size_t *) PTHREAD_HIDE; void pthread__destroy_tsd(pthread_t) PTHREAD_HIDE; __dead void pthread__assertfunc(const char *, int, const char *, const char *) PTHREAD_HIDE; Index: src/lib/libpthread/pthread_tsd.c diff -u src/lib/libpthread/pthread_tsd.c:1.12 src/lib/libpthread/pthread_tsd.c:1.13 --- src/lib/libpthread/pthread_tsd.c:1.12 Fri May 29 03:37:31 2015 +++ src/lib/libpthread/pthread_tsd.c Fri May 29 12:05:13 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_tsd.c,v 1.12 2015/05/29 07:37:31 manu Exp $ */ +/* $NetBSD: pthread_tsd.c,v 1.13 2015/05/29 16:05:13 christos Exp $ */ /*- * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc. @@ -30,10 +30,11 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_tsd.c,v 1.12 2015/05/29 07:37:31 manu Exp $"); +__RCSID("$NetBSD: pthread_tsd.c,v 1.13 2015/05/29 16:05:13 christos Exp $"); /* Functions and structures dealing with thread-specific data */ #include <errno.h> +#include <sys/mman.h> #include "pthread.h" #include "pthread_int.h" @@ -59,13 +60,14 @@ null_destructor(void *p) #include <stdlib.h> #include <stdio.h> -int -pthread_tsd_init(void) +void * +pthread_tsd_init(size_t *tlen) { char *pkm; - size_t len; + size_t alen; + char *arena; - if ((pkm = getenv("PTHREAD_KEYS_MAX")) != NULL) { + if ((pkm = pthread__getenv("PTHREAD_KEYS_MAX")) != NULL) { pthread_keys_max = (int)strtol(pkm, NULL, 0); if (pthread_keys_max < _POSIX_THREAD_KEYS_MAX) pthread_keys_max = _POSIX_THREAD_KEYS_MAX; @@ -73,22 +75,27 @@ pthread_tsd_init(void) pthread_keys_max = PTHREAD_KEYS_MAX; } - len = sizeof(*pthread__tsd_list); - if ((pthread__tsd_list = calloc(pthread_keys_max, len)) == NULL) - goto out1; - - len = sizeof(*pthread__tsd_destructors); - if ((pthread__tsd_destructors = calloc(pthread_keys_max, len)) == NULL) - goto out2; - - return 0; - -out2: - free(pthread__tsd_list); -out1: - pthread_keys_max = 0; + /* + * Can't use malloc here yet, because malloc will use the fake + * libc thread functions to initialize itself, so mmap the space. + */ + *tlen = sizeof(struct __pthread_st) + + pthread_keys_max * sizeof(struct pt_specific); + alen = *tlen + + sizeof(*pthread__tsd_list) * pthread_keys_max + + sizeof(*pthread__tsd_destructors) * pthread_keys_max; + + arena = mmap(NULL, alen, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0); + if (arena == MAP_FAILED) { + pthread_keys_max = 0; + return NULL; + } - return -1; + pthread__tsd_list = (void *)arena; + arena += sizeof(*pthread__tsd_list) * pthread_keys_max; + pthread__tsd_destructors = (void *)arena; + arena += sizeof(*pthread__tsd_destructors) * pthread_keys_max; + return arena; } int