28 # if __STDC_VERSION__ < 201100L
38 #if defined(P99_DECLARE_ATOMIC) || P00_DOXYGEN
39 # define P99_FIFO(T) P99_PASTE2(p00_fifo_, T)
40 # define P99_FIFO_DECLARE(T) \
41 typedef T P99_PASTE2(p00_fifo_base_, T); \
42 P99_DECLARE_ATOMIC(P99_PASTE2(p00_fifo_base_, T)); \
43 struct P99_PASTE2(p00_fifo_, T) { \
44 _Atomic(P99_PASTE2(p00_fifo_base_, T)) p00_head; \
45 _Atomic(P99_PASTE2(p00_fifo_base_, T)) p00_tail; \
47 typedef struct P99_PASTE2(p00_fifo_, T) P99_PASTE2(p00_fifo_, T)
48 # define P99_FIFO_INITIALIZER(HEAD, TAIL) { \
49 .p00_head = ATOMIC_VAR_INIT(HEAD), \
50 .p00_tail = ATOMIC_VAR_INIT(TAIL), \
61 #define P99_FIFO_APPEND(L, EL) \
65 register const P99_MACRO_VAR(p00_l, (L)); \
66 register const P99_MACRO_VAR(p00_el, (EL)); \
67 register const P99_MACRO_VAR(p00_h, &p00_l->p00_head); \
68 register const P99_MACRO_VAR(p00_t, &p00_l->p00_tail); \
69 p00_el->p99_lifo = 0; \
70 P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
74 if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_relaxed)) { \
76 atomic_exchange_explicit(p00_t, p00_el, memory_order_acq_rel)->p99_lifo = p00_el; \
78 atomic_store_explicit(p00_h, p00_head, memory_order_release); \
82 P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_relaxed)); \
84 && atomic_compare_exchange_weak_explicit(p00_t, &p00_tail, p00_el, memory_order_acq_rel, memory_order_relaxed)) { \
86 atomic_store_explicit(p00_h, p00_el, memory_order_release); \
90 p00_head = atomic_load_explicit(p00_h, memory_order_consume); \
136 #define P99_FIFO_POP(L) \
141 register const P99_MACRO_VAR(p00_l, (L)); \
142 register const P99_MACRO_VAR(p00_h, &p00_l->p00_head); \
143 register const P99_MACRO_VAR(p00_t, &p00_l->p00_tail); \
144 P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
148 if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_consume)) { \
149 if (p00_head->p99_lifo) \
152 atomic_store_explicit(p00_h, p00_head->p99_lifo, memory_order_release); \
156 atomic_store_explicit(p00_t, 0, memory_order_release); \
157 p00_head->p99_lifo = 0; \
161 register P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_consume)); \
162 if (!p00_tail) break; \
163 p00_head = atomic_load_explicit(p00_h, memory_order_relaxed); \
167 register const __typeof__(p00_head = p00_head) p00_r = p00_head; \
181 #define P99_FIFO_CLEAR(L) \
186 register const P99_MACRO_VAR(p00_l, (L)); \
187 register const P99_MACRO_VAR(p00_h, &p00_l->p00_head); \
188 register const P99_MACRO_VAR(p00_t, &p00_l->p00_tail); \
189 P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
193 if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_consume)) { \
194 atomic_store_explicit(p00_t, 0, memory_order_release); \
198 register const P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_consume)); \
199 if (!p00_tail) break; \
200 p00_head = atomic_load_explicit(p00_h, memory_order_relaxed); \
204 register const __typeof__(p00_head = p00_head) p00_r = p00_head; \
213 # define P99_FIFO(T) P99_PASTE2(p00_fifo_, T)
214 # define P99_FIFO_DECLARE(T) typedef T P99_PASTE2(p00_fifo_, T)[2]
215 # define P99_FIFO_INITIALIZER(HEAD, TAIL) { [0] = (HEAD), [1] = (TAIL) }
217 #define P99_FIFO_APPEND(L, EL) \
220 P99_MACRO_VAR(p00_l, (L)); \
221 P99_MACRO_VAR(p00_el, (EL)); \
222 p00_el->p99_lifo = (*p00_l)[1]; \
223 (*p00_l)[1] = p00_el; \
224 if (!(*p00_l)[0]) (*p00_l)[0] = p00_el; \
227 #define P99_FIFO_POP(L) \
230 P99_MACRO_VAR(p00_l, (L)); \
231 P99_MACRO_VAR(p00_el, (*p00_l)[0]); \
232 (*p00_l)[0] = p00_el->p99_lifo; \
233 if (!(*p00_l)[0]) = (*p00_l)[0] = 0; \
234 if (p00_el) p00_el->p99_lifo = 0; \
236 register const __typeof__(p00_el = p00_el) p00_r = p00_el; \
241 #define P99_FIFO_CLEAR(L) \
243 P99_MACRO_VAR(p00_l, (L)); \
244 register P99_MACRO_VAR(p00_ret, (*p00_l)[0]); \
255 #define P99_FIFO_TABULATE(TYPE, TAB, L) P00_FIFO_TABULATE(TYPE, TAB, P99_UNIQ(TAB), L)
257 #define P00_FIFO_TABULATE(TYPE, TAB, ID, L) \
258 size_t P99_PASTE2(ID, _cnt) = 0; \
259 TYPE * P99_PASTE2(ID, _head) = P99_FIFO_CLEAR(L); \
260 for (TYPE * p00_e = P99_PASTE2(ID, _head); \
262 p00_e = p00_e->p99_lifo) \
263 ++P99_PASTE2(ID, _cnt); \
264 TYPE * TAB[P99_PASTE2(ID, _cnt)]; \
265 for (TYPE ** p00_t = &(TAB[0]), \
266 * p00_e = P99_PASTE2(ID, _head); \
268 p00_e = p00_e->p99_lifo, \