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 acq = (idx - z_rtio_spsc_out(spsc)) < rtio_spsc_size(spsc);                   \ 
  176                        (spsc)->_spsc.acquire += 1;                                                \ 
  178                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.