|
|
@ -78,7 +78,6 @@ void rd_RingbufferInit(rd_ringbuf_t *rb, char *pool, int size) |
|
|
int rd_RingbufferSpaceLen(rd_ringbuf_t *rb) |
|
|
int rd_RingbufferSpaceLen(rd_ringbuf_t *rb) |
|
|
{ |
|
|
{ |
|
|
if (!rb) return -1; |
|
|
if (!rb) return -1; |
|
|
int iRet = 0; |
|
|
|
|
|
|
|
|
|
|
|
unsigned short wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_ACQUIRE); |
|
|
unsigned short wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_ACQUIRE); |
|
|
unsigned short ri = ATOMIC_LOAD(&rb->m_sReadIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
unsigned short ri = ATOMIC_LOAD(&rb->m_sReadIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
@ -86,19 +85,9 @@ int rd_RingbufferSpaceLen(rd_ringbuf_t *rb) |
|
|
unsigned char rb_m = ATOMIC_LOAD(&rb->m_bReadMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
unsigned char rb_m = ATOMIC_LOAD(&rb->m_bReadMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
|
|
|
|
|
|
if (wb == rb_m) { |
|
|
if (wb == rb_m) { |
|
|
iRet = rb->m_iBufsize - (wi - ri); |
|
|
return rb->m_iBufsize - (wi - ri); |
|
|
} else { |
|
|
} else { |
|
|
iRet = ri - wi; |
|
|
return ri - wi; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (iRet >= 0) |
|
|
|
|
|
{ |
|
|
|
|
|
return iRet; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
log_e("wb = %d, rb_m = %d, wi = %d, ri = %d", wb, rb_m, wi, ri); |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -131,27 +120,46 @@ int rd_RingbufferPut(rd_ringbuf_t *rb, const char *ptr, int length) |
|
|
{ |
|
|
{ |
|
|
if (!rb || !ptr || length <= 0) return RD_INVALUE; |
|
|
if (!rb || !ptr || length <= 0) return RD_INVALUE; |
|
|
|
|
|
|
|
|
int space = rd_RingbufferSpaceLen(rb); |
|
|
unsigned short wi, ri; |
|
|
if (space == 0) return 0; |
|
|
unsigned char wb, rb_m; |
|
|
if (space < length) length = space; |
|
|
int space, tail; |
|
|
|
|
|
unsigned int primask; |
|
|
|
|
|
|
|
|
unsigned short wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
__asm__ volatile ("mrs %0, primask" : "=r"(primask)); |
|
|
unsigned char wb = ATOMIC_LOAD(&rb->m_bWriteMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
__asm__ volatile ("cpsid i" ::: "memory"); |
|
|
|
|
|
|
|
|
/* 写入不跨越尾部 */ |
|
|
wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
if (rb->m_iBufsize - wi > length) { |
|
|
ri = ATOMIC_LOAD(&rb->m_sReadIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
|
|
|
wb = ATOMIC_LOAD(&rb->m_bWriteMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
|
|
|
rb_m = ATOMIC_LOAD(&rb->m_bReadMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
|
|
|
|
|
|
|
|
|
if (wb == rb_m) { |
|
|
|
|
|
space = rb->m_iBufsize - (int)(unsigned short)(wi - ri); |
|
|
|
|
|
} else { |
|
|
|
|
|
space = (int)(unsigned short)(ri - wi); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (space <= 0) { |
|
|
|
|
|
__asm__ volatile ("msr primask, %0" :: "r"(primask) : "memory"); |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
if (space < length) length = space; |
|
|
|
|
|
|
|
|
|
|
|
tail = rb->m_iBufsize - wi; |
|
|
|
|
|
if (tail > length) { |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[wi], ptr, length); |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[wi], ptr, length); |
|
|
wi += length; |
|
|
wi += length; |
|
|
} else { |
|
|
} else { |
|
|
int first = rb->m_iBufsize - wi; |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[wi], ptr, tail); |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[wi], ptr, first); |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[0], ptr + tail, length - tail); |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[0], ptr + first, length - first); |
|
|
wb ^= 1; |
|
|
wb ^= 1; /* 翻转镜像位 */ |
|
|
wi = length - tail; |
|
|
wi = length - first; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
ATOMIC_STORE(&rb->m_sWriteIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_sWriteIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_bWriteMirror, wb, unsigned char, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_bWriteMirror, wb, unsigned char, ATOMIC_ORDER_RELEASE); |
|
|
|
|
|
|
|
|
|
|
|
__asm__ volatile ("msr primask, %0" :: "r"(primask) : "memory"); |
|
|
return length; |
|
|
return length; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -168,6 +176,10 @@ int rd_RingbufferPutForce(rd_ringbuf_t *rb, const char *ptr, int length) |
|
|
{ |
|
|
{ |
|
|
if (!rb || !ptr || length <= 0) return RD_INVALUE; |
|
|
if (!rb || !ptr || length <= 0) return RD_INVALUE; |
|
|
|
|
|
|
|
|
|
|
|
unsigned int primask; |
|
|
|
|
|
__asm__ volatile ("mrs %0, primask" : "=r"(primask)); |
|
|
|
|
|
__asm__ volatile ("cpsid i" ::: "memory"); |
|
|
|
|
|
|
|
|
int space = rd_RingbufferSpaceLen(rb); |
|
|
int space = rd_RingbufferSpaceLen(rb); |
|
|
if (length > rb->m_iBufsize) { |
|
|
if (length > rb->m_iBufsize) { |
|
|
ptr += length - rb->m_iBufsize; |
|
|
ptr += length - rb->m_iBufsize; |
|
|
@ -177,18 +189,18 @@ int rd_RingbufferPutForce(rd_ringbuf_t *rb, const char *ptr, int length) |
|
|
unsigned short wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
unsigned short wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
unsigned char wb = ATOMIC_LOAD(&rb->m_bWriteMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
unsigned char wb = ATOMIC_LOAD(&rb->m_bWriteMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
|
|
|
|
|
|
if (rb->m_iBufsize - wi > length) { |
|
|
int tail = rb->m_iBufsize - wi; |
|
|
|
|
|
if (tail > length) { |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[wi], ptr, length); |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[wi], ptr, length); |
|
|
wi += length; |
|
|
wi += length; |
|
|
if (length > space) { |
|
|
if (length > space) { |
|
|
ATOMIC_STORE(&rb->m_sReadIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_sReadIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
int first = rb->m_iBufsize - wi; |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[wi], ptr, tail); |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[wi], ptr, first); |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[0], ptr + tail, length - tail); |
|
|
RD_MEMCPY(&rb->m_pcBufPtr[0], ptr + first, length - first); |
|
|
|
|
|
wb ^= 1; |
|
|
wb ^= 1; |
|
|
wi = length - first; |
|
|
wi = length - tail; |
|
|
if (length > space) { |
|
|
if (length > space) { |
|
|
unsigned short ri = ATOMIC_LOAD(&rb->m_sReadIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
unsigned short ri = ATOMIC_LOAD(&rb->m_sReadIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
if (wi <= ri) wb ^= 1; |
|
|
if (wi <= ri) wb ^= 1; |
|
|
@ -198,6 +210,8 @@ int rd_RingbufferPutForce(rd_ringbuf_t *rb, const char *ptr, int length) |
|
|
|
|
|
|
|
|
ATOMIC_STORE(&rb->m_sWriteIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_sWriteIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_bWriteMirror, wb, unsigned char, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_bWriteMirror, wb, unsigned char, ATOMIC_ORDER_RELEASE); |
|
|
|
|
|
|
|
|
|
|
|
__asm__ volatile ("msr primask, %0" :: "r"(primask) : "memory"); |
|
|
return length; |
|
|
return length; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -299,7 +313,15 @@ int rd_RingbufferPeekLinear(rd_ringbuf_t *rb, char *out, int length) |
|
|
int rd_RingbufferPutchar(rd_ringbuf_t *rb, const char ch) |
|
|
int rd_RingbufferPutchar(rd_ringbuf_t *rb, const char ch) |
|
|
{ |
|
|
{ |
|
|
if (!rb) return RD_INVALUE; |
|
|
if (!rb) return RD_INVALUE; |
|
|
if (!rd_RingbufferSpaceLen(rb)) return 0; |
|
|
|
|
|
|
|
|
unsigned int primask; |
|
|
|
|
|
__asm__ volatile ("mrs %0, primask" : "=r"(primask)); |
|
|
|
|
|
__asm__ volatile ("cpsid i" ::: "memory"); |
|
|
|
|
|
|
|
|
|
|
|
if (rd_RingbufferSpaceLen(rb) == 0) { |
|
|
|
|
|
__asm__ volatile ("msr primask, %0" :: "r"(primask) : "memory"); |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
unsigned short wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
unsigned short wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
unsigned char wb = ATOMIC_LOAD(&rb->m_bWriteMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
unsigned char wb = ATOMIC_LOAD(&rb->m_bWriteMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
@ -314,6 +336,8 @@ int rd_RingbufferPutchar(rd_ringbuf_t *rb, const char ch) |
|
|
|
|
|
|
|
|
ATOMIC_STORE(&rb->m_sWriteIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_sWriteIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_bWriteMirror, wb, unsigned char, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_bWriteMirror, wb, unsigned char, ATOMIC_ORDER_RELEASE); |
|
|
|
|
|
|
|
|
|
|
|
__asm__ volatile ("msr primask, %0" :: "r"(primask) : "memory"); |
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -329,6 +353,10 @@ int rd_RingbufferPutcharForce(rd_ringbuf_t *rb, const char ch) |
|
|
{ |
|
|
{ |
|
|
if (!rb) return RD_INVALUE; |
|
|
if (!rb) return RD_INVALUE; |
|
|
|
|
|
|
|
|
|
|
|
unsigned int primask; |
|
|
|
|
|
__asm__ volatile ("mrs %0, primask" : "=r"(primask)); |
|
|
|
|
|
__asm__ volatile ("cpsid i" ::: "memory"); |
|
|
|
|
|
|
|
|
enum ERingBufState old_state = rd_RingbufferStatus(rb); |
|
|
enum ERingBufState old_state = rd_RingbufferStatus(rb); |
|
|
unsigned short wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
unsigned short wi = ATOMIC_LOAD(&rb->m_sWriteIndex, unsigned short, ATOMIC_ORDER_RELAXED); |
|
|
unsigned char wb = ATOMIC_LOAD(&rb->m_bWriteMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
unsigned char wb = ATOMIC_LOAD(&rb->m_bWriteMirror, unsigned char, ATOMIC_ORDER_RELAXED); |
|
|
@ -352,6 +380,8 @@ int rd_RingbufferPutcharForce(rd_ringbuf_t *rb, const char ch) |
|
|
|
|
|
|
|
|
ATOMIC_STORE(&rb->m_sWriteIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_sWriteIndex, wi, unsigned short, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_bWriteMirror, wb, unsigned char, ATOMIC_ORDER_RELEASE); |
|
|
ATOMIC_STORE(&rb->m_bWriteMirror, wb, unsigned char, ATOMIC_ORDER_RELEASE); |
|
|
|
|
|
|
|
|
|
|
|
__asm__ volatile ("msr primask, %0" :: "r"(primask) : "memory"); |
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|