From 3027af783cc6fe26eda14cbeb3f68541b3538355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A5re=20von=20Geijer?= Date: Wed, 11 Sep 2024 21:13:46 +0200 Subject: [PATCH] Re-use initialized ring queues, instead of leaking In the LCRQ, when another thread manages to enqueue a new ring queue with CAS before you manage, you have already initialized your RQ. Now the local one is just discarded, which leaks memory. There is infrastructure in place in the handle to save these initialized ring queues, and later re-use them in future enqueues. This commit fixes that optimization, which seems to have been broken sometime in the past. --- lcrq.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lcrq.c b/lcrq.c index 0bd61a1..b08e68d 100644 --- a/lcrq.c +++ b/lcrq.c @@ -126,6 +126,9 @@ static void lcrq_put(queue_t * q, handle_t * handle, uint64_t arg) { CAS(&q->tail, &rq, nrq); handle->next = NULL; return; + } else { + // Save the ring queue for future use in the thread-local handle + handle->next = nrq; } continue; } @@ -228,6 +231,7 @@ static uint64_t lcrq_get(queue_t * q, handle_t * handle) { void queue_register(queue_t * q, handle_t * th, int id) { hzdptr_init(&th->hzdptr, q->nprocs, 1); + th->next = NULL; } void enqueue(queue_t * q, handle_t * th, void * val) @@ -239,6 +243,7 @@ void * dequeue(queue_t * q, handle_t * th) { return (void *) lcrq_get(q, th); } + //By K void handle_free(handle_t *h){ hzdptr_t *hzd = &h->hzdptr; @@ -247,7 +252,11 @@ void handle_free(handle_t *h){ free(rlist[i]); } free(h->hzdptr.ptrs); + if (h->next != NULL){ + free(h->next); + } } + void queue_free(queue_t * q, handle_t * h){ RingQueue *rq = q->head; while(rq){