1. 优化HRingBuffer, 更改为kfifo设计方法

This commit is contained in:
coffee 2026-05-22 00:26:36 +08:00
parent df494faf2d
commit fa25457c1e
3 changed files with 92 additions and 77 deletions

View File

@ -2,6 +2,11 @@
* : 2025-04-13
* : coffee
* :
*
* :
* start end ,
* = (end - start) == len, = end == start
* ( 2 )
*/
#ifndef _H_RING_BUFFER_H_
@ -16,9 +21,9 @@ enum eRingBufferFlag {
kHRingBufferFlag16 = 0x02, // 数据16位
kHRingBufferFlag32 = 0x04, // 数据32位
kHRingBufferPow2 = 0x08, // 容量为 2 的幂 (可用掩码代替取模)
kHRingBufferFlagAllMask = 0x07, // 数据掩码
kHRingBufferFull = 0x40, // 环转缓冲区满
kHRingBufferNeedInit = 0x80, // 需要初始化
};
@ -45,9 +50,9 @@ typedef uint8_t HRingBufferLenType;
typedef struct __attribute__ ((__packed__)) _HRingBufferBase {
volatile uint8_t flag;
HRingBufferLenType len;
HRingBufferLenType start;
HRingBufferLenType end;
HRingBufferLenType len; // 容量 (任意值)
HRingBufferLenType start; // 只增不减的读指针
HRingBufferLenType end; // 只增不减的写指针
} _HRingBufferBase;

View File

@ -132,6 +132,7 @@ void *HMemCalloc(size_t num, size_t size) {
}
if (num > (SIZE_MAX / size)) {
LogD("num[%d] overflow", num);
return NULL;
}
@ -150,6 +151,7 @@ void *HMemRealloc(void *ptr, size_t size) {
}
if (size > HMEM_SIZE_MAX) {
LogD("size[%d] overflow", size);
return NULL;
}
@ -213,6 +215,7 @@ uint8_t HMemFree(void *ptr) {
HMemHeader *header = GetHeader(ptr);
if (!IsValidHeader(header)) {
LogD("invalid addr[0x%08x]", ptr);
return 0;
}
@ -241,6 +244,8 @@ void *HMemAddRef(void *ptr, size_t size) {
if (IsValidHeader(header)) {
if (header->refCount < HMEM_REFCOUNT_MAX) {
++header->refCount;
} else {
LogD("ref count[%d][%d] overflow", header->refCount, HMEM_REFCOUNT_MAX);
}
return ptr;
}

View File

@ -1,5 +1,3 @@
#include <HRingBuffer.h>
#include <string.h>
@ -14,6 +12,19 @@
#endif
// 已用长度: 强转回 HRingBufferLenType 避免整型提升 (uint16_t→int) 导致负值
#define HRING_USED(end, start) ((HRingBufferLenType)((end) - (start)))
// 数组下标: 2 次幂走掩码, 否则取模
static inline HRingBufferLenType HRingIndex(HRingBufferLenType ptr, HRingBufferLenType len, uint8_t flag) {
if (flag & kHRingBufferPow2) {
return ptr & (len - 1);
}
return ptr % len;
}
static inline void InitRingBuffer(HRingBufferType *ringBuffer) {
if (ringBuffer == NULL) {
LogD("RingBuffer is NULL");
@ -32,6 +43,11 @@ static inline void InitRingBuffer(HRingBufferType *ringBuffer) {
base->start = _HRING_BUFFER_INIT_SIZE_INIT(len);
len = (uint8_t *)&base->end;
base->end = _HRING_BUFFER_INIT_SIZE_INIT(len);
// 检测容量是否为 2 的幂
if (base->len != 0 && (base->len & (base->len - 1)) == 0) {
base->flag |= kHRingBufferPow2;
}
}
static inline uint8_t GetRingBufferType(const HRingBufferType *ringBuffer) {
@ -93,33 +109,16 @@ static inline void SetRingBufferData(HRingBufferType *ringBuffer, HRingBufferLen
}
}
static inline uint8_t IsRingBufferFull(const HRingBufferType *ringBuffer) {
if (ringBuffer == NULL) {
return 1;
}
InitRingBuffer((HRingBufferType *)ringBuffer);
const _HRingBufferBase *base = (const _HRingBufferBase *)ringBuffer;
return !!(base->flag & kHRingBufferFull);
}
static inline void SetRingBufferFull(HRingBufferType *ringBuffer, uint8_t full) {
InitRingBuffer((HRingBufferType *)ringBuffer);
_HRingBufferBase *base = (_HRingBufferBase *)ringBuffer;
const uint8_t f = -(uint8_t)(!!full);
base->flag = (base->flag & ~kHRingBufferFull) | (f & kHRingBufferFull);
}
static void AdjustReadPos(HRingBufferType *ringBuffer, HRingBufferLenType pos) {
const uint8_t isFull = IsRingBufferFull(ringBuffer);
_HRingBufferBase *base = (_HRingBufferBase *)ringBuffer;
base->start += pos;
base->start -= (base->start >= base->len) * base->len;
if (isFull) {
SetRingBufferFull(ringBuffer, 0);
}
}
/* ==========================================================================
* kfifo
*
* :
* - start/end , wrap
* - = end - start ()
* - = (end - start) == len, = end == start
* - : 2 & (len-1), %
* ========================================================================== */
HRingBufferLenType HRingbufferInit8(void *buffer, HRingBufferLenType size)
{
const int len = size - sizeof(_HRingBufferBase);
@ -129,10 +128,16 @@ HRingBufferLenType HRingbufferInit8(void *buffer, HRingBufferLenType size)
const uint8_t init[] = _HRING_BUFFER_INIT8(len);
memcpy(buffer, init, sizeof(init));
// 运行时检测 2 次幂并标记
if (len != 0 && ((HRingBufferLenType)len & ((HRingBufferLenType)len - 1)) == 0) {
((_HRingBufferBase *)buffer)->flag |= kHRingBufferPow2;
}
return HRingBufferGetLen((HRingBufferType *)buffer);
}
// 添加数据到环形缓冲区, 成功返回1, 失败返回0
uint8_t HRingBufferAddData(HRingBufferType* buffer, HRingBufferDataType data) {
if (buffer == NULL) {
return 0;
@ -145,68 +150,66 @@ uint8_t HRingBufferAddData(HRingBufferType* buffer, HRingBufferDataType data) {
return 0;
}
// 判断缓冲区是否已满
if (IsRingBufferFull(buffer)) {
LogD("buffer is full, len[%d], start[%d], end[%d]", base->len, base->start, base->end);
if (HRING_USED(base->end, base->start) == base->len) {
LogD("buffer is full");
return 0;
}
SetRingBufferData(buffer, base->end, data);
SetRingBufferData(buffer, HRingIndex(base->end, base->len, base->flag), data);
++base->end;
base->end -= (base->end >= base->len) * base->len;
if (base->end == base->start) {
SetRingBufferFull(buffer, 1);
}
return 1;
}
// 添加数据到环形缓冲区, 当环形缓冲区满时, 会覆盖旧数据, 成功返回1, 失败返回0
uint8_t HRingBufferAddDataOver(HRingBufferType* buffer, HRingBufferDataType data) {
if (IsRingBufferFull(buffer)) {
_HRingBufferBase *base = (_HRingBufferBase *)buffer;
++base->start;
base->start -= (base->start >= base->len) * base->len;
SetRingBufferFull(buffer, 0);
if (buffer == NULL) {
return 0;
}
return HRingBufferAddData(buffer, data);
_HRingBufferBase *base = (_HRingBufferBase *)buffer;
InitRingBuffer(buffer);
if (base->len == 0) {
return 0;
}
if (HRING_USED(base->end, base->start) == base->len) {
++base->start;
}
SetRingBufferData(buffer, HRingIndex(base->end, base->len, base->flag), data);
++base->end;
return 1;
}
// 获取指定位置的环形缓冲区数据, 失败返回 HRING_BUFFER_ERROR
HRingBufferDataType HRingBufferGetData(HRingBufferType* buffer, HRingBufferLenType index) {
if (buffer == NULL) {
return HRING_BUFFER_ERROR;
}
if (HRingBufferGetUseLen(buffer) <= index) {
LogD("error index[%d], len[%d]", index, HRingBufferGetLen(buffer));
LogD("error index");
return HRING_BUFFER_ERROR;
}
_HRingBufferBase *base = (_HRingBufferBase *)buffer;
return GetRingBufferData(buffer, (base->start + index) % base->len);
return GetRingBufferData(buffer, HRingIndex(base->start + index, base->len, base->flag));
}
// 获取环形缓冲区数据, 失败返回 HRING_BUFFER_ERROR
HRingBufferDataType HRingBufferPopData(HRingBufferType* buffer) {
if (HRingBufferGetUseLen(buffer) == 0) {
return HRING_BUFFER_ERROR;
}
_HRingBufferBase *base = (_HRingBufferBase *)buffer;
HRingBufferDataType data = GetRingBufferData(buffer, base->start);
const HRingBufferDataType data = GetRingBufferData(buffer, HRingIndex(base->start, base->len, base->flag));
++base->start;
base->start -= (base->start >= base->len) * base->len;
if (IsRingBufferFull(buffer)) {
SetRingBufferFull(buffer, 0);
}
return data;
}
// 获取环状缓冲区数据, 返回获取的数据长度
HRingBufferLenType HRingBufferGetByteDatas(HRingBufferType* buffer, uint8_t *data, HRingBufferLenType len)
{
const HRingBufferLenType useLen = HRingBufferGetUseLen(buffer);
@ -229,7 +232,9 @@ HRingBufferLenType HRingBufferGetByteDatas(HRingBufferType* buffer, uint8_t *dat
return 0;
}
const HRingBufferLenType startPos = base->start;
// 当前读位置数组下标
const HRingBufferLenType startPos = HRingIndex(base->start, base->len, base->flag);
// 第一段: 从 startPos 到缓冲区末尾
HRingBufferLenType firstCopyElems = base->len - startPos;
if (firstCopyElems > copyElems) {
firstCopyElems = copyElems;
@ -242,11 +247,11 @@ HRingBufferLenType HRingBufferGetByteDatas(HRingBufferType* buffer, uint8_t *dat
memcpy(data + firstCopyLen, GetRingByteData(buffer, 0), copyLen - firstCopyLen);
}
AdjustReadPos(buffer, copyElems);
base->start += copyElems;
return copyLen;
}
// 获取环形缓冲区数据长度
HRingBufferLenType HRingBufferGetUseLen(HRingBufferType* buffer) {
if (buffer == NULL) {
return 0;
@ -254,22 +259,15 @@ HRingBufferLenType HRingBufferGetUseLen(HRingBufferType* buffer) {
_HRingBufferBase *base = (_HRingBufferBase *)buffer;
InitRingBuffer(buffer);
if (base->end >= base->start) {
if (IsRingBufferFull(buffer)) {
return base->len;
}
return base->end - base->start;
}
return base->len - base->start + base->end;
return HRING_USED(base->end, base->start);
}
// 获取环形缓冲区数据字节长度
HRingBufferLenType HRingBufferGetUseByteLen(HRingBufferType* buffer) {
return HRingBufferGetUseLen(buffer) * GetRingBufferTypeSize(buffer);
}
HRingBufferLenType HRingBufferGetLen(HRingBufferType* buffer) {
if (buffer == NULL) {
return 0;
@ -280,7 +278,7 @@ HRingBufferLenType HRingBufferGetLen(HRingBufferType* buffer) {
return base->len;
}
// 清空环形缓冲区
void HRingBufferClear(HRingBufferType* buffer) {
if (buffer == NULL) {
return ;
@ -288,20 +286,27 @@ void HRingBufferClear(HRingBufferType* buffer) {
_HRingBufferBase *base = (_HRingBufferBase *)buffer;
InitRingBuffer(buffer);
SetRingBufferFull(buffer, 0);
base->start = 0;
base->end = 0;
}
// 判断环形缓冲区是否为空
uint8_t HRingBufferEmpty(HRingBufferType* buffer) {
return HRingBufferGetUseLen(buffer) == 0;
}
uint8_t HRingBufferFull(HRingBufferType* buffer) {
return IsRingBufferFull(buffer);
if (buffer == NULL) {
return 1;
}
InitRingBuffer(buffer);
const _HRingBufferBase *base = (const _HRingBufferBase *)buffer;
return HRING_USED(base->end, base->start) == base->len;
}
uint8_t HRingBufferExist(HRingBufferType* buffer, HRingBufferDataType data) {
const HRingBufferLenType len = HRingBufferGetUseLen(buffer);
for (HRingBufferLenType i = 0; i < len; ++i) {