ensure isc_queue_t is aligned to double-cacheline size

This commit is contained in:
Witold Kręcicki 2019-11-15 10:47:08 +01:00 committed by Evan Hunt
parent 123ee350dc
commit 6718a4ef8b

View file

@ -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);
}