toys

toys.git
git clone git://git.lenczewski.org/toys.git
Log | Files | Refs | README | LICENSE

commit 027d9b04bb1fae62fbb1c842395ad1dacacc121f
parent 23ce869de42558066c42f905411e89354040cf23
Author: MikoĊ‚aj Lenczewski <mikolaj@lenczewski.org>
Date:   Tue,  9 Dec 2025 12:18:36 +0000

Warn about usefulness of spsc_queue_length()

Diffstat:
Mqueue.h | 20++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/queue.h b/queue.h @@ -220,11 +220,27 @@ spsc_queue_free(struct spsc_queue *queue) munmap(queue->ptr, queue->cap * 2); } +// NOTE: this (spsc_queue_length()) and its cousin (spsc_queue_capacity()) are +// not a great interface. For one, they are slow as molasses, and to be +// honest I'm neither sure of it being correct or it being useful (since +// in high-contention scenarios the length of the queue at the moment of +// calling the function will become stale pretty quickly). It might be +// far better to simply attempt a read or write, and detect a full queue +// by the return value (a return value of NULL means it was not possible +// to reserve a buffer of the given size). +// +// Included solely for "feature parity" with the unsynchronised queue + inline size_t spsc_queue_length(struct spsc_queue *queue) { - size_t head = atomic_load_explicit(&queue->head, memory_order_acquire); - size_t tail = atomic_load_explicit(&queue->tail, memory_order_acquire); + size_t head, tail; + + do { + head = atomic_load_explicit(&queue->head, memory_order_acquire); + tail = atomic_load_explicit(&queue->tail, memory_order_acquire); + } while (atomic_load_explicit(&queue->head, memory_order_acquire) != head); + return head - tail; }