ring buf

#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;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值