#ifndef __RING_BUF_H__
#define __RING_BUF_H__
#include "stdint.h"
void* ring_slab_new(void *slab_addr, uint32_t slab_length, size_t item_size);
void ring_slab_del(void *slab);
void* ring_slab_put(void *slab);
bool ring_slab_put_done(void *slab);
void* ring_slab_get(void *slab);
bool ring_slab_get_done(void *slab);
bool ring_slab_empty(void *slab);
#endif
#include "string.h"
#include "ring_buf.h"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64)
#pragma pack(push, 1)
#else
#pragma pack(1)
#endif
typedef struct {
mys_byte_t type;
uint32_t length;
char value[0];
} ring_buf_tlv_t;
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64)
#pragma pack(pop)
#else
#pragma pack()
#endif
typedef struct {
uint32_t write;
uint32_t read;
uint32_t buf_size;
size_t max_item_size;
mys_bool_t writing;
mys_bool_t reading;
mys_byte_t *buf;
void *buf_addr;
} ring_buf_t;
void* ring_buf_new(void* buf_addr, uint32_t buf_size, size_t max_item_size)
{
ring_buf_t *ring_buf;
ring_buf = (ring_buf_t *)malloc(sizeof(ring_buf_t));
if (NULL == ring_buf) {
return NULL;
}
ring_buf->buf_size = buf_size;
ring_buf->max_item_size = max_item_size;
ring_buf->buf_addr = buf_addr;
if (NULL != buf_addr) {
ring_buf->buf = (mys_byte_t *)buf_addr;
} else {
ring_buf->buf = (mys_byte_t *)malloc(ring_buf->buf_size);
if (NULL == ring_buf->buf) {
free(ring_buf);
return NULL;
}
}
ring_buf->write = 0;
ring_buf->read = 0;
ring_buf->reading = FALSE;
ring_buf->writing = FALSE;
return (void *)ring_buf;
}
void ring_buf_del(void *buf)
{
ring_buf_t *ring_buf = (ring_buf_t *)buf;
free(ring_buf->buf);
if (NULL == ring_buf->buf_addr) {
free(ring_buf);
}
}
static bool ring_buf_readable(ring_buf_t *ring_buf)
{
ring_buf_tlv_t *tlv;
if (ring_buf->write == ring_buf->read) {
return FALSE;
}
tlv = (ring_buf_tlv_t *)&ring_buf->buf[ring_buf->read];
if (TYPE_JUMP == tlv->type) {
ring_buf->read = 0;
}
return (ring_buf->write != ring_buf->read);
}
static bool ring_buf_writable(ring_buf_t *ring_buf, uint32_t len)
{
ring_buf_tlv_t *tlv;
/* 2 bytes for type and length */
len = len + 5;
if (ring_buf->read > ring_buf->write) {
/* can't be >=, need at least 1 byte gap between read and write in case of buf full */
return (ring_buf->read - ring_buf->write > len);
} else {
/* wrap around */
if (ring_buf->buf_size - ring_buf->write > len) {
return TRUE;
}
if (ring_buf->read > len) {
tlv = (ring_buf_tlv_t *)&ring_buf->buf[ring_buf->write];
tlv->type = TYPE_JUMP;
ring_buf->write = 0;
return TRUE;
}
}
return FALSE;
}
void* ring_buf_put(void *buf)
{
ring_buf_tlv_t *tlv;
ring_buf_t *ring_buf = (ring_buf_t *)buf;
if (ring_buf->writing || !ring_buf_writable(ring_buf, ring_buf->max_item_size)) {
return NULL;
}
ring_buf->writing = TRUE;
tlv = (ring_buf_tlv_t *)&ring_buf->buf[ring_buf->write];
return tlv->value;
}
bool ring_buf_put_done(void *buf, uint32_t len)
{
ring_buf_tlv_t *tlv;
ring_buf_t *ring_buf = (ring_buf_t *)buf;
if (!ring_buf->writing) {
return FALSE;
}
if (len > ring_buf->max_item_size) {
ring_buf->writing = FALSE;
return FALSE;
} else if (0 == len) {
ring_buf->writing = FALSE;
return TRUE;
}
tlv = (ring_buf_tlv_t *)&ring_buf->buf[ring_buf->write];
tlv->type = TYPE_READ;
tlv->length = len;
ring_buf->write = (ring_buf->write + tlv->length + 5) % ring_buf->buf_size;
ring_buf->writing = FALSE;
return TRUE;
}
void* ring_buf_get(void *buf, uint32_t *len)
{
ring_buf_tlv_t *tlv;
ring_buf_t *ring_buf = (ring_buf_t *)buf;
if (ring_buf->reading || !ring_buf_readable(ring_buf)) {
return NULL;
}
ring_buf->reading = TRUE;
tlv = (ring_buf_tlv_t *)&ring_buf->buf[ring_buf->read];
tlv->type = TYPE_NULL;
*len = tlv->length;
return tlv->value;
}
bool ring_buf_get_done(void *buf)
{
ring_buf_tlv_t *tlv;
ring_buf_t *ring_buf = (ring_buf_t *)buf;
if (!ring_buf->reading) {
return FALSE;
}
tlv = (ring_buf_tlv_t *)&ring_buf->buf[ring_buf->read];
ring_buf->read = (ring_buf->read + tlv->length + 5) % ring_buf->buf_size;
ring_buf->reading = FALSE;
return TRUE;
}
#ifndef __RING_BUF_H__
#define __RING_BUF_H__
#include "stdint.h"
void* ring_slab_new(void *slab_addr, uint32_t slab_length, size_t item_size);
void ring_slab_del(void *slab);
void* ring_slab_put(void *slab);
bool ring_slab_put_done(void *slab);
void* ring_slab_get(void *slab);
bool ring_slab_get_done(void *slab);
bool ring_slab_empty(void *slab);
#endif
#include "string.h"
#include "ring_slab.h"
typedef struct {
uint32_t write;
uint32_t read;
uint32_t slab_size;
size_t item_size;
bool writing;
bool . reading;
mys_byte_t *slab;
void *slab_addr;
} ring_slab_t;
void* ring_slab_new(void *slab_addr, uint32_t slab_length, size_t item_size)
{
ring_slab_t *ring_slab;
if (0xFFFFFFFFU / item_size < slab_length + 1) {
return NULL;
}
ring_slab = (ring_slab_t *)malloc(sizeof(ring_slab_t));
if (NULL == ring_slab) {
return NULL;
}
ring_slab->item_size = item_size;
/* the last 1 byte is used to distinguish emtpy and full state */
ring_slab->slab_size = (slab_length + 1) * item_size;
ring_slab->slab_addr = slab_addr;
if (NULL != slab_addr) {
ring_slab->slab = slab_addr;
} else {
ring_slab->slab = (mys_byte_t *)malloc(ring_slab->slab_size);
if (NULL == ring_slab->slab) {
free(ring_slab);
return NULL;
}
}
ring_slab->write = 0;
ring_slab->read = 0;
ring_slab->reading = FALSE;
ring_slab->writing = FALSE;
return (void *)ring_slab;
}
void ring_slab_del(void *slab)
{
ring_slab_t *ring_slab = (ring_slab_t *)slab;
free(ring_slab->slab);
if (NULL == ring_slab->slab_addr) {
free(ring_slab);
}
}
bool ring_slab_empty(void *slab)
{
ring_slab_t *ring_slab = (ring_slab_t *)slab;
return (ring_slab->write == ring_slab->read);
}
static bool ring_slab_full(ring_slab_t *ring_slab)
{
return ((ring_slab->write + ring_slab->item_size) % ring_slab->slab_size == ring_slab->read);
}
void* ring_slab_put(void *slab)
{
ring_slab_t *ring_slab = (ring_slab_t *)slab;
if (ring_slab->writing || ring_slab_full(ring_slab)) {
return NULL;
}
ring_slab->writing = TRUE;
return (void *)&ring_slab->slab[ring_slab->write];
}
bool ring_slab_put_done(void *slab)
{
ring_slab_t *ring_slab = (ring_slab_t *)slab;
if (!ring_slab->writing) {
return FALSE;
}
ring_slab->write = (ring_slab->write + ring_slab->item_size) % ring_slab->slab_size;
ring_slab->writing = FALSE;
return TRUE;
}
void* ring_slab_get(void *slab)
{
ring_slab_t *ring_slab = (ring_slab_t *)slab;
if (ring_slab->reading || ring_slab_empty(ring_slab)) {
return NULL;
}
ring_slab->reading = TRUE;
return (void *)&ring_slab->slab[ring_slab->read];
}
bool ring_slab_get_done(void *slab)
{
ring_slab_t *ring_slab = (ring_slab_t *)slab;
if (!ring_slab->reading) {
return FALSE;
}
ring_slab->read = (ring_slab->read + ring_slab->item_size) % ring_slab->slab_size;
ring_slab->reading = FALSE;
return TRUE;
}