]> git.tdb.fi Git - model-railway-devices.git/blob - common/ringbuffer.h
Add ring buffer utilities
[model-railway-devices.git] / common / ringbuffer.h
1 #ifndef RINGBUFFER_H_
2 #define RINGBUFFER_H_
3
4 #define RINGBUFFER(name, size) uint8_t name[(size)+4] = { size, 0, 0, 0 }
5
6 static inline uint8_t ringbuffer_fill(const uint8_t *buffer)
7 {
8         return buffer[1];
9 }
10
11 static inline uint8_t ringbuffer_space(const uint8_t *buffer)
12 {
13         return buffer[0]-buffer[1];
14 }
15
16 static inline void ringbuffer_push(uint8_t *buffer, uint8_t value)
17 {
18         const uint8_t size = buffer[0];
19         uint8_t head = buffer[2];
20         buffer[4+head++] = value;
21         if(head>=size)
22                 head -= size;
23         buffer[2] = head;
24         ++buffer[1];
25 }
26
27 static inline void ringbuffer_blocking_push(uint8_t *buffer, uint8_t value)
28 {
29         const volatile uint8_t *fill = buffer+1;
30         while(*fill>=buffer[0]) ;
31         ringbuffer_push(buffer, value);
32 }
33
34 static inline uint8_t ringbuffer_pop(uint8_t *buffer)
35 {
36         const uint8_t size = buffer[0];
37         uint8_t tail = buffer[3];
38         uint8_t value = buffer[4+tail++];
39         if(tail>=size)
40                 tail -= size;
41         buffer[3] = tail;
42         --buffer[1];
43         return value;
44 }
45
46 static inline uint8_t rinbuffer_blocking_pop(uint8_t *buffer)
47 {
48         const volatile uint8_t *fill = buffer+1;
49         while(*fill==0) ;
50         return ringbuffer_pop(buffer);
51 }
52
53 #endif