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))