#define MAX_THREADS 128
+#define ALIGNMENT 128
+
static uintptr_t nulluintptr = (uintptr_t)NULL;
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 *
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;
*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);
void
isc_queue_destroy(isc_queue_t *queue) {
node_t *last = NULL;
+ void *alloced = NULL;
REQUIRE(queue != NULL);
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);
}