mirror of
https://github.com/markqvist/OpenModem.git
synced 2024-10-01 03:15:46 -04:00
86 lines
1.7 KiB
C
86 lines
1.7 KiB
C
#ifndef UTIL_FIFO_H
|
|
#define UTIL_FIFO_H
|
|
|
|
#include <stddef.h>
|
|
#include <util/atomic.h>
|
|
|
|
typedef struct FIFOBuffer
|
|
{
|
|
unsigned char *begin;
|
|
unsigned char *end;
|
|
unsigned char * volatile head;
|
|
unsigned char * volatile tail;
|
|
} FIFOBuffer;
|
|
|
|
inline bool fifo_isempty(const FIFOBuffer *f) {
|
|
return f->head == f->tail;
|
|
}
|
|
|
|
inline bool fifo_isfull(const FIFOBuffer *f) {
|
|
return ((f->head == f->begin) && (f->tail == f->end)) || (f->tail == f->head - 1);
|
|
}
|
|
|
|
inline void fifo_push(FIFOBuffer *f, unsigned char c) {
|
|
*(f->tail) = c;
|
|
|
|
if (f->tail == f->end) {
|
|
f->tail = f->begin;
|
|
} else {
|
|
f->tail++;
|
|
}
|
|
}
|
|
|
|
inline unsigned char fifo_pop(FIFOBuffer *f) {
|
|
if(f->head == f->end) {
|
|
f->head = f->begin;
|
|
return *(f->end);
|
|
} else {
|
|
return *(f->head++);
|
|
}
|
|
}
|
|
|
|
inline void fifo_flush(FIFOBuffer *f) {
|
|
f->head = f->tail;
|
|
}
|
|
|
|
static inline bool fifo_isempty_locked(const FIFOBuffer *f) {
|
|
bool result;
|
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
|
result = fifo_isempty(f);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static inline bool fifo_isfull_locked(const FIFOBuffer *f) {
|
|
bool result;
|
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
|
result = fifo_isfull(f);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static inline void fifo_push_locked(FIFOBuffer *f, unsigned char c) {
|
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
|
fifo_push(f, c);
|
|
}
|
|
}
|
|
|
|
static inline unsigned char fifo_pop_locked(FIFOBuffer *f) {
|
|
unsigned char c;
|
|
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
|
|
c = fifo_pop(f);
|
|
}
|
|
return c;
|
|
}
|
|
|
|
inline void fifo_init(FIFOBuffer *f, unsigned char *buffer, size_t size) {
|
|
f->head = f->tail = f->begin = buffer;
|
|
f->end = buffer + size -1;
|
|
}
|
|
|
|
inline size_t fifo_len(FIFOBuffer *f) {
|
|
return f->end - f->begin;
|
|
}
|
|
|
|
#endif
|