BUF_RING(9)

πŸ’– BUF_RING πŸ’–

okay bestie, welcome to the buf_ring page from the Kernel Developer's Manual (that's section 9, kernel dev territory, we're in the big leagues now πŸ‘‘). this is the lock-less ring buffer situation and honestly? it's giving main character energy. let's get into it πŸ¦‹


✨ NAME ✨

buf_ring, buf_ring_alloc, buf_ring_free, buf_ring_enqueue, buf_ring_dequeue_mc, buf_ring_dequeue_sc, buf_ring_count, buf_ring_empty, buf_ring_full, buf_ring_peek β€” the multi-producer, {single, multi}-consumer lock-less ring buffer 🌈


✨ SYNOPSIS ✨

first things first, you gotta pull in the headers, no cap:

#include <sys/param.h>
#include <sys/buf_ring.h>

and here's the whole squad of function signatures, character for character, don't come for me:

struct buf_ring *
buf_ring_alloc(int count, struct malloc_type *type, int flags,
    struct mtx *sc_lock);

void
buf_ring_free(struct buf_ring *br, struct malloc_type *type);

int
buf_ring_enqueue(struct buf_ring *br, void *buf);

void *
buf_ring_dequeue_mc(struct buf_ring *br);

void *
buf_ring_dequeue_sc(struct buf_ring *br);

int
buf_ring_count(struct buf_ring *br);

int
buf_ring_empty(struct buf_ring *br);

int
buf_ring_full(struct buf_ring *br);

void *
buf_ring_peek(struct buf_ring *br);

✨ DESCRIPTION ✨

so the buf_ring functions hand you a lock-less multi-producer and lock-less multi-consumer ring buffer, plus a single-consumer one too. yes, lock-less. yes, that's iconic. πŸ’…

the functions, one by one πŸŽ€

  • buf_ring_alloc() β€” this is the one that actually makes the ring buffer happen. it allocates a buf_ring with count slots, using malloc type type and memory flags flags. and listen: the single consumer interface is protected by sc_lock. protect it, bestie 🫢
  • buf_ring_free() β€” frees a buf_ring. important though: you, the user, are responsible for freeing any enqueued items. it will not do that for you. it's not your mom, it's not your bestie, it's a free function. clean up after yourself fr fr 😭
  • buf_ring_enqueue() β€” enqueues a buffer onto a buf_ring. in it goes πŸ“
  • buf_ring_dequeue_mc() β€” the multi-consumer safe way to dequeue elements from a buf_ring. multiple consumers? no problem, she's built different.
  • buf_ring_dequeue_sc() β€” the single-consumer interface for dequeueing elements. ⚠️ catch: it requires you to serialize accesses with a lock. yes you. with a lock. don't skip this part πŸ™ˆ
  • buf_ring_count() β€” returns the number of elements currently chilling in the buf_ring.
  • buf_ring_empty() β€” returns TRUE if the buf_ring is empty, FALSE otherwise. vibe check: is it empty?
  • buf_ring_full() β€” returns TRUE if no more items can be enqueued, FALSE otherwise. she's full, she can't take anymore πŸ’€
  • buf_ring_peek() β€” returns a pointer to the last element in the buf_ring if the buf_ring is not empty, and NULL otherwise. just a lil peek, no dequeue, no strings attached πŸ‘€

✨ RETURN VALUES ✨

  • buf_ring_enqueue() returns ENOBUFS if there are no available slots in the buf_ring. that's it, that's the whole list. no room at the inn, bestie 🚫

✨ HISTORY ✨

these functions were introduced in FreeBSD 8.0. vintage, but make it lock-less. ⭐


okay that's the whole page, you ate that. go forth and ring buffer responsibly πŸ’œ

sign-off time: this lil manual page comes from Debian, dated September 27, 2012 β€” so yeah, she's been around a minute, and she still slays. πŸŽ€βœ¨

πŸ“¦ where this page comes from