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:
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;
}