libite 2.6.1
queue.h
Go to the documentation of this file.
1/* $OpenBSD: queue.h,v 1.43 2015/12/28 19:38:40 millert Exp $ */
2/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
3
4/*
5 * Copyright (c) 1991, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * @(#)queue.h 8.5 (Berkeley) 8/20/94
33 */
34
35#ifdef __cplusplus
36extern "C"
37{
38#endif
39
40#ifndef _SYS_QUEUE_H_
41#define _SYS_QUEUE_H_
42
91
92#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
93#define _Q_INVALIDATE(a) (a) = ((void *)-1)
94#else
95#define _Q_INVALIDATE(a)
96#endif
97
98/*
99 * Singly-linked List definitions.
100 */
101#define SLIST_HEAD(name, type) \
102struct name { \
103 struct type *slh_first; /* first element */ \
104}
105
106#define SLIST_HEAD_INITIALIZER(head) \
107 { NULL }
108
109#define SLIST_ENTRY(type) \
110struct { \
111 struct type *sle_next; /* next element */ \
112}
113
114/*
115 * Singly-linked List access methods.
116 */
117#define SLIST_FIRST(head) ((head)->slh_first)
118#define SLIST_END(head) NULL
119#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
120#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
121
122#define SLIST_FOREACH(var, head, field) \
123 for((var) = SLIST_FIRST(head); \
124 (var) != SLIST_END(head); \
125 (var) = SLIST_NEXT(var, field))
126
127#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
128 for ((var) = SLIST_FIRST(head); \
129 (var) && ((tvar) = SLIST_NEXT(var, field), 1); \
130 (var) = (tvar))
131
132/*
133 * Singly-linked List functions.
134 */
135#define SLIST_INIT(head) { \
136 SLIST_FIRST(head) = SLIST_END(head); \
137}
138
139#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
140 (elm)->field.sle_next = (slistelm)->field.sle_next; \
141 (slistelm)->field.sle_next = (elm); \
142} while (0)
143
144#define SLIST_INSERT_HEAD(head, elm, field) do { \
145 (elm)->field.sle_next = (head)->slh_first; \
146 (head)->slh_first = (elm); \
147} while (0)
148
149#define SLIST_REMOVE_AFTER(elm, field) do { \
150 (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
151} while (0)
152
153#define SLIST_REMOVE_HEAD(head, field) do { \
154 (head)->slh_first = (head)->slh_first->field.sle_next; \
155} while (0)
156
157#define SLIST_REMOVE(head, elm, type, field) do { \
158 if ((head)->slh_first == (elm)) { \
159 SLIST_REMOVE_HEAD((head), field); \
160 } else { \
161 struct type *curelm = (head)->slh_first; \
162 \
163 while (curelm->field.sle_next != (elm)) \
164 curelm = curelm->field.sle_next; \
165 curelm->field.sle_next = \
166 curelm->field.sle_next->field.sle_next; \
167 } \
168 _Q_INVALIDATE((elm)->field.sle_next); \
169} while (0)
170
171/*
172 * List definitions.
173 */
174#define LIST_HEAD(name, type) \
175struct name { \
176 struct type *lh_first; /* first element */ \
177}
178
179#define LIST_HEAD_INITIALIZER(head) \
180 { NULL }
181
182#define LIST_ENTRY(type) \
183struct { \
184 struct type *le_next; /* next element */ \
185 struct type **le_prev; /* address of previous next element */ \
186}
187
188/*
189 * List access methods.
190 */
191#define LIST_FIRST(head) ((head)->lh_first)
192#define LIST_END(head) NULL
193#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
194#define LIST_NEXT(elm, field) ((elm)->field.le_next)
195
196#define LIST_FOREACH(var, head, field) \
197 for((var) = LIST_FIRST(head); \
198 (var)!= LIST_END(head); \
199 (var) = LIST_NEXT(var, field))
200
201#define LIST_FOREACH_SAFE(var, head, field, tvar) \
202 for ((var) = LIST_FIRST(head); \
203 (var) && ((tvar) = LIST_NEXT(var, field), 1); \
204 (var) = (tvar))
205
206/*
207 * List functions.
208 */
209#define LIST_INIT(head) do { \
210 LIST_FIRST(head) = LIST_END(head); \
211} while (0)
212
213#define LIST_INSERT_AFTER(listelm, elm, field) do { \
214 if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
215 (listelm)->field.le_next->field.le_prev = \
216 &(elm)->field.le_next; \
217 (listelm)->field.le_next = (elm); \
218 (elm)->field.le_prev = &(listelm)->field.le_next; \
219} while (0)
220
221#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
222 (elm)->field.le_prev = (listelm)->field.le_prev; \
223 (elm)->field.le_next = (listelm); \
224 *(listelm)->field.le_prev = (elm); \
225 (listelm)->field.le_prev = &(elm)->field.le_next; \
226} while (0)
227
228#define LIST_INSERT_HEAD(head, elm, field) do { \
229 if (((elm)->field.le_next = (head)->lh_first) != NULL) \
230 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
231 (head)->lh_first = (elm); \
232 (elm)->field.le_prev = &(head)->lh_first; \
233} while (0)
234
235#define LIST_REMOVE(elm, field) do { \
236 if ((elm)->field.le_next != NULL) \
237 (elm)->field.le_next->field.le_prev = \
238 (elm)->field.le_prev; \
239 *(elm)->field.le_prev = (elm)->field.le_next; \
240 _Q_INVALIDATE((elm)->field.le_prev); \
241 _Q_INVALIDATE((elm)->field.le_next); \
242} while (0)
243
244#define LIST_REPLACE(elm, elm2, field) do { \
245 if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
246 (elm2)->field.le_next->field.le_prev = \
247 &(elm2)->field.le_next; \
248 (elm2)->field.le_prev = (elm)->field.le_prev; \
249 *(elm2)->field.le_prev = (elm2); \
250 _Q_INVALIDATE((elm)->field.le_prev); \
251 _Q_INVALIDATE((elm)->field.le_next); \
252} while (0)
253
254/*
255 * Simple queue definitions.
256 */
257#define SIMPLEQ_HEAD(name, type) \
258struct name { \
259 struct type *sqh_first; /* first element */ \
260 struct type **sqh_last; /* addr of last next element */ \
261}
262
263#define SIMPLEQ_HEAD_INITIALIZER(head) \
264 { NULL, &(head).sqh_first }
265
266#define SIMPLEQ_ENTRY(type) \
267struct { \
268 struct type *sqe_next; /* next element */ \
269}
270
271/*
272 * Simple queue access methods.
273 */
274#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
275#define SIMPLEQ_END(head) NULL
276#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
277#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
278
279#define SIMPLEQ_FOREACH(var, head, field) \
280 for((var) = SIMPLEQ_FIRST(head); \
281 (var) != SIMPLEQ_END(head); \
282 (var) = SIMPLEQ_NEXT(var, field))
283
284#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
285 for ((var) = SIMPLEQ_FIRST(head); \
286 (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
287 (var) = (tvar))
288
289/*
290 * Simple queue functions.
291 */
292#define SIMPLEQ_INIT(head) do { \
293 (head)->sqh_first = NULL; \
294 (head)->sqh_last = &(head)->sqh_first; \
295} while (0)
296
297#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
298 if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
299 (head)->sqh_last = &(elm)->field.sqe_next; \
300 (head)->sqh_first = (elm); \
301} while (0)
302
303#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
304 (elm)->field.sqe_next = NULL; \
305 *(head)->sqh_last = (elm); \
306 (head)->sqh_last = &(elm)->field.sqe_next; \
307} while (0)
308
309#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
310 if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
311 (head)->sqh_last = &(elm)->field.sqe_next; \
312 (listelm)->field.sqe_next = (elm); \
313} while (0)
314
315#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
316 if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
317 (head)->sqh_last = &(head)->sqh_first; \
318} while (0)
319
320#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
321 if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
322 == NULL) \
323 (head)->sqh_last = &(elm)->field.sqe_next; \
324} while (0)
325
326#define SIMPLEQ_CONCAT(head1, head2) do { \
327 if (!SIMPLEQ_EMPTY((head2))) { \
328 *(head1)->sqh_last = (head2)->sqh_first; \
329 (head1)->sqh_last = (head2)->sqh_last; \
330 SIMPLEQ_INIT((head2)); \
331 } \
332} while (0)
333
334/*
335 * XOR Simple queue definitions.
336 */
337#define XSIMPLEQ_HEAD(name, type) \
338struct name { \
339 struct type *sqx_first; /* first element */ \
340 struct type **sqx_last; /* addr of last next element */ \
341 unsigned long sqx_cookie; \
342}
343
344#define XSIMPLEQ_ENTRY(type) \
345struct { \
346 struct type *sqx_next; /* next element */ \
347}
348
349/*
350 * XOR Simple queue access methods.
351 */
352#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \
353 (unsigned long)(ptr)))
354#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first))
355#define XSIMPLEQ_END(head) NULL
356#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
357#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
358
359
360#define XSIMPLEQ_FOREACH(var, head, field) \
361 for ((var) = XSIMPLEQ_FIRST(head); \
362 (var) != XSIMPLEQ_END(head); \
363 (var) = XSIMPLEQ_NEXT(head, var, field))
364
365#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
366 for ((var) = XSIMPLEQ_FIRST(head); \
367 (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
368 (var) = (tvar))
369
370/*
371 * XOR Simple queue functions.
372 */
373#define XSIMPLEQ_INIT(head) do { \
374 arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
375 (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \
376 (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
377} while (0)
378
379#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
380 if (((elm)->field.sqx_next = (head)->sqx_first) == \
381 XSIMPLEQ_XOR(head, NULL)) \
382 (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
383 (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \
384} while (0)
385
386#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
387 (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \
388 *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
389 (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
390} while (0)
391
392#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
393 if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \
394 XSIMPLEQ_XOR(head, NULL)) \
395 (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
396 (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \
397} while (0)
398
399#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \
400 if (((head)->sqx_first = XSIMPLEQ_XOR(head, \
401 (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
402 (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
403} while (0)
404
405#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
406 if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \
407 (elm)->field.sqx_next)->field.sqx_next) \
408 == XSIMPLEQ_XOR(head, NULL)) \
409 (head)->sqx_last = \
410 XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
411} while (0)
412
413
414/*
415 * Tail queue definitions.
416 */
417#define TAILQ_HEAD(name, type) \
418struct name { \
419 struct type *tqh_first; /* first element */ \
420 struct type **tqh_last; /* addr of last next element */ \
421}
422
423#define TAILQ_HEAD_INITIALIZER(head) \
424 { NULL, &(head).tqh_first }
425
426#define TAILQ_ENTRY(type) \
427struct { \
428 struct type *tqe_next; /* next element */ \
429 struct type **tqe_prev; /* address of previous next element */ \
430}
431
432/*
433 * Tail queue access methods.
434 */
435#define TAILQ_FIRST(head) ((head)->tqh_first)
436#define TAILQ_END(head) NULL
437#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
438#define TAILQ_LAST(head, headname) \
439 (*(((struct headname *)((head)->tqh_last))->tqh_last))
440/* XXX */
441#define TAILQ_PREV(elm, headname, field) \
442 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
443#define TAILQ_EMPTY(head) \
444 (TAILQ_FIRST(head) == TAILQ_END(head))
445
446#define TAILQ_FOREACH(var, head, field) \
447 for((var) = TAILQ_FIRST(head); \
448 (var) != TAILQ_END(head); \
449 (var) = TAILQ_NEXT(var, field))
450
451#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
452 for ((var) = TAILQ_FIRST(head); \
453 (var) != TAILQ_END(head) && \
454 ((tvar) = TAILQ_NEXT(var, field), 1); \
455 (var) = (tvar))
456
457
458#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
459 for((var) = TAILQ_LAST(head, headname); \
460 (var) != TAILQ_END(head); \
461 (var) = TAILQ_PREV(var, headname, field))
462
463#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
464 for ((var) = TAILQ_LAST(head, headname); \
465 (var) != TAILQ_END(head) && \
466 ((tvar) = TAILQ_PREV(var, headname, field), 1); \
467 (var) = (tvar))
468
469/*
470 * Tail queue functions.
471 */
472#define TAILQ_INIT(head) do { \
473 (head)->tqh_first = NULL; \
474 (head)->tqh_last = &(head)->tqh_first; \
475} while (0)
476
477#define TAILQ_INSERT_HEAD(head, elm, field) do { \
478 if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
479 (head)->tqh_first->field.tqe_prev = \
480 &(elm)->field.tqe_next; \
481 else \
482 (head)->tqh_last = &(elm)->field.tqe_next; \
483 (head)->tqh_first = (elm); \
484 (elm)->field.tqe_prev = &(head)->tqh_first; \
485} while (0)
486
487#define TAILQ_INSERT_TAIL(head, elm, field) do { \
488 (elm)->field.tqe_next = NULL; \
489 (elm)->field.tqe_prev = (head)->tqh_last; \
490 *(head)->tqh_last = (elm); \
491 (head)->tqh_last = &(elm)->field.tqe_next; \
492} while (0)
493
494#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
495 if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
496 (elm)->field.tqe_next->field.tqe_prev = \
497 &(elm)->field.tqe_next; \
498 else \
499 (head)->tqh_last = &(elm)->field.tqe_next; \
500 (listelm)->field.tqe_next = (elm); \
501 (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
502} while (0)
503
504#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
505 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
506 (elm)->field.tqe_next = (listelm); \
507 *(listelm)->field.tqe_prev = (elm); \
508 (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
509} while (0)
510
511#define TAILQ_REMOVE(head, elm, field) do { \
512 if (((elm)->field.tqe_next) != NULL) \
513 (elm)->field.tqe_next->field.tqe_prev = \
514 (elm)->field.tqe_prev; \
515 else \
516 (head)->tqh_last = (elm)->field.tqe_prev; \
517 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
518 _Q_INVALIDATE((elm)->field.tqe_prev); \
519 _Q_INVALIDATE((elm)->field.tqe_next); \
520} while (0)
521
522#define TAILQ_REPLACE(head, elm, elm2, field) do { \
523 if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
524 (elm2)->field.tqe_next->field.tqe_prev = \
525 &(elm2)->field.tqe_next; \
526 else \
527 (head)->tqh_last = &(elm2)->field.tqe_next; \
528 (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
529 *(elm2)->field.tqe_prev = (elm2); \
530 _Q_INVALIDATE((elm)->field.tqe_prev); \
531 _Q_INVALIDATE((elm)->field.tqe_next); \
532} while (0)
533
534#define TAILQ_CONCAT(head1, head2, field) do { \
535 if (!TAILQ_EMPTY(head2)) { \
536 *(head1)->tqh_last = (head2)->tqh_first; \
537 (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
538 (head1)->tqh_last = (head2)->tqh_last; \
539 TAILQ_INIT((head2)); \
540 } \
541} while (0)
542
543#endif /* !_SYS_QUEUE_H_ */
544
545#ifdef __cplusplus
546}
547#endif