]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Backport performance work to 9.11 (#45637)
authorMukund Sivaraman <muks@isc.org>
Wed, 6 Dec 2017 05:00:20 +0000 (10:30 +0530)
committerMukund Sivaraman <muks@isc.org>
Wed, 6 Dec 2017 05:05:21 +0000 (10:35 +0530)
12 files changed:
CHANGES
OPTIONS
OPTIONS.md
lib/dns/message.c
lib/dns/name.c
lib/dns/rbtdb.c
lib/dns/ssu_external.c
lib/isc/hash.c
lib/isc/include/isc/buffer.h
lib/isc/include/isc/msgs.h
lib/isc/mem.c
lib/isc/rwlock.c

diff --git a/CHANGES b/CHANGES
index e446b541f4c077ab81c943ada129a4c1dd9e0748..075e9af960f4eaf24b04dcd24fbaa867610762ab 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+4605.  [performance]   (partial backport) Improve general query
+                       performance. Improves performance of owner case
+                       restoration, hash function, etc. Uses inline
+                       buffer implementation by default. [RT #45637]
+
 4839.  [bug]           zone.c:zone_sign was not properly determining
                        if there were active KSK and ZSK keys for
                        a algorithm when update-check-ksk is true
diff --git a/OPTIONS b/OPTIONS
index 033cc517fe15c93f986186e6305b9b696d7886cf..d934a0505c05c584f8309e71f98af7cf0ef252bd 100644 (file)
--- a/OPTIONS
+++ b/OPTIONS
@@ -27,4 +27,6 @@ Setting                   Description
                           highest possible setting
 -DISC_HEAP_CHECK          Test heap consistency after every heap
                           operation; used when debugging
-
+                          Disable the use of inline functions to implement
+-DISC_BUFFER_USEINLINE=0  the isc_buffer API: this reduces performance but
+                          may be useful when debugging
index ae1debe3a9774b9bb6515ac5dd30ed07d3499f40..738076d62a7b6551b089af49d86734b44e778a09 100644 (file)
@@ -23,3 +23,4 @@ Some of these settings are:
 |`-DDIG_SIGCHASE=1`|Enable DNSSEC signature chasing support in `dig`.  (Note: This feature is deprecated. Use `delv` instead.)|
 |`-DNS_RPZ_MAX_ZONES=64`|Increase the maximum number of configurable response policy zones from 32 to 64; this is the highest possible setting|
 |`-DISC_HEAP_CHECK`|Test heap consistency after every heap operation; used when debugging|
+|`-DISC_BUFFER_USEINLINE=0`|Disable the use of inline functions to implement the `isc_buffer` API: this reduces performance but may be useful when debugging |
index dcac977364928162377d9437c49cf17df94b23ac..1bc7141cb8b22303c246027fa671176d18bc9e85 100644 (file)
@@ -96,11 +96,11 @@ hexdump(const char *msg, const char *msg2, void *base, size_t len) {
  * XXXMLG These should come from a config setting.
  */
 #define SCRATCHPAD_SIZE                512
-#define NAME_COUNT               8
+#define NAME_COUNT              64
 #define OFFSET_COUNT             4
 #define RDATA_COUNT              8
 #define RDATALIST_COUNT                  8
-#define RDATASET_COUNT          RDATALIST_COUNT
+#define RDATASET_COUNT          64
 
 /*%
  * Text representation of the different items, for message_totext
@@ -740,6 +740,7 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
        result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool);
        if (result != ISC_R_SUCCESS)
                goto cleanup;
+       isc_mempool_setfillcount(m->namepool, NAME_COUNT);
        isc_mempool_setfreemax(m->namepool, NAME_COUNT);
        isc_mempool_setname(m->namepool, "msg:names");
 
@@ -747,7 +748,8 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
                                    &m->rdspool);
        if (result != ISC_R_SUCCESS)
                goto cleanup;
-       isc_mempool_setfreemax(m->rdspool, NAME_COUNT);
+       isc_mempool_setfillcount(m->rdspool, RDATASET_COUNT);
+       isc_mempool_setfreemax(m->rdspool, RDATASET_COUNT);
        isc_mempool_setname(m->rdspool, "msg:rdataset");
 
        dynbuf = NULL;
index f54dc53f6a5da65028a96fd9f05ad2cc303d5928..e9bb9f9b57bd0be894ba771e5fdd5b964d236da9 100644 (file)
@@ -939,9 +939,9 @@ dns_name_getlabelsequence(const dns_name_t *source,
                          unsigned int first, unsigned int n,
                          dns_name_t *target)
 {
-       unsigned char *offsets;
-       dns_offsets_t odata;
+       unsigned char *p, l;
        unsigned int firstoffset, endoffset;
+       unsigned int i;
 
        /*
         * Make 'target' refer to the 'n' labels including and following
@@ -954,17 +954,26 @@ dns_name_getlabelsequence(const dns_name_t *source,
        REQUIRE(n <= source->labels - first); /* note first+n could overflow */
        REQUIRE(BINDABLE(target));
 
-       SETUP_OFFSETS(source, offsets, odata);
-
-       if (first == source->labels)
+       p = source->ndata;
+       if (ISC_UNLIKELY(first == source->labels)) {
                firstoffset = source->length;
-       else
-               firstoffset = offsets[first];
+       } else {
+               for (i = 0; i < first; i++) {
+                       l = *p;
+                       p += l + 1;
+               }
+               firstoffset = p - source->ndata;
+       }
 
-       if (first + n == source->labels)
+       if (ISC_LIKELY(first + n == source->labels))
                endoffset = source->length;
-       else
-               endoffset = offsets[first + n];
+       else {
+               for (i = 0; i < n; i++) {
+                       l = *p;
+                       p += l + 1;
+               }
+               endoffset = p - source->ndata;
+       }
 
        target->ndata = &source->ndata[firstoffset];
        target->length = endoffset - firstoffset;
@@ -1756,16 +1765,15 @@ set_offsets(const dns_name_t *name, unsigned char *offsets,
        offset = 0;
        nlabels = 0;
        absolute = ISC_FALSE;
-       while (offset != length) {
+       while (ISC_LIKELY(offset != length)) {
                INSIST(nlabels < 128);
                offsets[nlabels++] = offset;
-               count = *ndata++;
-               offset++;
+               count = *ndata;
                INSIST(count <= 63);
-               offset += count;
-               ndata += count;
+               offset += count + 1;
+               ndata += count + 1;
                INSIST(offset <= length);
-               if (count == 0) {
+               if (ISC_UNLIKELY(count == 0)) {
                        absolute = ISC_TRUE;
                        break;
                }
index c407d3e27165f42cf5c032f9e751c5ad7d995b40..1339c01efe054ebb462a446ab67a77122f89a56e 100644 (file)
@@ -501,6 +501,7 @@ typedef ISC_LIST(dns_rbtnode_t)         rbtnodelist_t;
 #define RDATASET_ATTR_PREFETCH          0x0200
 #define RDATASET_ATTR_CASESET           0x0400
 #define RDATASET_ATTR_ZEROTTL           0x0800
+#define RDATASET_ATTR_CASEFULLYLOWER    0x1000
 
 typedef struct acache_cbarg {
        dns_rdatasetadditional_t        type;
@@ -549,6 +550,9 @@ struct acachectl {
        (((header)->attributes & RDATASET_ATTR_CASESET) != 0)
 #define ZEROTTL(header) \
        (((header)->attributes & RDATASET_ATTR_ZEROTTL) != 0)
+#define CASEFULLYLOWER(header) \
+       (((header)->attributes & RDATASET_ATTR_CASEFULLYLOWER) != 0)
+
 
 #define ACTIVE(header, now) \
        (((header)->rdh_ttl > (now)) || \
@@ -1671,8 +1675,12 @@ update_newheader(rdatasetheader_t *newh, rdatasetheader_t *old) {
                newh->node = (dns_rbtnode_t *)p;
        }
        if (CASESET(old)) {
+               uint16_t attr;
+
                memmove(newh->upper, old->upper, sizeof(old->upper));
-               newh->attributes |= RDATASET_ATTR_CASESET;
+               attr = old->attributes & (RDATASET_ATTR_CASESET |
+                                         RDATASET_ATTR_CASEFULLYLOWER);
+               newh->attributes |= attr;
        }
 }
 
@@ -10090,16 +10098,22 @@ rdataset_putadditional(dns_acache_t *acache, dns_rdataset_t *rdataset,
 static void
 setownercase(rdatasetheader_t *header, const dns_name_t *name) {
        unsigned int i;
+       isc_boolean_t fully_lower;
 
        /*
         * We do not need to worry about label lengths as they are all
         * less than or equal to 63.
         */
        memset(header->upper, 0, sizeof(header->upper));
+       fully_lower = ISC_TRUE;
        for (i = 0; i < name->length; i++)
-               if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a)
+               if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a) {
                        header->upper[i/8] |= 1 << (i%8);
+                       fully_lower = ISC_FALSE;
+               }
        header->attributes |= RDATASET_ATTR_CASESET;
+       if (ISC_LIKELY(fully_lower))
+               header->attributes |= RDATASET_ATTR_CASEFULLYLOWER;
 }
 
 static void
@@ -10111,17 +10125,94 @@ rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
        setownercase(header, name);
 }
 
+static const unsigned char charmask[] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+       0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char maptolower[] = {
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+       0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+       0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+       0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+       0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+       0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+       0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+       0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+       0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+       0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+       0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+       0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+       0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+       0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+       0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+       0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+       0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+       0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+       0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+       0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+       0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+       0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+       0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+       0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+       0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+       0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
 static void
 rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
        const unsigned char *raw = rdataset->private3;        /* RDATASLAB */
        const rdatasetheader_t *header;
-       unsigned int i;
+       unsigned int i, j;
+       unsigned char bits;
+       unsigned char c, flip;
 
        header = (const struct rdatasetheader *)(raw - sizeof(*header));
 
        if (!CASESET(header))
                return;
 
+#if 0
+       /*
+        * This was the original code, and is implemented differently in
+        * the #else block that follows.
+        */
        for (i = 0; i < name->length; i++) {
                /*
                 * Set the case bit if it does not match the recorded bit.
@@ -10133,6 +10224,63 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
                         (header->upper[i/8] & (1 << (i%8))) == 0)
                        name->ndata[i] |= 0x20; /* set the lower case bit */
        }
+#else
+       if (ISC_LIKELY(CASEFULLYLOWER(header))) {
+               unsigned char *bp, *be;
+               bp = name->ndata;
+               be = bp + name->length;
+
+               while (bp <= be - 4) {
+                       c = bp[0];
+                       bp[0] = maptolower[c];
+                       c = bp[1];
+                       bp[1] = maptolower[c];
+                       c = bp[2];
+                       bp[2] = maptolower[c];
+                       c = bp[3];
+                       bp[3] = maptolower[c];
+                       bp += 4;
+               }
+               while (bp < be) {
+                       c = *bp;
+                       *bp++ = maptolower[c];
+               }
+               return;
+       }
+
+       i = 0;
+       for (j = 0; j < (name->length >> 3); j++) {
+               unsigned int k;
+
+               bits = ~(header->upper[j]);
+
+               for (k = 0; k < 8; k++) {
+                       c = name->ndata[i];
+                       flip = (bits & 1) << 5;
+                       flip ^= c;
+                       flip &= charmask[c];
+                       name->ndata[i] ^= flip;
+
+                       i++;
+                       bits >>= 1;
+               }
+       }
+
+       if (ISC_UNLIKELY(i == name->length))
+               return;
+
+       bits = ~(header->upper[j]);
+
+       for (; i < name->length; i++) {
+               c = name->ndata[i];
+               flip = (bits & 1) << 5;
+               flip ^= c;
+               flip &= charmask[c];
+               name->ndata[i] ^= flip;
+
+               bits >>= 1;
+       }
+#endif
 }
 
 /*%
index c2d6e6b504c20a04cf7a5c60bce5cf8476585770..d746954147290cf8f69dc8c2c80ce130088b0440 100644 (file)
@@ -125,7 +125,7 @@ dns_ssu_external_match(dns_name_t *identity,
        int fd;
        const char *sock_path;
        unsigned int req_len;
-       isc_region_t token_region;
+       isc_region_t token_region = {NULL, 0};
        unsigned char *data;
        isc_buffer_t buf;
        isc_uint32_t token_len = 0;
index a9c5992c58d49b858a9b2ff1dbd52369b48d3035..c1d85b6d60cdc2e2d3ee5cb9b1213d11748725c3 100644 (file)
@@ -397,6 +397,7 @@ isc__hash_setvec(const isc_uint16_t *vec) {
 
 static isc_uint32_t fnv_offset_basis;
 static isc_once_t fnv_once = ISC_ONCE_INIT;
+static isc_boolean_t fnv_initialized = ISC_FALSE;
 
 static void
 fnv_initialize(void) {
@@ -408,11 +409,14 @@ fnv_initialize(void) {
        while (fnv_offset_basis == 0) {
                isc_random_get(&fnv_offset_basis);
        }
+
+       fnv_initialized = ISC_TRUE;
 }
 
 const void *
 isc_hash_get_initializer(void) {
-       RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+       if (ISC_UNLIKELY(!fnv_initialized))
+               RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
 
        return (&fnv_offset_basis);
 }
@@ -425,7 +429,8 @@ isc_hash_set_initializer(const void *initializer) {
         * Ensure that fnv_initialize() is not called after
         * isc_hash_set_initializer() is called.
         */
-       RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+       if (ISC_UNLIKELY(!fnv_initialized))
+               RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
 
        fnv_offset_basis = *((const unsigned int *) initializer);
 }
@@ -440,7 +445,9 @@ isc_hash_function(const void *data, size_t length,
        const unsigned char *be;
 
        REQUIRE(length == 0 || data != NULL);
-       RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+
+       if (ISC_UNLIKELY(!fnv_initialized))
+               RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
 
        hval = ISC_UNLIKELY(previous_hashp != NULL) ?
                *previous_hashp : fnv_offset_basis;
@@ -461,35 +468,35 @@ isc_hash_function(const void *data, size_t length,
         */
 
        if (case_sensitive) {
-               while (bp < be - 4) {
-                       hval ^= (isc_uint32_t) bp[0];
+               while (bp <= be - 4) {
+                       hval ^= bp[0];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) bp[1];
+                       hval ^= bp[1];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) bp[2];
+                       hval ^= bp[2];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) bp[3];
+                       hval ^= bp[3];
                        hval *= 16777619;
                        bp += 4;
                }
                while (bp < be) {
-                       hval ^= (isc_uint32_t) *bp++;
+                       hval ^= *bp++;
                        hval *= 16777619;
                }
        } else {
-               while (bp < be - 4) {
-                       hval ^= (isc_uint32_t) maptolower[bp[0]];
+               while (bp <= be - 4) {
+                       hval ^= maptolower[bp[0]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[bp[1]];
+                       hval ^= maptolower[bp[1]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[bp[2]];
+                       hval ^= maptolower[bp[2]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[bp[3]];
+                       hval ^= maptolower[bp[3]];
                        hval *= 16777619;
                        bp += 4;
                }
                while (bp < be) {
-                       hval ^= (isc_uint32_t) maptolower[*bp++];
+                       hval ^= maptolower[*bp++];
                        hval *= 16777619;
                }
        }
@@ -507,7 +514,9 @@ isc_hash_function_reverse(const void *data, size_t length,
        const unsigned char *be;
 
        REQUIRE(length == 0 || data != NULL);
-       RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
+
+       if (ISC_UNLIKELY(!fnv_initialized))
+               RUNTIME_CHECK(isc_once_do(&fnv_once, fnv_initialize) == ISC_R_SUCCESS);
 
        hval = ISC_UNLIKELY(previous_hashp != NULL) ?
                *previous_hashp : fnv_offset_basis;
@@ -530,33 +539,33 @@ isc_hash_function_reverse(const void *data, size_t length,
        if (case_sensitive) {
                while (be >= bp + 4) {
                        be -= 4;
-                       hval ^= (isc_uint32_t) be[3];
+                       hval ^= be[3];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) be[2];
+                       hval ^= be[2];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) be[1];
+                       hval ^= be[1];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) be[0];
+                       hval ^= be[0];
                        hval *= 16777619;
                }
                while (--be >= bp) {
-                       hval ^= (isc_uint32_t) *be;
+                       hval ^= *be;
                        hval *= 16777619;
                }
        } else {
                while (be >= bp + 4) {
                        be -= 4;
-                       hval ^= (isc_uint32_t) maptolower[be[3]];
+                       hval ^= maptolower[be[3]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[be[2]];
+                       hval ^= maptolower[be[2]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[be[1]];
+                       hval ^= maptolower[be[1]];
                        hval *= 16777619;
-                       hval ^= (isc_uint32_t) maptolower[be[0]];
+                       hval ^= maptolower[be[0]];
                        hval *= 16777619;
                }
                while (--be >= bp) {
-                       hval ^= (isc_uint32_t) maptolower[*be];
+                       hval ^= maptolower[*be];
                        hval *= 16777619;
                }
        }
index 7f97ee20351e19b6d1bbc9e0c398b9add25c0c9e..569471f0bfdb56fa56ffce446d75685e221ea33b 100644 (file)
 #include <isc/types.h>
 
 /*!
- * To make many functions be inline macros (via \#define) define this.
- * If it is undefined, a function will be used.
+ * To make many functions be inline macros (via \#define) define this to 1.
+ * To use continue to use them as functions define this to 0.
  */
-/* #define ISC_BUFFER_USEINLINE */
+#ifndef ISC_BUFFER_USEINLINE
+#define ISC_BUFFER_USEINLINE 1
+#endif
 
 ISC_LANG_BEGINDECLS
 
@@ -908,6 +910,7 @@ ISC_LANG_ENDDECLS
 #define ISC__BUFFER_PUTUINT8(_b, _val) \
        do { \
                unsigned char *_cp; \
+               /* evaluate (_val) only once */ \
                isc_uint8_t _val2 = (_val); \
                if (ISC_UNLIKELY((_b)->autore)) { \
                        isc_buffer_t *_tmp = _b; \
@@ -917,12 +920,13 @@ ISC_LANG_ENDDECLS
                ISC_REQUIRE(isc_buffer_availablelength(_b) >= 1U); \
                _cp = isc_buffer_used(_b); \
                (_b)->used++; \
-               _cp[0] = _val2 & 0x00ff; \
+               _cp[0] = _val2; \
        } while (0)
 
 #define ISC__BUFFER_PUTUINT16(_b, _val) \
        do { \
                unsigned char *_cp; \
+               /* evaluate (_val) only once */ \
                isc_uint16_t _val2 = (_val); \
                if (ISC_UNLIKELY((_b)->autore)) { \
                        isc_buffer_t *_tmp = _b; \
@@ -932,13 +936,14 @@ ISC_LANG_ENDDECLS
                ISC_REQUIRE(isc_buffer_availablelength(_b) >= 2U); \
                _cp = isc_buffer_used(_b); \
                (_b)->used += 2; \
-               _cp[0] = (unsigned char)((_val2 & 0xff00U) >> 8); \
-               _cp[1] = (unsigned char)(_val2 & 0x00ffU); \
+               _cp[0] = _val2 >> 8; \
+               _cp[1] = _val2; \
        } while (0)
 
 #define ISC__BUFFER_PUTUINT24(_b, _val) \
        do { \
                unsigned char *_cp; \
+               /* evaluate (_val) only once */ \
                isc_uint32_t _val2 = (_val); \
                if (ISC_UNLIKELY((_b)->autore)) { \
                        isc_buffer_t *_tmp = _b; \
@@ -948,14 +953,15 @@ ISC_LANG_ENDDECLS
                ISC_REQUIRE(isc_buffer_availablelength(_b) >= 3U); \
                _cp = isc_buffer_used(_b); \
                (_b)->used += 3; \
-               _cp[0] = (unsigned char)((_val2 & 0xff0000U) >> 16); \
-               _cp[1] = (unsigned char)((_val2 & 0xff00U) >> 8); \
-               _cp[2] = (unsigned char)(_val2 & 0x00ffU); \
+               _cp[0] = _val2 >> 16; \
+               _cp[1] = _val2 >> 8; \
+               _cp[2] = _val2; \
        } while (0)
 
 #define ISC__BUFFER_PUTUINT32(_b, _val) \
        do { \
                unsigned char *_cp; \
+               /* evaluate (_val) only once */ \
                isc_uint32_t _val2 = (_val); \
                if (ISC_UNLIKELY((_b)->autore)) { \
                        isc_buffer_t *_tmp = _b; \
@@ -965,13 +971,13 @@ ISC_LANG_ENDDECLS
                ISC_REQUIRE(isc_buffer_availablelength(_b) >= 4U); \
                _cp = isc_buffer_used(_b); \
                (_b)->used += 4; \
-               _cp[0] = (unsigned char)((_val2 & 0xff000000) >> 24); \
-               _cp[1] = (unsigned char)((_val2 & 0x00ff0000) >> 16); \
-               _cp[2] = (unsigned char)((_val2 & 0x0000ff00) >> 8); \
-               _cp[3] = (unsigned char)((_val2 & 0x000000ff)); \
+               _cp[0] = _val2 >> 24; \
+               _cp[1] = _val2 >> 16; \
+               _cp[2] = _val2 >> 8; \
+               _cp[3] = _val2; \
        } while (0)
 
-#if defined(ISC_BUFFER_USEINLINE)
+#if ISC_BUFFER_USEINLINE
 #define isc_buffer_init                        ISC__BUFFER_INIT
 #define isc_buffer_initnull            ISC__BUFFER_INITNULL
 #define isc_buffer_invalidate          ISC__BUFFER_INVALIDATE
index d8bedc4a470ec3c1fa01bf26566ad5004d6a9a8a..2926ed141a5c4bed95c67e89e072e2ebc8ac13c8 100644 (file)
 #define ISC_MSG_POSTLOCK       1207 /*%< "postlock" */
 #define ISC_MSG_PREUNLOCK      1208 /*%< "preunlock" */
 #define ISC_MSG_POSTUNLOCK     1209 /*%< "postunlock" */
+#define ISC_MSG_PRINTLOCK2     1210 /*%< "rwlock %p thread %lu ..." w/ atomic */
 
 #define ISC_MSG_UNKNOWNFAMILY  1301 /*%< "unknown address family: %d" */
 
index 63b1fdc785f2486f2b0ea2230566f0190d7ba450..1442a32db68fae6efe281d94b73cf808d46f922b 100644 (file)
@@ -198,14 +198,19 @@ struct isc__mempool {
 #define DELETE_TRACE(a, b, c, d, e)
 #define ISC_MEMFUNC_SCOPE
 #else
+#define TRACE_OR_RECORD (ISC_MEM_DEBUGTRACE|ISC_MEM_DEBUGRECORD)
 #define ADD_TRACE(a, b, c, d, e) \
        do { \
-               if ((isc_mem_debugging & (ISC_MEM_DEBUGTRACE | \
-                                         ISC_MEM_DEBUGRECORD)) != 0 && \
+               if ((isc_mem_debugging & TRACE_OR_RECORD) != 0 && \
                     b != NULL) \
                         add_trace_entry(a, b, c, d, e); \
        } while (0)
-#define DELETE_TRACE(a, b, c, d, e)    delete_trace_entry(a, b, c, d, e)
+#define DELETE_TRACE(a, b, c, d, e)                                    \
+       do {                                                            \
+               if ((isc_mem_debugging & TRACE_OR_RECORD) != 0 &&       \
+                   b != NULL)                                          \
+                       delete_trace_entry(a, b, c, d, e);              \
+       } while(0)
 
 static void
 print_active(isc__mem_t *ctx, FILE *out);
@@ -1508,9 +1513,7 @@ isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
        if (((ctx->flags & ISC_MEMFLAG_INTERNAL) == 0) && (si != NULL))
                mem_getstats(ctx, si[-1].u.size);
 
-#if ISC_MEM_TRACKLINES
        ADD_TRACE(ctx, si, si[-1].u.size, file, line);
-#endif
        if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&
            !ctx->is_overmem) {
                ctx->is_overmem = ISC_TRUE;
@@ -2031,7 +2034,7 @@ isc___mempool_get(isc_mempool_t *mpctx0 FLARG) {
                UNLOCK(mpctx->lock);
 
 #if ISC_MEM_TRACKLINES
-       if (item != NULL) {
+       if (((isc_mem_debugging & TRACE_OR_RECORD) != 0) && item != NULL) {
                MCTXLOCK(mctx, &mctx->lock);
                ADD_TRACE(mctx, item, mpctx->size, file, line);
                MCTXUNLOCK(mctx, &mctx->lock);
@@ -2060,9 +2063,11 @@ isc___mempool_put(isc_mempool_t *mpctx0, void *mem FLARG) {
        mpctx->allocated--;
 
 #if ISC_MEM_TRACKLINES
-       MCTXLOCK(mctx, &mctx->lock);
-       DELETE_TRACE(mctx, mem, mpctx->size, file, line);
-       MCTXUNLOCK(mctx, &mctx->lock);
+       if ((isc_mem_debugging & TRACE_OR_RECORD) != 0) {
+               MCTXLOCK(mctx, &mctx->lock);
+               DELETE_TRACE(mctx, mem, mpctx->size, file, line);
+               MCTXUNLOCK(mctx, &mctx->lock);
+       }
 #endif /* ISC_MEM_TRACKLINES */
 
        /*
@@ -2286,17 +2291,19 @@ isc_mem_checkdestroyed(FILE *file) {
        RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
 
        LOCK(&contextslock);
-       if (!ISC_LIST_EMPTY(contexts))  {
+       if (!ISC_LIST_EMPTY(contexts)) {
 #if ISC_MEM_TRACKLINES
-               isc__mem_t *ctx;
-
-               for (ctx = ISC_LIST_HEAD(contexts);
-                    ctx != NULL;
-                    ctx = ISC_LIST_NEXT(ctx, link)) {
-                       fprintf(file, "context: %p\n", ctx);
-                       print_active(ctx, file);
+               if ((isc_mem_debugging & TRACE_OR_RECORD) != 0) {
+                       isc__mem_t *ctx;
+
+                       for (ctx = ISC_LIST_HEAD(contexts);
+                            ctx != NULL;
+                            ctx = ISC_LIST_NEXT(ctx, link)) {
+                               fprintf(file, "context: %p\n", ctx);
+                               print_active(ctx, file);
+                       }
+                       fflush(file);
                }
-               fflush(file);
 #endif
                INSIST(0);
        }
index 234159ce32c422dac8c82ff1c480314fd2dc7418..1ad80e852b7e538d9fed1ed759fe0ac7d9e1609c 100644 (file)
@@ -50,6 +50,24 @@ isc__rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
 
 static void
 print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+       fprintf(stderr,
+               isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+                              ISC_MSG_PRINTLOCK2,
+                              "rwlock %p thread %lu %s(%s): "
+                              "write_requests=%u, write_completions=%u, "
+                              "cnt_and_flag=0x%x, readers_waiting=%u, "
+                              "write_granted=%u, write_quota=%u\n"),
+               rwl, isc_thread_self(), operation,
+               (type == isc_rwlocktype_read ?
+                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+                               ISC_MSG_READ, "read") :
+                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
+                               ISC_MSG_WRITE, "write")),
+               rwl->write_requests, rwl->write_completions,
+               rwl->cnt_and_flag, rwl->readers_waiting,
+               rwl->write_granted, rwl->write_quota);
+#else
        fprintf(stderr,
                isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
                               ISC_MSG_PRINTLOCK,
@@ -66,10 +84,11 @@ print_lock(const char *operation, isc_rwlock_t *rwl, isc_rwlocktype_t type) {
                                ISC_MSG_READING, "reading") :
                 isc_msgcat_get(isc_msgcat, ISC_MSGSET_RWLOCK,
                                ISC_MSG_WRITING, "writing")),
-               rwl->active, rwl->granted, rwl->readers_waiting,
-               rwl->writers_waiting);
-}
+               rwl->active, rwl->granted,
+               rwl->readers_waiting, rwl->writers_waiting);
 #endif
+}
+#endif /* ISC_RWLOCK_TRACE */
 
 isc_result_t
 isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,