8#ifndef ZEPHYR_RTIO_SPSC_H_
9#define ZEPHYR_RTIO_SPSC_H_
62 unsigned long acquire;
65 unsigned long consume;
74 const unsigned long mask;
83#define RTIO_SPSC_INITIALIZER(sz, buf) \
88 .in = ATOMIC_INIT(0), \
89 .out = ATOMIC_INIT(0), \
101#define RTIO_SPSC_DECLARE(name, type) \
102 static struct rtio_spsc_##name { \
103 struct rtio_spsc _spsc; \
104 type * const buffer; \
114#define RTIO_SPSC_DEFINE(name, type, sz) \
115 BUILD_ASSERT(IS_POWER_OF_TWO(sz)); \
116 static type __spsc_buf_##name[sz]; \
117 RTIO_SPSC_DECLARE(name, type) name = RTIO_SPSC_INITIALIZER(sz, __spsc_buf_##name);
124#define rtio_spsc_size(spsc) ((spsc)->_spsc.mask + 1)
133#define z_rtio_spsc_mask(spsc, i) ((i) & (spsc)->_spsc.mask)
140#define z_rtio_spsc_in(spsc) (unsigned long)atomic_get(&(spsc)->_spsc.in)
146#define z_rtio_spsc_out(spsc) (unsigned long)atomic_get(&(spsc)->_spsc.out)
156#define rtio_spsc_reset(spsc) \
158 (spsc)->_spsc.consume = 0; \
159 (spsc)->_spsc.acquire = 0; \
160 atomic_set(&(spsc)->_spsc.in, 0); \
161 atomic_set(&(spsc)->_spsc.out, 0); \
171#define rtio_spsc_acquire(spsc) \
173 unsigned long idx = z_rtio_spsc_in(spsc) + (spsc)->_spsc.acquire; \
174 bool spsc_acq = (idx - z_rtio_spsc_out(spsc)) < rtio_spsc_size(spsc); \
176 (spsc)->_spsc.acquire += 1; \
178 spsc_acq ? &((spsc)->buffer[z_rtio_spsc_mask(spsc, idx)]) : NULL; \
188#define rtio_spsc_produce(spsc) \
190 if ((spsc)->_spsc.acquire > 0) { \
191 (spsc)->_spsc.acquire -= 1; \
192 atomic_add(&(spsc)->_spsc.in, 1); \
204#define rtio_spsc_produce_all(spsc) \
206 if ((spsc)->_spsc.acquire > 0) { \
207 unsigned long acquired = (spsc)->_spsc.acquire; \
208 (spsc)->_spsc.acquire = 0; \
209 atomic_add(&(spsc)->_spsc.in, acquired); \
220#define rtio_spsc_drop_all(spsc) \
222 (spsc)->_spsc.acquire = 0; \
232#define rtio_spsc_consume(spsc) \
234 unsigned long idx = z_rtio_spsc_out(spsc) + (spsc)->_spsc.consume; \
235 bool has_consumable = (idx != z_rtio_spsc_in(spsc)); \
236 if (has_consumable) { \
237 (spsc)->_spsc.consume += 1; \
239 has_consumable ? &((spsc)->buffer[z_rtio_spsc_mask(spsc, idx)]) : NULL; \
247#define rtio_spsc_release(spsc) \
249 if ((spsc)->_spsc.consume > 0) { \
250 (spsc)->_spsc.consume -= 1; \
251 atomic_add(&(spsc)->_spsc.out, 1); \
261#define rtio_spsc_release_all(spsc) \
263 if ((spsc)->_spsc.consume > 0) { \
264 unsigned long consumed = (spsc)->_spsc.consume; \
265 (spsc)->_spsc.consume = 0; \
266 atomic_add(&(spsc)->_spsc.out, consumed); \
275#define rtio_spsc_acquirable(spsc) \
277 (((spsc)->_spsc.in + (spsc)->_spsc.acquire) - (spsc)->_spsc.out) - \
278 rtio_spsc_size(spsc); \
286#define rtio_spsc_consumable(spsc) \
287 ({ (spsc)->_spsc.in - (spsc)->_spsc.out - (spsc)->_spsc.consume; })
296#define rtio_spsc_peek(spsc) \
298 unsigned long idx = z_rtio_spsc_out(spsc) + (spsc)->_spsc.consume; \
299 bool has_consumable = (idx != z_rtio_spsc_in(spsc)); \
300 has_consumable ? &((spsc)->buffer[z_rtio_spsc_mask(spsc, idx)]) : NULL; \
312#define rtio_spsc_next(spsc, item) \
314 unsigned long idx = ((item) - (spsc)->buffer); \
315 bool has_next = z_rtio_spsc_mask(spsc, (idx + 1)) != \
316 (z_rtio_spsc_mask(spsc, z_rtio_spsc_in(spsc))); \
317 has_next ? &((spsc)->buffer[z_rtio_spsc_mask((spsc), idx + 1)]) : NULL; \
328#define rtio_spsc_prev(spsc, item) \
330 unsigned long idx = ((item) - &(spsc)->buffer[0]) / sizeof((spsc)->buffer[0]); \
331 bool has_prev = idx != z_rtio_spsc_mask(spsc, z_rtio_spsc_out(spsc)); \
332 has_prev ? &((spsc)->buffer[z_rtio_spsc_mask(spsc, idx - 1)]) : NULL; \
long atomic_t
Definition atomic.h:22
Common toolchain abstraction.