libc has a number of macros for dealing with thread safety such that it 
can operate efficiently when single-threaded but Do The Right Thing when 
multi-threaded.  In include/thread_private.h are two sets of macros that 
look interchangable but that are quite different on the underside.

_MUTEX_LOCK() and _MUTEX_UNLOCK() let libc treat a void* variable as a 
mutex.  They're no-ops unless linked with libpthread.

_THREAD_PRIVATE_MUTEX_LOCK() and _THREAD_PRIVATE_MUTEX_UNLOCK() look 
similar, but require you to declare the mutex with _THREAD_PRIVATE_MUTEX() 
and have this _THREAD_PRIVATE() extra feature for doing thread-specific 
data.

The trick is that the _THREAD_PRIVATE() feature means 
_THREAD_PRIVATE_MUTEX_LOCK() is quite a bit more expensive, allocating a 
couple more chunks of memory and creating a pthread_key_t under the 
covers, which involves another spin lock, etc.  If you're not using the 
per-thread storage part of _THREAD_PRIVATE* then it's a pile of overhead 
and over kill.

So, diff below converts several uses of _THREAD_PRIVATE_MUTEX_*() to 
_MUTEX_*().  Regress tests libc/stdio_threading/* and asr/bin/threads 
still pass with this.

ok?

Philip Guenther


Index: stdio/findfp.c
===================================================================
RCS file: /cvs/src/lib/libc/stdio/findfp.c,v
retrieving revision 1.18
diff -u -p -r1.18 findfp.c
--- stdio/findfp.c      27 Aug 2015 04:37:09 -0000      1.18
+++ stdio/findfp.c      4 Apr 2016 00:47:53 -0000
@@ -56,7 +56,7 @@ static FILE usual[FOPEN_MAX - 3];
 static struct __sfileext usualext[FOPEN_MAX - 3];
 static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
 static struct glue *lastglue = &uglue;
-_THREAD_PRIVATE_MUTEX(__sfp_mutex);
+static void *sfp_mutex;
 
 static struct __sfileext __sFext[3];
 FILE __sF[3] = {
@@ -108,7 +108,7 @@ __sfp(void)
        if (!__sdidinit)
                __sinit();
 
-       _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
+       _MUTEX_LOCK(&sfp_mutex);
        for (g = &__sglue; g != NULL; g = g->next) {
                for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
                        if (fp->_flags == 0)
@@ -116,16 +116,16 @@ __sfp(void)
        }
 
        /* release lock while mallocing */
-       _THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
+       _MUTEX_UNLOCK(&sfp_mutex);
        if ((g = moreglue(NDYNAMIC)) == NULL)
                return (NULL);
-       _THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
+       _MUTEX_LOCK(&sfp_mutex);
        lastglue->next = g;
        lastglue = g;
        fp = g->iobs;
 found:
        fp->_flags = 1;         /* reserve this slot; caller sets real flags */
-       _THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
+       _MUTEX_UNLOCK(&sfp_mutex);
        fp->_p = NULL;          /* no current pointer */
        fp->_w = 0;             /* nothing to read or write */
        fp->_r = 0;
@@ -161,10 +161,10 @@ _cleanup(void)
 void
 __sinit(void)
 {
-       _THREAD_PRIVATE_MUTEX(__sinit_mutex);
+       static void *sinit_mutex;
        int i;
 
-       _THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex);
+       _MUTEX_LOCK(&sinit_mutex);
        if (__sdidinit)
                goto out;       /* bail out if caller lost the race */
        for (i = 0; i < FOPEN_MAX - 3; i++) {
@@ -174,5 +174,5 @@ __sinit(void)
        __atexit_register_cleanup(_cleanup); /* conservative */
        __sdidinit = 1;
 out: 
-       _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);
+       _MUTEX_UNLOCK(&sinit_mutex);
 }
Index: stdlib/random.c
===================================================================
RCS file: /cvs/src/lib/libc/stdlib/random.c,v
retrieving revision 1.29
diff -u -p -r1.29 random.c
--- stdlib/random.c     16 Jan 2015 16:48:51 -0000      1.29
+++ stdlib/random.c     4 Apr 2016 00:47:53 -0000
@@ -176,10 +176,11 @@ static int rand_sep = SEP_3;
 static int random_deterministic;
 
 _THREAD_PRIVATE_MUTEX(random);
+static void *random_mutex;
 static long random_l(void);
 
-#define LOCK() _THREAD_PRIVATE_MUTEX_LOCK(random)
-#define UNLOCK() _THREAD_PRIVATE_MUTEX_UNLOCK(random)
+#define LOCK()         _MUTEX_LOCK(&random_mutex)
+#define UNLOCK()       _MUTEX_UNLOCK(&random_mutex)
 
 /*
  * srandom:
Index: asr/res_init.c
===================================================================
RCS file: /cvs/src/lib/libc/asr/res_init.c,v
retrieving revision 1.9
diff -u -p -r1.9 res_init.c
--- asr/res_init.c      23 Mar 2016 18:45:03 -0000      1.9
+++ asr/res_init.c      4 Apr 2016 00:47:53 -0000
@@ -37,7 +37,7 @@ int h_errno;
 int
 res_init(void)
 {
-       _THREAD_PRIVATE_MUTEX(init);
+       static void *resinit_mutex;
        struct asr_ctx  *ac;
        int i;
 
@@ -48,7 +48,7 @@ res_init(void)
         * structure from the async context, not overriding fields set early
         * by the user.
         */
-       _THREAD_PRIVATE_MUTEX_LOCK(init);
+       _MUTEX_LOCK(&resinit_mutex);
        if (!(_res.options & RES_INIT)) {
                if (_res.retry == 0)
                        _res.retry = ac->ac_nsretries;
@@ -75,7 +75,7 @@ res_init(void)
                _res.nscount = i;
                _res.options |= RES_INIT;
        }
-       _THREAD_PRIVATE_MUTEX_UNLOCK(init);
+       _MUTEX_UNLOCK(&resinit_mutex);
 
        /*
         * If the program is not threaded, we want to reflect (some) changes
Index: net/res_random.c
===================================================================
RCS file: /cvs/src/lib/libc/net/res_random.c,v
retrieving revision 1.23
diff -u -p -r1.23 res_random.c
--- net/res_random.c    5 Oct 2015 02:57:16 -0000       1.23
+++ net/res_random.c    4 Apr 2016 00:47:53 -0000
@@ -230,12 +230,12 @@ __res_randomid(void)
        struct timespec ts;
        pid_t pid;
        u_int r;
-       _THREAD_PRIVATE_MUTEX(random);
+       static void *randomid_mutex;
 
        clock_gettime(CLOCK_MONOTONIC, &ts);
        pid = getpid();
 
-       _THREAD_PRIVATE_MUTEX_LOCK(random);
+       _MUTEX_LOCK(&randomid_mutex);
 
        if (ru_counter >= RU_MAX || ts.tv_sec > ru_reseed || pid != ru_pid) {
                res_initid();
@@ -248,7 +248,7 @@ __res_randomid(void)
 
        r = permute15(ru_seed ^ pmod(ru_g, ru_seed2 + ru_x, RU_N)) | ru_msb;
 
-       _THREAD_PRIVATE_MUTEX_UNLOCK(random);
+       _MUTEX_UNLOCK(&randomid_mutex);
 
        return (r);
 }

Reply via email to