]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Initialize pthread_mutexattrs just once (#38547)
authorMukund Sivaraman <muks@isc.org>
Thu, 26 Feb 2015 09:13:45 +0000 (14:43 +0530)
committerMukund Sivaraman <muks@isc.org>
Thu, 26 Feb 2015 09:13:45 +0000 (14:43 +0530)
CHANGES
lib/dns/tests/dnstest.c
lib/isc/nothreads/include/isc/mutex.h
lib/isc/pthreads/mutex.c

diff --git a/CHANGES b/CHANGES
index 3596ea54a2fd8fc34254a2d655d52f1c1209d083..b9b2dc8af40d3e474129c5e82bbe94acaf185083 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4071.  [cleanup]       Initialize pthread mutex attrs just once, instead of
+                       doing it per mutex creation. [RT #38547]
+
 4070.  [bug]           Fix a segfault in nslookup in a query such as
                        "nslookup isc.org AMS.SNS-PB.ISC.ORG -all".
                        [RT #38548]
index c70e516829807b3bff2832174364c9b4d802a921..6c26789e1952951154c7bb4748548dfb95e0582b 100644 (file)
@@ -189,8 +189,7 @@ dns_test_end(void) {
  * Create a view.
  */
 isc_result_t
-dns_test_makeview(const char *name, dns_view_t **viewp)
-{
+dns_test_makeview(const char *name, dns_view_t **viewp) {
        isc_result_t result;
        dns_view_t *view = NULL;
 
index 1f2187b8b53fb4e163807a190f35b22e8eb5de5c..23eb0a09c6af127eb26a382e256bb3d6f2b887cb 100644 (file)
@@ -15,8 +15,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: mutex.h,v 1.6 2007/06/19 23:47:18 tbox Exp $ */
-
 #ifndef ISC_MUTEX_H
 #define ISC_MUTEX_H 1
 
index e09444a2ca37083bfb17518ef220b700e953a12d..71e843c1595b5efc2b9d57b45035ac9e09209eb0 100644 (file)
 #include <isc/mutex.h>
 #include <isc/util.h>
 #include <isc/strerror.h>
+#include <isc/once.h>
 
 #if ISC_MUTEX_PROFILE
 
 /*@{*/
 /*% Operations on timevals; adapted from FreeBSD's sys/time.h */
 #define timevalclear(tvp)      ((tvp)->tv_sec = (tvp)->tv_usec = 0)
-#define timevaladd(vvp, uvp)                                            \
-       do {                                                            \
-               (vvp)->tv_sec += (uvp)->tv_sec;                         \
-               (vvp)->tv_usec += (uvp)->tv_usec;                       \
-               if ((vvp)->tv_usec >= 1000000) {                        \
-                       (vvp)->tv_sec++;                                \
-                       (vvp)->tv_usec -= 1000000;                      \
-               }                                                       \
+#define timevaladd(vvp, uvp)                                           \
+       do {                                                            \
+               (vvp)->tv_sec += (uvp)->tv_sec;                         \
+               (vvp)->tv_usec += (uvp)->tv_usec;                       \
+               if ((vvp)->tv_usec >= 1000000) {                        \
+                       (vvp)->tv_sec++;                                \
+                       (vvp)->tv_usec -= 1000000;                      \
+               }                                                       \
        } while (0)
-#define timevalsub(vvp, uvp)                                            \
-       do {                                                            \
-               (vvp)->tv_sec -= (uvp)->tv_sec;                         \
-               (vvp)->tv_usec -= (uvp)->tv_usec;                       \
-               if ((vvp)->tv_usec < 0) {                               \
-                       (vvp)->tv_sec--;                                \
-                       (vvp)->tv_usec += 1000000;                      \
-               }                                                       \
+#define timevalsub(vvp, uvp)                                           \
+       do {                                                            \
+               (vvp)->tv_sec -= (uvp)->tv_sec;                         \
+               (vvp)->tv_usec -= (uvp)->tv_usec;                       \
+               if ((vvp)->tv_usec < 0) {                               \
+                       (vvp)->tv_sec--;                                \
+                       (vvp)->tv_usec += 1000000;                      \
+               }                                                       \
        } while (0)
 
 /*@}*/
@@ -68,7 +69,7 @@ typedef struct {
 
 struct isc_mutexstats {
        const char *            file;   /*%< File mutex was created in. */
-       int                     line;   /*%< Line mutex was created on. */
+       int                     line;   /*%< Line mutex was created on. */
        unsigned                count;
        struct timeval          lock_t;
        struct timeval          locked_total;
@@ -225,24 +226,35 @@ isc_mutex_statsprofile(FILE *fp) {
 #endif /* ISC_MUTEX_PROFILE */
 
 #if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
-isc_result_t
-isc_mutex_init_errcheck(isc_mutex_t *mp)
-{
-       pthread_mutexattr_t attr;
-       int err, errd;
 
-       if (pthread_mutexattr_init(&attr) != 0)
-               return (ISC_R_UNEXPECTED);
+static isc_boolean_t errcheck_initialized = ISC_FALSE;
+static pthread_mutexattr_t errcheck;
+static isc_once_t once_errcheck = ISC_ONCE_INIT;
 
-       if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) {
-               errd = pthread_mutexattr_destroy(&attr);
-               RUNTIME_CHECK(errd == 0);
-               return (ISC_R_UNEXPECTED);
+static void
+destroy_errcheck(void) {
+       if (errcheck_initialized) {
+               RUNTIME_CHECK(pthread_mutexattr_destroy(&errcheck) == 0);
        }
+}
+
+static void
+initialize_errcheck(void) {
+       RUNTIME_CHECK(pthread_mutexattr_init(&errcheck) == 0);
+       RUNTIME_CHECK(pthread_mutexattr_settype
+                     (&errcheck, PTHREAD_MUTEX_ERRORCHECK) == 0);
+       errcheck_initialized = ISC_TRUE;
+}
 
-       err = pthread_mutex_init(mp, &attr) != 0)
-       errd = pthread_mutexattr_destroy(&attr);
-       RUNTIME_CHECK(errd == 0);
+isc_result_t
+isc_mutex_init_errcheck(isc_mutex_t *mp) {
+       isc_result_t result;
+       int err;
+
+       result = isc_once_do(&once_errcheck, initialize_errcheck);
+       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+       err = pthread_mutex_init(mp, &errcheck);
        if (err == ENOMEM)
                return (ISC_R_NOMEMORY);
        return ((err == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED);
@@ -257,25 +269,39 @@ pthread_mutexattr_t isc__mutex_attrs = {
 #endif
 
 #if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && !ISC_MUTEX_PROFILE
+
+static isc_boolean_t attr_initialized = ISC_FALSE;
+static pthread_mutexattr_t attr;
+static isc_once_t once_attr = ISC_ONCE_INIT;
+
+static void
+destroy_attr(void) {
+       if (attr_initialized) {
+               RUNTIME_CHECK(pthread_mutexattr_destroy(&attr) == 0);
+       }
+}
+
+#ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
+static void
+initialize_attr(void) {
+       RUNTIME_CHECK(pthread_mutexattr_init(&attr) == 0);
+       RUNTIME_CHECK(pthread_mutexattr_settype
+                     (&attr, PTHREAD_MUTEX_ADAPTIVE_NP) == 0);
+       attr_initialized = ISC_TRUE;
+}
+#endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
+
 isc_result_t
 isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
        char strbuf[ISC_STRERRORSIZE];
        isc_result_t result = ISC_R_SUCCESS;
        int err;
+
 #ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
-       pthread_mutexattr_t attr;
-       int errd;
+       result = isc_once_do(&once_attr, initialize_attr);
+       RUNTIME_CHECK(result == ISC_R_SUCCESS);
 
-       if (pthread_mutexattr_init(&attr) != 0)
-               return (ISC_R_UNEXPECTED);
-       if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP) != 0) {
-               errd = pthread_mutexattr_destroy(&attr);
-               RUNTIME_CHECK(errd == 0);
-               return (ISC_R_UNEXPECTED);
-       }
        err = pthread_mutex_init(mp, &attr);
-       errd = pthread_mutexattr_destroy(&attr);
-       RUNTIME_CHECK(errd == 0);
 #else /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
        err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS);
 #endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */