Listing 2
#if 0 /* REQUIRED DEFINITIONS */ #define FIFO_CELL_T int /* any type */ #define FIFO_T myq /* optional name of queue type */ #define FIFO_P2_SIZE /* optional, optimize for size 2^n */ #endif #include "circ_arr.h" typedef struct { FIFO_CELL_T *base, *end; union { volatile FIFO_CELL_T * volatile w; volatile FIFO_CELL_T * volatile const r; volatile FIFO_CELL_T * const l; } head, tail; int size, mask; } FIFO_T; /* Initialization */ #define FIFO_INIT( q, b, sz ) (\ (q)->base = (b), (q)->end = (b) + (sz), \ (q)->tail.w = (q)->head.w = (b), \ (q)->size = (sz), (q)->mask = (sz) - 1 \ ) /* Producer primitives */ static inline BOOL fifo_full (const FIFO_T *q) { volatile const FIFO_CELL_T *head = q->head.r; #ifdef FIFO_P2_SIZE return CIRC_ARR_P2_DS_FULL (head, q->tail.l, q->mask); #else return CIRC_ARR_DS_FULL (head, q->tail.l, q->size); #endif } static inline void fifo_ins (FIFO_T *q, FIFO_CELL_T x) { *q->tail.l = x; q->tail.w = CIRC_ARR_ADV_PTR (q->tail.l, q->base, q->end); } #define FIFO_INS_CHK( q, x ) \ (fifo_full (q) ? FALSE : (fifo_ins (q, x), TRUE)) static inline void fifo_swallow (FIFO_T *q, int delta) { q->tail.w = CIRC_ARR_WRAP_END (q->tail.l + delta, q->base, q->end); } /* Consumer primitives */ static inline FIFO_CELL_T fifo_read (FIFO_T *q) { q->head.w = CIRC_ARR_ADV_PTR (q->head.l, q->base, q->end); return *q->head.l; } #define FIFO_DROP( q, n ) ((q)->head.w = \ CIRC_ARR_WRAP_FWD ((q)->head.l + n, (q)->end, (q)->size))