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 

BcacheWiki: LocklessFifo (last edited 2010-07-08 10:48:39 by Kent)