mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/tsrb: Make thread-safe
Drop the requirement of having only one writer and one reader, as the name of the ring-buffer does not indicate any limitation on the thread-safety. The two-threads-one-buffer kind of ring buffer can be reintroduced with a different name.
This commit is contained in:
parent
2df92b0d61
commit
0d0b14de29
@ -12,9 +12,6 @@
|
||||
* @brief Thread-safe ringbuffer implementation
|
||||
* @{
|
||||
*
|
||||
* @note This ringbuffer implementation can be used without locking if
|
||||
* there's only one producer and one consumer.
|
||||
*
|
||||
* @attention Buffer size must be a power of two!
|
||||
*
|
||||
* @file
|
||||
@ -30,6 +27,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "irq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -40,8 +39,8 @@ extern "C" {
|
||||
typedef struct tsrb {
|
||||
uint8_t *buf; /**< Buffer to operate on. */
|
||||
unsigned int size; /**< Size of buffer, must be power of 2. */
|
||||
volatile unsigned reads; /**< total number of reads */
|
||||
volatile unsigned writes; /**< total number of writes */
|
||||
unsigned reads; /**< total number of reads */
|
||||
unsigned writes; /**< total number of writes */
|
||||
} tsrb_t;
|
||||
|
||||
/**
|
||||
@ -76,7 +75,10 @@ static inline void tsrb_init(tsrb_t *rb, uint8_t *buffer, unsigned bufsize)
|
||||
*/
|
||||
static inline int tsrb_empty(const tsrb_t *rb)
|
||||
{
|
||||
return (rb->reads == rb->writes);
|
||||
unsigned irq_state = irq_disable();
|
||||
int retval = (rb->reads == rb->writes);
|
||||
irq_restore(irq_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@ -87,7 +89,10 @@ static inline int tsrb_empty(const tsrb_t *rb)
|
||||
*/
|
||||
static inline unsigned int tsrb_avail(const tsrb_t *rb)
|
||||
{
|
||||
return (rb->writes - rb->reads);
|
||||
unsigned irq_state = irq_disable();
|
||||
int retval = (rb->writes - rb->reads);
|
||||
irq_restore(irq_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +103,10 @@ static inline unsigned int tsrb_avail(const tsrb_t *rb)
|
||||
*/
|
||||
static inline int tsrb_full(const tsrb_t *rb)
|
||||
{
|
||||
return (rb->writes - rb->reads) == rb->size;
|
||||
unsigned irq_state = irq_disable();
|
||||
int retval = (rb->writes - rb->reads) == rb->size;
|
||||
irq_restore(irq_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,7 +116,10 @@ static inline int tsrb_full(const tsrb_t *rb)
|
||||
*/
|
||||
static inline unsigned int tsrb_free(const tsrb_t *rb)
|
||||
{
|
||||
return (rb->size - rb->writes + rb->reads);
|
||||
unsigned irq_state = irq_disable();
|
||||
int retval = (rb->size - rb->writes + rb->reads);
|
||||
irq_restore(irq_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,7 @@
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "irq.h"
|
||||
#include "tsrb.h"
|
||||
|
||||
static void _push(tsrb_t *rb, uint8_t c)
|
||||
@ -31,51 +32,59 @@ static uint8_t _pop(tsrb_t *rb)
|
||||
|
||||
int tsrb_get_one(tsrb_t *rb)
|
||||
{
|
||||
int retval = -1;
|
||||
unsigned irq_state = irq_disable();
|
||||
if (!tsrb_empty(rb)) {
|
||||
return _pop(rb);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
retval = _pop(rb);
|
||||
}
|
||||
irq_restore(irq_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int tsrb_get(tsrb_t *rb, uint8_t *dst, size_t n)
|
||||
{
|
||||
size_t tmp = n;
|
||||
unsigned irq_state = irq_disable();
|
||||
while (tmp && !tsrb_empty(rb)) {
|
||||
*dst++ = _pop(rb);
|
||||
tmp--;
|
||||
}
|
||||
irq_restore(irq_state);
|
||||
return (n - tmp);
|
||||
}
|
||||
|
||||
int tsrb_drop(tsrb_t *rb, size_t n)
|
||||
{
|
||||
size_t tmp = n;
|
||||
unsigned irq_state = irq_disable();
|
||||
while (tmp && !tsrb_empty(rb)) {
|
||||
_pop(rb);
|
||||
tmp--;
|
||||
}
|
||||
irq_restore(irq_state);
|
||||
return (n - tmp);
|
||||
}
|
||||
|
||||
int tsrb_add_one(tsrb_t *rb, uint8_t c)
|
||||
{
|
||||
int retval = -1;
|
||||
unsigned irq_state = irq_disable();
|
||||
if (!tsrb_full(rb)) {
|
||||
_push(rb, c);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
retval = 0;
|
||||
}
|
||||
irq_restore(irq_state);
|
||||
return retval;
|
||||
}
|
||||
|
||||
int tsrb_add(tsrb_t *rb, const uint8_t *src, size_t n)
|
||||
{
|
||||
size_t tmp = n;
|
||||
unsigned irq_state = irq_disable();
|
||||
while (tmp && !tsrb_full(rb)) {
|
||||
_push(rb, *src++);
|
||||
tmp--;
|
||||
}
|
||||
irq_restore(irq_state);
|
||||
return (n - tmp);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user