Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7]: src Pull up following revision(s) (requested by manu in ticke...



details:   https://anonhg.NetBSD.org/src/rev/b78e6fe9f574
branches:  netbsd-7
changeset: 799723:b78e6fe9f574
user:      martin <martin%NetBSD.org@localhost>
date:      Tue Nov 24 17:37:15 2015 +0000

description:
Pull up following revision(s) (requested by manu in ticket #829):
        lib/libpthread_dbg/pthread_dbg.c: revision 1.43 (via patch)
        lib/libpthread/pthread_int.h: revision 1.91-1.92 (via patch)
        lib/libc/stdlib/jemalloc.c: revision 1.37-1.38
        lib/libpthread/pthread_tsd.c: revision 1.12-1.14 (via patch)
        include/limits.h: revision 1.34 (via patch)
        lib/libpthread/pthread.c: revision 1.146-1.147 (via patch)
        lib/libpthread/pthread_key_create.3: revision 1.7 (via patch)

libpthread:

Make PTHREAD_KEYS_MAX dynamically adjustable
NetBSD's PTHREAD_KEYS_MAX is set to 256, which is low compared to
other systems like Linux (1024) or MacOS X (512). As a result some
setups tested on Linux will exhibit problems on NetBSD because of
pthread_keys usage beyond the limit. This happens for instance on
Apache with various module loaded, and in this case no particular
developper can be blamed for going beyond the limit, since several
modules from different sources contribute to the problem.
This patch makes the limit conigurable through the PTHREAD_KEYS_MAX
environement variable. If undefined, the default remains unchanged
(256). In any case, the value cannot be lowered below POSIX-mandated
_POSIX_THREAD_KEYS_MAX (128).

While there:
- use EXIT_FAILURE instead of 1 when calling err(3) in libpthread.
- Reset _POSIX_THREAD_KEYS_MAX to POSIX mandated 128, instead of 256.

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.

Thanks rump for not letting us use even mmap during initialization.

libc/jemalloc:

Fix non _REENTRANT build.
Defer using pthread keys until we are threaded.
>From Christos, fixes PR port-arm/50087 by allowing malloc calls prior
to libpthread initialization.

diffstat:

 include/limits.h                    |  12 +++--
 lib/libc/stdlib/jemalloc.c          |  73 +++++++++++++++++++++++++++++-------
 lib/libpthread/pthread.c            |  54 ++++++++++++++++----------
 lib/libpthread/pthread_int.h        |  14 ++++--
 lib/libpthread/pthread_key_create.3 |   9 ++++-
 lib/libpthread/pthread_tsd.c        |  69 ++++++++++++++++++++++++++++------
 lib/libpthread_dbg/pthread_dbg.c    |   6 +-
 7 files changed, 174 insertions(+), 63 deletions(-)

diffs (truncated from 567 to 300 lines):

diff -r 76fa8d11cb00 -r b78e6fe9f574 include/limits.h
--- a/include/limits.h  Sun Nov 22 14:23:41 2015 +0000
+++ b/include/limits.h  Tue Nov 24 17:37:15 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: limits.h,v 1.33 2012/11/18 17:41:53 manu Exp $ */
+/*     $NetBSD: limits.h,v 1.33.8.1 2015/11/24 17:37:16 martin Exp $   */
 
 /*
  * Copyright (c) 1988, 1993
@@ -75,18 +75,20 @@
  */
 
 /*
- * The following 3 are not part of the standard
- * but left here for compatibility
+ * The following 3 are defined in 
+ * Open Group Base Specifications Issue 7
  */
 #define        _POSIX_THREAD_DESTRUCTOR_ITERATIONS     4
-#define        _POSIX_THREAD_KEYS_MAX                  256
+#define        _POSIX_THREAD_KEYS_MAX                  128
 #define        _POSIX_THREAD_THREADS_MAX               64
 
 /*
  * These are the correct names, defined in terms of the above
+ * except for PTHREAD_KEYS_MAX which is bigger than standard 
+ * mandated minimum value _POSIX_THREAD_KEYS_MAX.
  */
 #define        PTHREAD_DESTRUCTOR_ITERATIONS   _POSIX_THREAD_DESTRUCTOR_ITERATIONS
-#define        PTHREAD_KEYS_MAX                _POSIX_THREAD_KEYS_MAX
+#define        PTHREAD_KEYS_MAX                256
 /* Not yet: PTHREAD_STACK_MIN */
 #define        PTHREAD_THREADS_MAX             _POSIX_THREAD_THREADS_MAX
 
diff -r 76fa8d11cb00 -r b78e6fe9f574 lib/libc/stdlib/jemalloc.c
--- a/lib/libc/stdlib/jemalloc.c        Sun Nov 22 14:23:41 2015 +0000
+++ b/lib/libc/stdlib/jemalloc.c        Tue Nov 24 17:37:15 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: jemalloc.c,v 1.34 2014/08/10 05:57:31 matt Exp $       */
+/*     $NetBSD: jemalloc.c,v 1.34.2.1 2015/11/24 17:37:16 martin Exp $ */
 
 /*-
  * Copyright (C) 2006,2007 Jason Evans <jasone%FreeBSD.org@localhost>.
@@ -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.34 2014/08/10 05:57:31 matt Exp $");
+__RCSID("$NetBSD: jemalloc.c,v 1.34.2.1 2015/11/24 17:37:16 martin Exp $");
 
 #ifdef __FreeBSD__
 #include "libc_private.h"
@@ -382,9 +382,11 @@
 /* Set to true once the allocator has been initialized. */
 static bool malloc_initialized = false;
 
+#ifdef _REENTRANT
 /* Used to avoid initialization races. */
 static mutex_t init_lock = MUTEX_INITIALIZER;
 #endif
+#endif
 
 /******************************************************************************/
 /*
@@ -694,8 +696,10 @@
  * Chunks.
  */
 
+#ifdef _REENTRANT
 /* Protects chunk-related data structures. */
 static malloc_mutex_t  chunks_mtx;
+#endif
 
 /* Tree of chunks that are stand-alone huge allocations. */
 static chunk_tree_t    huge;
@@ -746,7 +750,9 @@
 static void            *base_next_addr;
 static void            *base_past_addr; /* Addr immediately past base_pages. */
 static chunk_node_t    *base_chunk_nodes; /* LIFO cache of chunk nodes. */
+#ifdef _REENTRANT
 static malloc_mutex_t  base_mtx;
+#endif
 #ifdef MALLOC_STATS
 static size_t          base_mapped;
 #endif
@@ -763,20 +769,62 @@
 static arena_t         **arenas;
 static unsigned                narenas;
 static unsigned                next_arena;
+#ifdef _REENTRANT
 static malloc_mutex_t  arenas_mtx; /* Protects arenas initialization. */
-
-#ifndef NO_TLS
+#endif
+
 /*
  * 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
+static arena_t **arenas_map;
+#endif
+
+#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;
-#define        get_arenas_map()        thr_getspecific(arenas_map_key)
-#define        set_arenas_map(x)       thr_setspecific(arenas_map_key, x)
+
+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
@@ -3634,11 +3682,6 @@
                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) {
diff -r 76fa8d11cb00 -r b78e6fe9f574 lib/libpthread/pthread.c
--- a/lib/libpthread/pthread.c  Sun Nov 22 14:23:41 2015 +0000
+++ b/lib/libpthread/pthread.c  Tue Nov 24 17:37:15 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread.c,v 1.144 2014/01/31 20:44:01 christos Exp $   */
+/*     $NetBSD: pthread.c,v 1.144.4.1 2015/11/24 17:37:16 martin 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.144 2014/01/31 20:44:01 christos Exp $");
+__RCSID("$NetBSD: pthread.c,v 1.144.4.1 2015/11/24 17:37:16 martin Exp $");
 
 #define        __EXPOSE_STACK  1
 
@@ -115,7 +115,8 @@
  */
 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 *);
 
@@ -164,6 +165,17 @@
        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.
+        */
+       pthread__main = pthread_tsd_init(&__pthread_st_size);
+       if (pthread__main == NULL)
+               err(EXIT_FAILURE, "Cannot allocate pthread storage");
+
        __uselibcstub = 0;
 
        pthread__pagesize = (size_t)sysconf(_SC_PAGESIZE);
@@ -178,7 +190,7 @@
        /* 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;
 
@@ -199,7 +211,7 @@
        (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 */
@@ -240,7 +252,7 @@
 
        /* 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();
 }
@@ -298,7 +310,6 @@
        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
@@ -451,7 +462,7 @@
         * and initialize it.
         */
        if (newthread == NULL) {
-               newthread = malloc(sizeof(*newthread));
+               newthread = calloc(1, __pthread_st_size);
                if (newthread == NULL) {
                        free(name);
                        return ENOMEM;
@@ -566,7 +577,7 @@
        }
 
        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);
@@ -1281,17 +1292,18 @@
        _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;
                }
@@ -1313,24 +1325,24 @@
        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;
        }



Home | Main Index | Thread Index | Old Index