ringbuff 代码实现

C代码

#include "san_rb.h"

#define min(a, b) ((a) < (b) ? (a) : (b))
static inline void ring_buff_lock(struct ring_buff* buff)
{
    while (buff->lock);
    buff->lock = 1;
}

static inline void ring_buff_unlock(struct ring_buff* buff)
{
    buff->lock = 0;
}

static inline unsigned int ring_buff_len(struct ring_buff* buff)
{
    return buff->in - buff->out;
}

static bool ring_buff_is_empty(struct ring_buff* buff)
{
    return (buff->in == buff->out);
}

static bool ring_buff_is_full(struct ring_buff* buff)
{
    ring_buff_lock(buff);
    unsigned int l = ring_buff_len(buff);
    ring_buff_unlock(buff);

    return l == (buff->mask + 1) ? true : false;
}

static inline unsigned int ring_buff_unused(struct ring_buff* buff)
{
    return (buff->mask + 1) - (buff->in - buff->out);
}

static int ring_buff_init(struct ring_buff* buff, void* buffer, unsigned int size, size_t esize)
{
    size /= esize;

    buff->in    = 0;
    buff->out   = 0;
    buff->lock  = 0;
    buff->esize = esize;
    buff->data  = buffer;

    if (size < 2)
    {
        buff->mask = 0;
        return -1;
    }

    buff->mask = size - 1;
    return 0;
}
static void ring_buff_copy_in(struct ring_buff* buff, const void* src, unsigned int len, unsigned int off)
{
    unsigned int size  = buff->mask + 1;
    unsigned int esize = buff->esize;
    unsigned int l;

    off &= buff->mask;
    if (esize != 1)
    {
        off *= esize;
        size *= esize;
        len *= esize;
    }
    l = min(len, size - off);

    memcpy(buff->data + off, src, l);
    memcpy(buff->data, src + l, len - l);
}

static unsigned int ring_buff_write(struct ring_buff* buff, const void* buf, unsigned int len)
{
    unsigned int l;

    ring_buff_lock(buff);
    l = ring_buff_unused(buff);
    if (len > l)
        len = l;

    if (!len)
    {
        ring_buff_unlock(buff);
        return 0;
    }

    ring_buff_copy_in(buff, buf, len, buff->in);
    buff->in += len;
    ring_buff_unlock(buff);

    return len;
}

static void ring_buff_copy_out(struct ring_buff* buff, void* dst, unsigned int len, unsigned int off)
{
    unsigned int size  = buff->mask + 1;
    unsigned int esize = buff->esize;
    unsigned int l;

    off &= buff->mask;
    if (esize != 1)
    {
        off *= esize;
        size *= esize;
        len *= esize;
    }
    l = min(len, size - off);

    memcpy(dst, buff->data + off, l);
    memcpy(dst + l, buff->data, len - l);
}
static unsigned int ring_buff_out_peek(struct ring_buff* buff, void* buf, unsigned int len)
{
    unsigned int l;

    l = ring_buff_len(buff);
    if (!l)
        return 0;

    if (len > l)
        len = l;

    ring_buff_copy_out(buff, buf, len, buff->out);
    return len;
}

static unsigned int ring_buff_read(struct ring_buff* buff, void* buf, unsigned int len)
{
    ring_buff_lock(buff);
    len = ring_buff_out_peek(buff, buf, len);
    buff->out += len;
    ring_buff_unlock(buff);

    return len;
}

头文件


#ifndef __ring_buff_H__
#define __ring_buff_H__

struct ring_buff
{
    volatile unsigned int in;
    volatile unsigned int out;
    volatile unsigned int mask;
    volatile unsigned int esize;
    volatile unsigned int lock;
    void*                 data;
};
typedef struct ring_buff RingBuff;

#endif

C++代码实现

#include "san_rbuff.h"

#define min(a, b) ((a) < (b) ? (a) : (b))

using namespace std;

RingBuff::RingBuff(uint32_t ele_num, uint32_t ele_size)
    :esize(ele_size)
    ,mask(ele_num -1)
    ,in(0)
    ,out(0)
{
    rbuff = malloc(ele_num*ele_size);
    assert(rbuff != NULL);
    memset(rbuff, 0x0, ele_num*ele_size);
}

RingBuff::~RingBuff()
{
    if(rbuff)
        free(rbuff);
}

uint32_t RingBuff::ring_buff_used_len()
{
    return (in - out);
}

uint32_t RingBuff::ring_buff_unused_len()
{
    return (mask + 1) - (in - out);
}

uint32_t RingBuff::ring_buff_out_peek(void* buf, uint32_t len)
{
    uint32_t l;

    l = ring_buff_used_len();
    if (!l)
        return 0;

    if (len > l)
        len = l;

    ring_buff_copy_out(buf, len, out);
    return len;
}

uint32_t RingBuff::ring_buff_read(void* buf, uint32_t len)
{
    std::lock_guard<std::mutex> l(m_Mutex);
    len = ring_buff_out_peek(buf, len);
    out += len;
    return len;
}
uint32_t RingBuff::ring_buff_write(const void* buf, uint32_t len)
{
    uint32_t l;

    std::lock_guard<std::mutex> lock(m_Mutex);
    l = ring_buff_unused_len();
    if (len > l)
        len = l;

    if (!len)
        return 0;

    ring_buff_copy_in(buf, len, in);
    in += len;
    return len;
}

void RingBuff::ring_buff_copy_in(const void* src, uint32_t len, uint32_t off)
{
    uint32_t size  = mask + 1;
    uint32_t l;

    off &= mask;
    if (esize != 1)
    {
        off *= esize;
        size *= esize;
        len *= esize;
    }
    l = min(len, size - off);
    memcpy(rbuff + off, src, l);
    memcpy(rbuff, src + l, len - l);
}
void RingBuff::ring_buff_copy_out(void* dst, uint32_t len, uint32_t off)
{
    uint32_t size  = mask + 1;
    uint32_t l;

    off &= mask;
    if (esize != 1)
    {
        off *= esize;
        size *= esize;
        len *= esize;
    }
    l = min(len, size - off);
    memcpy(dst, rbuff + off, l);
    memcpy(dst + l, rbuff, len - l);
}

bool RingBuff::ring_buff_is_empty()
{
    std::lock_guard<std::mutex> lock(m_Mutex);
    return (in == out);
}

bool RingBuff::ring_buff_is_full()
{
    std::lock_guard<std::mutex> lock(m_Mutex);
    uint32_t l = ring_buff_used_len();
    return (l == (mask + 1) ? true : false);
}

头文件

#ifndef __RingBuff_H__
#define __RingBuff_H__
#include <mutex>
#include <iostream>
#include <cstring>
#include <cassert>
#include <stdio.h>
#include <stdlib.h>

class RingBuff
{
public:
    RingBuff(uint32_t ele_num, uint32_t ele_size);
    ~RingBuff();

    bool ring_buff_is_empty();
    bool ring_buff_is_full();
    uint32_t ring_buff_read(void* buf, uint32_t len);
    uint32_t ring_buff_write(const void* buf, uint32_t len);

private:
    uint32_t ring_buff_used_len();
    uint32_t ring_buff_unused_len();
    uint32_t ring_buff_out_peek(void* buf, uint32_t len);
    void ring_buff_copy_out(void* dst, uint32_t len, uint32_t off);
    void ring_buff_copy_in(const void* src, uint32_t len, uint32_t off);

private:
    uint32_t in;
    uint32_t out;
    uint32_t esize;
    uint32_t mask;
    void*    rbuff;
    std::mutex m_Mutex;
};

#endif

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值