utils
utilities in C for microcontrollers
queue
queue.h
Go to the documentation of this file.
1
6
#ifndef QUEUE_H
7
#define QUEUE_H
8
9
#include <stdlib.h>
10
#include <stdint.h>
11
12
/*
13
A very simple circular buffer.
14
15
Example:
16
QUEUE(test, int, count)
17
18
Creates:
19
struct queue_test {...};
20
static inline void queue_test_init(struct queue_test *) {...}
21
static inline int queue_test_push(struct queue_test *, int *) {...}
22
static inline int queue_test_pop(struct queue_test *, int *) {...}
23
24
API:
25
queue_*_init initializes a queue
26
queue_*_push pushes an item onto the queue, returns 0 if successful, not 0 if fail
27
queue_*_pop pops an item from the queue, returns 0 if successful, not 0 if fail
28
queue_*_foreach takes a function pointer and pointer to some context and for each
29
element in the queue calls the function with a pointer to that element. If the
30
returns zero queue_*_foreach will continue processing the rest of the items, if
31
the function returns non zero then queue_*_foreach will not process any more items.
32
33
*/
34
41
#define QUEUE(name, type, size) \
42
struct queue_##name { \
43
type storage[size]; \
44
/*index of the read head, initialy 0*/
\
45
size_t read; \
46
/*index of the write head, initialy 0*/
\
47
size_t write; \
48
/*number of items in the queue*/
\
49
size_t count; \
50
}; \
51
static inline int queue_##name##_init(volatile struct queue_##name *self) { \
52
if (!self) return -1; \
53
self->read = 0; \
54
self->write = 0; \
55
self->count = 0; \
56
return 0; \
57
} \
58
static inline int queue_##name##_push(volatile struct queue_##name *self, \
59
const volatile type *item) { \
60
if (!self || !item) return -1; \
61
if (self->count < size) { \
62
size_t next = (self->write + 1) % size; \
63
self->storage[next] = *item; \
64
self->write = next; \
65
self->count++; \
66
return 0; \
67
} else { \
68
return -1; \
69
} \
70
} \
71
static inline int queue_##name##_pop(volatile struct queue_##name *self, \
72
volatile type *item) { \
73
if (!self || !item) return -1; \
74
if (self->count > 0) { \
75
size_t next = (self->read + 1) % size; \
76
*item = self->storage[next]; \
77
self->read = next; \
78
self->count--; \
79
return 0; \
80
} else { \
81
return -1; \
82
} \
83
} \
84
static inline size_t queue_##name##_count(const volatile struct queue_##name *self) { \
85
if (!self) return 0; \
86
return self->count; \
87
} \
88
static inline void queue_##name##_foreach(volatile struct queue_##name *self, \
89
int (*fun)(volatile type *, volatile void *), \
90
volatile void *ctx) { \
91
if (!self) return; \
92
if (fun == NULL) return; \
93
for (size_t i = 0; i < self->count; ++i) { \
94
if (fun(&self->storage[(self->read + i + 1) % size], ctx) != 0) break; \
95
} \
96
}
97
98
#ifdef DOXYGEN
99
QUEUE
(NAME, TYPE, SIZE);
146
#endif
147
148
149
#endif //QUEUE_H
150
QUEUE
#define QUEUE(name, type, size)
Generates the queue api.
Definition:
queue.h:41
Generated by
1.8.14