Skip to content

Instantly share code, notes, and snippets.

@rlapz
Last active October 19, 2022 10:58
Show Gist options
  • Save rlapz/b49791f8879d39ac25f30cdbfa96350f to your computer and use it in GitHub Desktop.
Save rlapz/b49791f8879d39ac25f30cdbfa96350f to your computer and use it in GitHub Desktop.
Ring buffer
/*
* Arthur Lapz <[email protected]>
*/
#ifndef ___AUTO_QUEUE_H___
#define ___AUTO_QUEUE_H___
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
struct auto_queue {
uint16_t count;
uint16_t head;
uint16_t tail;
uint16_t size;
uint16_t nmemb;
void *ptr;
};
static inline void
auto_queue_init(struct auto_queue *self, void *ptr, uint16_t nmemb,
uint16_t size)
{
self->count = 0;
self->head = 0;
self->tail = 0;
self->ptr = ptr;
self->nmemb = nmemb;
self->size = size;
}
static inline void *
auto_queue_init_alloc(struct auto_queue *self, uint16_t nmemb, uint16_t size)
{
void *ptr = malloc(nmemb * size);
if (ptr == NULL)
return NULL;
auto_queue_init(self, ptr, nmemb, size);
return ptr;
}
static inline void
auto_queue_reset(struct auto_queue *self)
{
self->head = 0;
self->tail = 0;
self->count = 0;
}
/*
* sqe: submission pointer(head)
*/
static inline void *
auto_queue_sqe(struct auto_queue *self)
{
const uint16_t size = self->size;
const uint16_t count = self->count;
if (count == size)
return NULL;
uint16_t head = self->head;
void *const ret = &((uint8_t *)self->ptr)[self->nmemb * head];
head++;
if (head >= size)
head = 0;
self->head = head;
self->count = count +1u;
return ret;
}
/* --- */
/*
* cqe: completion pointer(tail)
*/
static inline void *
auto_queue_cqe_peek(struct auto_queue *self)
{
if (self->count == 0)
return NULL;
return &((uint8_t *)self->ptr)[self->nmemb * self->tail];
}
static inline void
auto_queue_cqe_seen(struct auto_queue *self)
{
uint16_t tail = self->tail +1u;
if (tail >= (self->size))
tail = 0;
self->tail = tail;
self->count--;
}
static inline void *
auto_queue_cqe(struct auto_queue *self)
{
void *const ret = auto_queue_cqe_peek(self);
if (ret == NULL)
return NULL;
auto_queue_cqe_seen(self);
return ret;
}
#endif /* ___AUTO_QUEUE_H___ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment