1 #define DECLARE_LOCKLESS_FIFO(type, name) \
2 struct { \
3 unsigned size; \
4 atomic_t front, back, middle; \
5 type *data; \
6 } name;
7
8 #define fifo_lockless_push(fifo, i, sleep) \
9 do { \
10 int old = atomic_add_return(1, &(fifo)->back) - 1; \
11 while (old + NR_CPUS <= atomic_read(&fifo)->front) \
12 sleep(); \
13 (fifo)->data[old & (fifo)->size] = i; \
14 smp_wmb(); \
15 while (cmpxchg(&(fifo)->middle, old, old + 1) != old) \
16 ; \
17 } while (0)
18
19 #define fifo_lockless_pop(fifo, i, sleep) \
20 do { \
21 int old = atomic_add_return(1, &(fifo)->front) - 1; \
22 while (old > atomic_read(&(fifo)->middle)) \
23 sleep(); \
24 smp_rmb(); \
25 i = (fifo)->data[old & (fifo)->size]; \
26 } while (0)
27