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