CK_RING_ENQUEUE_SPSC_SIZE(3)
π ck_ring_enqueue_spsc_size β the "enqueue a pointer AND get the size back" moment π
okay bestie, welcome to ck_ring_enqueue_spsc_size(3), part of the Concurrency Kit, aka libck (you link it with -lck, no cap π). this is the single-producer-single-consumer ring enqueue that ALSO tells you how big the buffer got. it's giving main character energy and we're obsessed.
β¨ SYNOPSIS β¨
#include <ck_ring.h>
bool
ck_ring_enqueue_spsc_size(ck_ring_t *ring, ck_ring_buffer_t *buffer,
void *entry, unsigned int *size);
like, four args, one bool, and a lil pointer to an unsigned int for the size. we love a signature that just works π«Ά
πΈ DESCRIPTION πΈ
so what this does: ck_ring_enqueue_spsc_size(3) enqueues the pointer entry into the bounded buffer that ring points at, and it does it FIFO style β first in, first out, periodt. β¨
the buffer that buffer points to has to be unique to ring, bestie, and it has to point to an array of ck_ring_buffer_t of sufficient length β and that length is determined by the power-of-2 number of elements in the buffer. (yes, power of 2. the vibes must be binary.) π₯
why is the ring decoupled from the buffer like this? because it addresses use-cases involving multiple address spaces and DMA, among others. it's a whole thing, and honestly? iconic. π
if you're on non-POSIX platforms, or you're just out here wanting strict compliance with C, then it's recommended that you pass a pointer of type void ** for entry. lowkey important, don't skip that.
this function is safe to call without locking for up to one concurrent invocation of ck_ring_dequeue_spsc(3). one. that's the number. don't get greedy. π
and it provides wait-free progress guarantees, which is the technical way of saying "she does not block, she does not wait, she slays." π
π¦ EXAMPLE π¦
here's the whole vibe, verbatim, because code is sacred:
#include <ck_ring.h>
/* This ring was previously initialized with ck_ring_init. */
ck_ring_t ring;
/* The ring was initialized for 1023 elements. */
ck_ring_buffer_t buffer[1024];
void
enqueue(void)
{
void *entry = some_object;
unsigned int length;
/* Attempt to enqueue pointer to some_object into buffer. */
if (ck_ring_enqueue_spsc(&ring, &buffer, &entry, &length) == false) {
/*
* The buffer was full and the enqueue operation
* has failed.
*/
return;
}
/*
* If buffer length was 100 items or more at the time entry was
* enqueued, do something.
*/
if (length > 100) {
do_something;
}
return;
}
notice the 1023 elements but buffer[1024]? that's the power-of-2 thing doing its thing, bestie. the ring is set up for 1023 elements and the backing array is 1024. β¨ also note that when the enqueue fails, it's because the buffer was full, and when it succeeds you get length back and can go if (length > 100) { do_something; }. that's the whole point of the _size version β you get the receipts. π§Ύπ
π RETURN VALUES π
so here's the tea:
- the function returns
trueif the value ofentrywas successfully enqueued intoring. π - it'll return the number of items in
ringwith respect to the linearization point β that's the exact point in time whereentrygets enqueued. yes, a real moment. a moment most pivotal in the timeline. β - it returns
falseif the value ofentrycould not be enqueued, which only happens ifringwas full. that's it. that's the only failure mode. full ring, no room, try again later. π
π SEE ALSO π
go read these too, bestie, they're all part of the family:
ck_ring_init(3)ck_ring_dequeue_spmc(3)ck_ring_trydequeue_spmc(3)ck_ring_enqueue_spmc(3)ck_ring_enqueue_spmc_size(3)ck_ring_dequeue_spsc(3)ck_ring_enqueue_spsc(3)ck_ring_capacity(3)ck_ring_size(3)
and there's more lore available at http://concurrencykit.org/ if you want to go down the rabbit hole πβ¨
kay that's the whole page, bestie π this one came from the Concurrency Kit source, dated April 20, 2013, and it lives in the manual as CK_RING_ENQUEUE_SPSC_SIZE(3). go enqueue something. slay. π π
π¦ where this page comes from
- alpine 3.24: ck-doc 0.7.2-r1 Β· BSD-2-Clause AND Apache-2.0
- debian bookworm: libck-dev 0.7.1-10 Β· BSD-2-Clause
- debian trixie: libck-dev 0.7.2-6 Β· BSD-2-Clause
- epel 10: ck-devel 0.7.2-1.el10_1 Β· BSD-2-clause AND Apache-2.0 AND BSD-3-clause
- epel 9: ck-devel 0.7.0-10.el9 Β· BSD
- fedora 43: ck-devel 0.7.2-2.fc43 Β· BSD-2-clause AND Apache-2.0 AND BSD-3-clause
- fedora 43: ck-devel 0.7.2-2.fc43 Β· BSD-2-clause AND Apache-2.0 AND BSD-3-clause
- fedora 44: ck-devel 0.7.2-4.fc44 Β· BSD-2-clause AND Apache-2.0 AND BSD-3-clause
- fedora 44: ck-devel 0.7.2-4.fc44 Β· BSD-2-clause AND Apache-2.0 AND BSD-3-clause
- nixos 26.05: ck 0.7.2
- nixpkgs unstable: ck 0.7.2
- opensuse-leap 16.0: ck-devel 0.7.2-bp160.1.9 Β· Apache-2.0 AND BSD-2-Clause
- opensuse-leap 16.0: ck-devel 0.7.2-bp160.1.9 Β· Apache-2.0 AND BSD-2-Clause
- opensuse-leap 16.0: ck-devel 0.7.2-bp160.1.9 Β· Apache-2.0 AND BSD-2-Clause
- ubuntu jammy: libck-dev 0.7.1-6ubuntu2 Β· BSD-2-Clause
- ubuntu noble: libck-dev 0.7.1-13build1 Β· BSD-2-Clause
- ubuntu questing: libck-dev 0.7.2-5ubuntu1
- ubuntu resolute: libck-dev 0.7.2-5ubuntu2 Β· BSD-2-Clause
- ubuntu stonking: libck-dev 0.7.2-11 Β· BSD-2-Clause
- Copyright 2012-2013 Samy Al Bahra
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms