diff --git a/lib/isc/queue.c b/lib/isc/queue.c index 1729079906..5072adaaa5 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); }