Last active
October 19, 2022 10:58
-
-
Save rlapz/b49791f8879d39ac25f30cdbfa96350f to your computer and use it in GitHub Desktop.
Ring buffer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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