-
Notifications
You must be signed in to change notification settings - Fork 17
/
ring_buffer_fixed_size.h
64 lines (54 loc) · 2.82 KB
/
ring_buffer_fixed_size.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Copyright (c) Konstantin Belyalov. All rights reserved.
// Licensed under the MIT license.
#ifndef __RING_BUFFER_H
#define __RING_BUFFER_H
// Declares ring buffer structure
#define RING_BUFFER_DECLARE(_name, _item, _size) \
struct _name##_ring { \
_item buffer[_size]; \
size_t head; \
size_t tail; \
size_t size; \
uint8_t full; \
}; \
// Defines and initializes ring buffer structure.
// Params:
// - _name: variable name to be created
// - _item: ring buffer item type
// - _size: ring size (items count)
#define RING_BUFFER_DEFINE(_name, _item, _size) \
struct _name##_ring _name##_ring_def = {{0}, 0, 0, _size}; \
struct _name##_ring *_name = &_name##_ring_def;
// Pushes "_item" into ring buffer (does memcpy)
#define RING_BUFFER_PUSH_COPY(_name, _item) \
({ \
(_name)->head = ((_name)->head + 1) % (_name)->size; \
memcpy(&(_name)->buffer[(_name)->head], _item, sizeof(*_item)); \
if (!(_name)->full) (_name)->full = (_name)->head == (_name)->tail; \
})
// "Pushes" item (basically does pointer advance) and returns it.
// You must copy data yourself
#define RING_BUFFER_PUSH(_name) \
({ \
(_name)->head = ((_name)->head + 1) % (_name)->size; \
if (!(_name)->full) (_name)->full = ((_name)->head == (_name)->tail); \
&(_name)->buffer[(_name)->head]; \
})
// Returns pointer to next element. Does NOT advance pointer
// You must copy data yourself
#define RING_BUFFER_GET_NEXT(_name) (&(_name)->buffer[(((_name)->head + 1) % (_name)->size)])
// POPs item from ring buffer (NOTE: it does not check for empty queue)
// and returns pointer to the item
#define RING_BUFFER_POP(_name) \
({ \
(_name)->tail = ((_name)->tail + 1) % (_name)->size; \
(_name)->full = 0; \
&(_name)->buffer[(_name)->tail]; \
})
// Returns pointer to current tail
#define RING_BUFFER_TAIL(_name) (&(_name)->buffer[((_name)->tail + 1) % (_name)->size])
// Returns True if buffer is full
#define RING_BUFFER_FULL(_name) ((_name)->full)
// Returns True if buffer is empty
#define RING_BUFFER_EMPTY(_name) (!(_name)->full && (_name)->head == (_name)->tail)
#endif