Module Name: src Committed By: martin Date: Sun Jul 26 17:21:55 UTC 2015
Modified Files: src/lib/libc/stdlib: jemalloc.c Log Message: Defer using pthread keys until we are threaded. >From Christos, fixes PR port-arm/50087 by allowing malloc calls prior to libpthread initialization. To generate a diff of this commit: cvs rdiff -u -r1.37 -r1.38 src/lib/libc/stdlib/jemalloc.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/libc/stdlib/jemalloc.c diff -u src/lib/libc/stdlib/jemalloc.c:1.37 src/lib/libc/stdlib/jemalloc.c:1.38 --- src/lib/libc/stdlib/jemalloc.c:1.37 Tue Jan 20 18:31:25 2015 +++ src/lib/libc/stdlib/jemalloc.c Sun Jul 26 17:21:55 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: jemalloc.c,v 1.37 2015/01/20 18:31:25 christos Exp $ */ +/* $NetBSD: jemalloc.c,v 1.38 2015/07/26 17:21:55 martin Exp $ */ /*- * Copyright (C) 2006,2007 Jason Evans <jas...@freebsd.org>. @@ -118,7 +118,7 @@ #include <sys/cdefs.h> /* __FBSDID("$FreeBSD: src/lib/libc/stdlib/malloc.c,v 1.147 2007/06/15 22:00:16 jasone Exp $"); */ -__RCSID("$NetBSD: jemalloc.c,v 1.37 2015/01/20 18:31:25 christos Exp $"); +__RCSID("$NetBSD: jemalloc.c,v 1.38 2015/07/26 17:21:55 martin Exp $"); #ifdef __FreeBSD__ #include "libc_private.h" @@ -783,20 +783,58 @@ static unsigned next_arena; static malloc_mutex_t arenas_mtx; /* Protects arenas initialization. */ #endif -#ifndef NO_TLS /* * Map of pthread_self() --> arenas[???], used for selecting an arena to use * for allocations. */ -static __thread arena_t *arenas_map; -#define get_arenas_map() (arenas_map) -#define set_arenas_map(x) (arenas_map = x) +#ifndef NO_TLS +static __thread arena_t **arenas_map; #else -#ifdef _REENTRANT -static thread_key_t arenas_map_key; +static arena_t **arenas_map; #endif -#define get_arenas_map() thr_getspecific(arenas_map_key) -#define set_arenas_map(x) thr_setspecific(arenas_map_key, x) + +#if !defined(NO_TLS) || !defined(_REENTRANT) +# define get_arenas_map() (arenas_map) +# define set_arenas_map(x) (arenas_map = x) +#else + +static thread_key_t arenas_map_key = -1; + +static inline arena_t ** +get_arenas_map(void) +{ + if (!__isthreaded) + return arenas_map; + + if (arenas_map_key == -1) { + (void)thr_keycreate(&arenas_map_key, NULL); + if (arenas_map != NULL) { + thr_setspecific(arenas_map_key, arenas_map); + arenas_map = NULL; + } + } + + return thr_getspecific(arenas_map_key); +} + +static __inline void +set_arenas_map(arena_t **a) +{ + if (!__isthreaded) { + arenas_map = a; + return; + } + + if (arenas_map_key == -1) { + (void)thr_keycreate(&arenas_map_key, NULL); + if (arenas_map != NULL) { + _DIAGASSERT(arenas_map == a); + arenas_map = NULL; + } + } + + thr_setspecific(arenas_map_key, a); +} #endif #ifdef MALLOC_STATS @@ -3654,11 +3692,6 @@ malloc_init_hard(void) opt_narenas_lshift += 2; } -#ifdef NO_TLS - /* Initialize arena key. */ - (void)thr_keycreate(&arenas_map_key, NULL); -#endif - /* Determine how many arenas to use. */ narenas = ncpus; if (opt_narenas_lshift > 0) {