CK_RING_DEQUEUE_SPMC(3)

πŸ’– NAME πŸ’–

ck_ring_dequeue_spmc β€” dequeue pointer from bounded FIFO 🌸

okay so bestie, this is the Concurrency Kit manual, section 3, and we're talking about ck_ring_dequeue_spmc(3) specifically. she's a single-consumer girlie pulling pointers out of a bounded FIFO. let's get into it πŸ’…


πŸ“š LIBRARY πŸ“š

Concurrency Kit (libck, -lck) 🫢


✨ SYNOPSIS ✨

#include <ck_ring.h>

bool
ck_ring_dequeue_spmc(ck_ring_t *ring, ck_ring_buffer_t *buffer,
    void *result);

πŸ¦‹ DESCRIPTION πŸ¦‹

so like, ck_ring_dequeue_spmc(3) dequeues a pointer from the bounded buffer pointed to by ring, and she does it FIFO fashion β€” first in, first out, no cutting the line bestie πŸ’…. That pointer gets stored in the pointer pointed to by result. easy!

now here's the thing: the buffer pointed to by buffer must be unique to ring. like, not shared, not communal, hers and hers only πŸ™ˆ. the whole reason the ring and the buffer are decoupled like this is to address use-cases involving multiple address spaces and DMA, among others β€” it's giving "separation for the plot" ✨.

if you're on non-POSIX platforms, or you just want strict compliance with C, then it's recommended that you pass a pointer of type void ** for result. noted πŸŽ€

and the actual concurrency tea: this function is safe to call without locking for up to UINT_MAX concurrent invocations of ck_ring_dequeue_spmc(3) or ck_ring_trydequeue_spmc(3), and up to one concurrent ck_ring_enqueue_spmc(3) or ck_ring_tryenqueue_spmc(3) invocation. one. single. producer. the way she has lock-free progress guarantees? iconic, no notes πŸ‘‘

bestie pls respect the one-producer limit, it's not a suggestion, it's the whole vibe of the algorithm πŸ’€

🌈 EXAMPLE 🌈

#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
dequeue(void)
{
        void *result;

        /* Dequeue from ring until it is empty. */
        while (ck_ring_dequeue_spmc(&ring, &buffer, &result) == true) {
                /*
                 * Results contains the oldest pointer in ring
                 * since the dequeue operation returned true.
                 */
                operation(result);
        }

        /* An empty ring was encountered, leave. */
        return;
}

see how she just keeps looping until the ring says "ma'am, I'm empty"? πŸ₯Ή the oldest pointer comes out first every time. that's the FIFO fantasy fr fr.


πŸŽ€ RETURN VALUES πŸŽ€

  • the function returns true if the buffer was non-empty πŸ’–
  • the result of the dequeue operation is stored in the value pointed to by result ✨
  • the function returns false if the buffer was empty β€” and heads up, when that happens the value in result is undefined 😭 so don't go reading it, that's a trap bestie

πŸ‘‘ SEE ALSO πŸ‘‘

additional info available at http://concurrencykit.org/ 🌐


and that's the whole page bestie 🫢 this diva was written back on April 20, 2013 and lives in the CK_RING_DEQUEUE_SPMC(3) era of the Concurrency Kit manual. go forth and dequeue responsibly πŸ’…βœ¨πŸŒ™

πŸ“¦ where this page comes from