Source-Changes-HG archive

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

[src/trunk]: src Make PTHREAD_KEYS_MAX dynamically adjustable



details:   https://anonhg.NetBSD.org/src/rev/5549501920ce
branches:  trunk
changeset: 338526:5549501920ce
user:      manu <manu%NetBSD.org@localhost>
date:      Fri May 29 07:37:31 2015 +0000

description:
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.

diffstat:

 include/limits.h                    |  12 ++++---
 lib/libpthread/pthread.c            |  61 +++++++++++++++++++++++-------------
 lib/libpthread/pthread_int.h        |   6 ++-
 lib/libpthread/pthread_key_create.3 |   9 ++++-
 lib/libpthread/pthread_tsd.c        |  59 +++++++++++++++++++++++++++-------
 lib/libpthread_dbg/pthread_dbg.c    |   6 +-
 6 files changed, 107 insertions(+), 46 deletions(-)

diffs (truncated from 416 to 300 lines):

diff -r a24889c53bbb -r 5549501920ce include/limits.h
--- a/include/limits.h  Fri May 29 06:28:50 2015 +0000
+++ b/include/limits.h  Fri May 29 07:37:31 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.34 2015/05/29 07:37:31 manu 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 a24889c53bbb -r 5549501920ce lib/libpthread/pthread.c
--- a/lib/libpthread/pthread.c  Fri May 29 06:28:50 2015 +0000
+++ b/lib/libpthread/pthread.c  Fri May 29 07:37:31 2015 +0000
@@ -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 <sys/cdefs.h>
-__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 @@
  */
 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 @@
        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 @@
        /* 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 @@
        (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 @@
 
        /* 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_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 @@
         * 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 @@
        }
 
        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 @@
        _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 @@
        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
diff -r a24889c53bbb -r 5549501920ce lib/libpthread/pthread_int.h
--- a/lib/libpthread/pthread_int.h      Fri May 29 06:28:50 2015 +0000
+++ b/lib/libpthread/pthread_int.h      Fri May 29 07:37:31 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_int.h,v 1.90 2014/12/16 20:05:54 pooka Exp $   */
+/*     $NetBSD: pthread_int.h,v 1.91 2015/05/29 07:37:31 manu Exp $    */
 
 /*-
  * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -151,7 +151,7 @@
        struct pt_specific {
                void *pts_value;
                PTQ_ENTRY(pt_specific) pts_next;
-       } pt_specific[PTHREAD_KEYS_MAX];
+       } pt_specific[];
 };
 
 /* Thread states */
@@ -181,6 +181,7 @@
 extern int     pthread__concurrency;
 extern int     pthread__osrev;
 extern int     pthread__unpark_max;
+extern int     pthread_keys_max;
 
 extern int     __uselibcstub;
 
@@ -291,6 +292,7 @@
        }                                                               \
         } while (/*CONSTCOND*/0)
 
+int    pthread_tsd_init(void) PTHREAD_HIDE;
 void   pthread__destroy_tsd(pthread_t) PTHREAD_HIDE;
 __dead void    pthread__assertfunc(const char *, int, const char *, const char *)
                            PTHREAD_HIDE;
diff -r a24889c53bbb -r 5549501920ce lib/libpthread/pthread_key_create.3
--- a/lib/libpthread/pthread_key_create.3       Fri May 29 06:28:50 2015 +0000
+++ b/lib/libpthread/pthread_key_create.3       Fri May 29 07:37:31 2015 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: pthread_key_create.3,v 1.6 2010/07/09 10:55:11 wiz Exp $
+.\" $NetBSD: pthread_key_create.3,v 1.7 2015/05/29 07:37:31 manu Exp $
 .\"
 .\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -151,6 +151,13 @@
 .Fn pthread_key_delete
 will return zero upon success.
 Upon failure both functions return an error number to indicate the cause.
+.Sh ENVIRONMENT
+.Bl -tag -width PTHREAD_KEYS_MAX
+.It Ev PTHREAD_KEYS_MAX
+Maximum per process thread-specific data keys. This cannot be set
+below 
+.Dv _POSIX_THREAD_KEYS_MAX .
+.El
 .Sh ERRORS
 The
 .Fn pthread_key_create
diff -r a24889c53bbb -r 5549501920ce lib/libpthread/pthread_tsd.c
--- a/lib/libpthread/pthread_tsd.c      Fri May 29 06:28:50 2015 +0000
+++ b/lib/libpthread/pthread_tsd.c      Fri May 29 07:37:31 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pthread_tsd.c,v 1.11 2013/03/21 16:49:12 christos Exp $        */
+/*     $NetBSD: pthread_tsd.c,v 1.12 2015/05/29 07:37:31 manu Exp $    */
 
 /*-
  * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_tsd.c,v 1.11 2013/03/21 16:49:12 christos Exp $");
+__RCSID("$NetBSD: pthread_tsd.c,v 1.12 2015/05/29 07:37:31 manu Exp $");
 
 /* Functions and structures dealing with thread-specific data */
 #include <errno.h>
@@ -39,13 +39,12 @@
 #include "pthread_int.h"
 #include "reentrant.h"
 
-
+int pthread_keys_max;
 static pthread_mutex_t tsd_mutex = PTHREAD_MUTEX_INITIALIZER;
 static int nextkey;
 
-PTQ_HEAD(pthread__tsd_list, pt_specific)
-    pthread__tsd_list[PTHREAD_KEYS_MAX];
-void (*pthread__tsd_destructors[PTHREAD_KEYS_MAX])(void *);
+PTQ_HEAD(pthread__tsd_list, pt_specific) *pthread__tsd_list = NULL;
+void (**pthread__tsd_destructors)(void *) = NULL;
 
 __strong_alias(__libc_thr_keycreate,pthread_key_create)
 __strong_alias(__libc_thr_keydelete,pthread_key_delete)
@@ -58,6 +57,40 @@
 
 #include <err.h>
 #include <stdlib.h>
+#include <stdio.h>
+
+int
+pthread_tsd_init(void)
+{
+       char *pkm;
+       size_t len;



Home | Main Index | Thread Index | Old Index