From: Witold Kręcicki Date: Fri, 15 Nov 2019 09:47:08 +0000 (+0100) Subject: ensure isc_queue_t is aligned to double-cacheline size X-Git-Tag: v9.15.6~1^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6718a4ef8b55935d4417e59a2b0e005a82e84747;p=thirdparty%2Fbind9.git ensure isc_queue_t is aligned to double-cacheline size --- diff --git a/lib/isc/queue.c b/lib/isc/queue.c index 17290799067..5072adaaa58 100644 --- a/lib/isc/queue.c +++ b/lib/isc/queue.c @@ -22,6 +22,8 @@ #define MAX_THREADS 128 +#define ALIGNMENT 128 + static uintptr_t nulluintptr = (uintptr_t)NULL; typedef struct node { @@ -37,12 +39,13 @@ typedef struct node { #define HP_HEAD 0 struct isc_queue { - alignas(128) atomic_uintptr_t head; - alignas(128) atomic_uintptr_t tail; + alignas(ALIGNMENT) atomic_uintptr_t head; + alignas(ALIGNMENT) atomic_uintptr_t tail; isc_mem_t *mctx; int max_threads; int taken; isc_hp_t *hp; + void* alloced_ptr; }; static node_t * @@ -96,8 +99,17 @@ queue_cas_head(isc_queue_t *queue, node_t *cmp, const node_t *val) { isc_queue_t * isc_queue_new(isc_mem_t *mctx, int max_threads) { - isc_queue_t *queue = isc_mem_get(mctx, sizeof(*queue)); - node_t *sentinel = node_new(mctx, nulluintptr); + isc_queue_t *queue = NULL; + node_t *sentinel = NULL; + void *qbuf = NULL; + uintptr_t qptr; + + /* + * A trick to allocate an aligned isc_queue_t structure + */ + qbuf = isc_mem_get(mctx, sizeof(*queue) + ALIGNMENT); + qptr = (uintptr_t) qbuf; + queue = (isc_queue_t *) (qptr + (ALIGNMENT - (qptr % ALIGNMENT))); if (max_threads == 0) { max_threads = MAX_THREADS; @@ -105,13 +117,16 @@ isc_queue_new(isc_mem_t *mctx, int max_threads) { *queue = (isc_queue_t){ .max_threads = max_threads, + .alloced_ptr = qbuf, }; isc_mem_attach(mctx, &queue->mctx); queue->hp = isc_hp_new(mctx, 1, node_destroy); + sentinel = node_new(mctx, nulluintptr); atomic_init(&sentinel->enqidx, 0); + atomic_init(&queue->head, (uintptr_t)sentinel); atomic_init(&queue->tail, (uintptr_t)sentinel); @@ -205,6 +220,7 @@ isc_queue_dequeue(isc_queue_t *queue) { void isc_queue_destroy(isc_queue_t *queue) { node_t *last = NULL; + void *alloced = NULL; REQUIRE(queue != NULL); @@ -215,5 +231,8 @@ isc_queue_destroy(isc_queue_t *queue) { last = (node_t *)atomic_load_relaxed(&queue->head); node_destroy(last); isc_hp_destroy(queue->hp); - isc_mem_putanddetach(&queue->mctx, queue, sizeof(*queue)); + + alloced = queue->alloced_ptr; + isc_mem_putanddetach(&queue->mctx, alloced, + sizeof(*queue) + ALIGNMENT); }