Listing 3
#include "fifo.h" /* Initialization */ static inline void pktq_init (FIFO_T *q, FIFO_CELL_T *base, int size) { volatile FIFO_CELL_T *ptr; int n; FIFO_INIT (q, base, size); for (ptr = q->head.l, n = size; n--; ptr++) *ptr = NULL; } /* Producers */ static inline FIFO_CELL_T *pktq_ins_valid (FIFO_T *q, FIFO_SIZE_T n) { FIFO_SIZE_T avail = FIFO_AVAIL (q); if (n != 0 && ((n < 0 && n >= avail - q->size + 2) || n <= avail)) { volatile FIFO_CELL_T *ptr = q->tail.l + n - 1; ptr = CIRC_ARR_WRAP (ptr, q->base, q->end, q->size); if (*ptr == NULL) return (FIFO_CELL_T *) ptr; } return NULL; } static inline void pktq_ins_at (FIFO_T *q, int n, FIFO_CELL_T pkt, volatile FIFO_CELL_T *ptr) { *ptr = pkt; if (n > 0) q->tail.w = CIRC_ARR_ADV_PTR (ptr, q->base, q->end); } static inline void pktq_ins_oo (FIFO_T *q, int n, FIFO_CELL_T pkt) { int len = FIFO_USED (q); volatile FIFO_CELL_T *ptr = q->tail.l + n - 1; ptr = CIRC_ARR_WRAP (ptr, q->base, q->end, q->size); pktq_ins_at (q, n, pkt, ptr); } /* Consumers */ STATIC_INLINE void pktq_drop (FIFO_T *q, FIFO_SIZE_T n) { FIFO_SIZE_T total; volatile FIFO_CELL_T *ptr; for (ptr = q->head.l, total = 0; n; ptr = CIRC_ARR_ADV_PTR (ptr, q->base, q->end), total++) if (ptr == q->tail.r) break; else if (*ptr) { *ptr = NULL; n--; } FIFO_DROP (q, total); } static inline FIFO_CELL_T pktq_read (FIFO_T *q) { FIFO_CELL_T result = NULL; FIFO_SIZE_T total; volatile FIFO_CELL_T *ptr; for (ptr = q->head.l, total = 0; ptr != q->tail.r; ptr = CIRC_ARR_ADV_PTR (ptr, q->base, q->end), total++) if (*ptr) { result = *ptr; *ptr = NULL; total++; break; } FIFO_DROP (q, total); return result; }