blob: 089083850b19d85acc981b3b61cf21fc9a4c7639 [file] [log] [blame]
Colin Cross64ceac32010-01-13 21:19:52 -08001/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * @(#)queue.h 8.5 (Berkeley) 8/20/94
30 */
31
32#ifndef _SYS_QUEUE_H_
33#define _SYS_QUEUE_H_
34
Elliott Hughes203e13d2016-07-22 14:56:18 -070035#include <sys/cdefs.h>
36
Colin Cross64ceac32010-01-13 21:19:52 -080037/*
38 * This file defines five types of data structures: singly-linked lists,
39 * lists, simple queues, tail queues, and circular queues.
40 *
41 * A singly-linked list is headed by a single forward pointer. The
42 * elements are singly linked for minimum space and pointer manipulation
43 * overhead at the expense of O(n) removal for arbitrary elements. New
44 * elements can be added to the list after an existing element or at the
45 * head of the list. Elements being removed from the head of the list
46 * should use the explicit macro for this purpose for optimum
47 * efficiency. A singly-linked list may only be traversed in the forward
48 * direction. Singly-linked lists are ideal for applications with large
49 * datasets and few or no removals or for implementing a LIFO queue.
50 *
51 * A list is headed by a single forward pointer (or an array of forward
52 * pointers for a hash table header). The elements are doubly linked
53 * so that an arbitrary element can be removed without a need to
54 * traverse the list. New elements can be added to the list before
55 * or after an existing element or at the head of the list. A list
56 * may only be traversed in the forward direction.
57 *
58 * A simple queue is headed by a pair of pointers, one the head of the
59 * list and the other to the tail of the list. The elements are singly
60 * linked to save space, so elements can only be removed from the
61 * head of the list. New elements can be added to the list after
62 * an existing element, at the head of the list, or at the end of the
63 * list. A simple queue may only be traversed in the forward direction.
64 *
65 * A tail queue is headed by a pair of pointers, one to the head of the
66 * list and the other to the tail of the list. The elements are doubly
67 * linked so that an arbitrary element can be removed without a need to
68 * traverse the list. New elements can be added to the list before or
69 * after an existing element, at the head of the list, or at the end of
70 * the list. A tail queue may be traversed in either direction.
71 *
72 * A circle queue is headed by a pair of pointers, one to the head of the
73 * list and the other to the tail of the list. The elements are doubly
74 * linked so that an arbitrary element can be removed without a need to
75 * traverse the list. New elements can be added to the list before or after
76 * an existing element, at the head of the list, or at the end of the list.
77 * A circle queue may be traversed in either direction, but has a more
78 * complex end of list detection.
79 *
80 * For details on the use of these macros, see the queue(3) manual page.
81 */
82
83/*
84 * List definitions.
85 */
86#define LIST_HEAD(name, type) \
87struct name { \
88 struct type *lh_first; /* first element */ \
89}
90
91#define LIST_HEAD_INITIALIZER(head) \
92 { NULL }
93
94#define LIST_ENTRY(type) \
95struct { \
96 struct type *le_next; /* next element */ \
97 struct type **le_prev; /* address of previous next element */ \
98}
99
100/*
101 * List functions.
102 */
103#define LIST_INIT(head) do { \
104 (head)->lh_first = NULL; \
105} while (/*CONSTCOND*/0)
106
107#define LIST_INSERT_AFTER(listelm, elm, field) do { \
108 if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
109 (listelm)->field.le_next->field.le_prev = \
110 &(elm)->field.le_next; \
111 (listelm)->field.le_next = (elm); \
112 (elm)->field.le_prev = &(listelm)->field.le_next; \
113} while (/*CONSTCOND*/0)
114
115#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
116 (elm)->field.le_prev = (listelm)->field.le_prev; \
117 (elm)->field.le_next = (listelm); \
118 *(listelm)->field.le_prev = (elm); \
119 (listelm)->field.le_prev = &(elm)->field.le_next; \
120} while (/*CONSTCOND*/0)
121
122#define LIST_INSERT_HEAD(head, elm, field) do { \
123 if (((elm)->field.le_next = (head)->lh_first) != NULL) \
124 (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
125 (head)->lh_first = (elm); \
126 (elm)->field.le_prev = &(head)->lh_first; \
127} while (/*CONSTCOND*/0)
128
129#define LIST_REMOVE(elm, field) do { \
130 if ((elm)->field.le_next != NULL) \
131 (elm)->field.le_next->field.le_prev = \
132 (elm)->field.le_prev; \
133 *(elm)->field.le_prev = (elm)->field.le_next; \
134} while (/*CONSTCOND*/0)
135
136#define LIST_FOREACH(var, head, field) \
137 for ((var) = ((head)->lh_first); \
138 (var); \
139 (var) = ((var)->field.le_next))
140
141/*
142 * List access methods.
143 */
144#define LIST_EMPTY(head) ((head)->lh_first == NULL)
145#define LIST_FIRST(head) ((head)->lh_first)
146#define LIST_NEXT(elm, field) ((elm)->field.le_next)
147
148
149/*
150 * Singly-linked List definitions.
151 */
152#define SLIST_HEAD(name, type) \
153struct name { \
154 struct type *slh_first; /* first element */ \
155}
156
157#define SLIST_HEAD_INITIALIZER(head) \
158 { NULL }
159
160#define SLIST_ENTRY(type) \
161struct { \
162 struct type *sle_next; /* next element */ \
163}
164
165/*
166 * Singly-linked List functions.
167 */
168#define SLIST_INIT(head) do { \
169 (head)->slh_first = NULL; \
170} while (/*CONSTCOND*/0)
171
172#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
173 (elm)->field.sle_next = (slistelm)->field.sle_next; \
174 (slistelm)->field.sle_next = (elm); \
175} while (/*CONSTCOND*/0)
176
177#define SLIST_INSERT_HEAD(head, elm, field) do { \
178 (elm)->field.sle_next = (head)->slh_first; \
179 (head)->slh_first = (elm); \
180} while (/*CONSTCOND*/0)
181
182#define SLIST_REMOVE_HEAD(head, field) do { \
183 (head)->slh_first = (head)->slh_first->field.sle_next; \
184} while (/*CONSTCOND*/0)
185
186#define SLIST_REMOVE(head, elm, type, field) do { \
187 if ((head)->slh_first == (elm)) { \
188 SLIST_REMOVE_HEAD((head), field); \
189 } \
190 else { \
191 struct type *curelm = (head)->slh_first; \
192 while(curelm->field.sle_next != (elm)) \
193 curelm = curelm->field.sle_next; \
194 curelm->field.sle_next = \
195 curelm->field.sle_next->field.sle_next; \
196 } \
197} while (/*CONSTCOND*/0)
198
199#define SLIST_FOREACH(var, head, field) \
200 for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
201
202/*
203 * Singly-linked List access methods.
204 */
205#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
206#define SLIST_FIRST(head) ((head)->slh_first)
207#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
208
209
210/*
211 * Singly-linked Tail queue declarations.
212 */
213#define STAILQ_HEAD(name, type) \
214struct name { \
215 struct type *stqh_first; /* first element */ \
216 struct type **stqh_last; /* addr of last next element */ \
217}
218
219#define STAILQ_HEAD_INITIALIZER(head) \
220 { NULL, &(head).stqh_first }
221
222#define STAILQ_ENTRY(type) \
223struct { \
224 struct type *stqe_next; /* next element */ \
225}
226
227/*
228 * Singly-linked Tail queue functions.
229 */
230#define STAILQ_INIT(head) do { \
231 (head)->stqh_first = NULL; \
232 (head)->stqh_last = &(head)->stqh_first; \
233} while (/*CONSTCOND*/0)
234
235#define STAILQ_INSERT_HEAD(head, elm, field) do { \
236 if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
237 (head)->stqh_last = &(elm)->field.stqe_next; \
238 (head)->stqh_first = (elm); \
239} while (/*CONSTCOND*/0)
240
241#define STAILQ_INSERT_TAIL(head, elm, field) do { \
242 (elm)->field.stqe_next = NULL; \
243 *(head)->stqh_last = (elm); \
244 (head)->stqh_last = &(elm)->field.stqe_next; \
245} while (/*CONSTCOND*/0)
246
247#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
248 if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
249 (head)->stqh_last = &(elm)->field.stqe_next; \
250 (listelm)->field.stqe_next = (elm); \
251} while (/*CONSTCOND*/0)
252
253#define STAILQ_REMOVE_HEAD(head, field) do { \
254 if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
255 (head)->stqh_last = &(head)->stqh_first; \
256} while (/*CONSTCOND*/0)
257
258#define STAILQ_REMOVE(head, elm, type, field) do { \
259 if ((head)->stqh_first == (elm)) { \
260 STAILQ_REMOVE_HEAD((head), field); \
261 } else { \
262 struct type *curelm = (head)->stqh_first; \
263 while (curelm->field.stqe_next != (elm)) \
264 curelm = curelm->field.stqe_next; \
265 if ((curelm->field.stqe_next = \
266 curelm->field.stqe_next->field.stqe_next) == NULL) \
267 (head)->stqh_last = &(curelm)->field.stqe_next; \
268 } \
269} while (/*CONSTCOND*/0)
270
271#define STAILQ_FOREACH(var, head, field) \
272 for ((var) = ((head)->stqh_first); \
273 (var); \
274 (var) = ((var)->field.stqe_next))
275
276/*
277 * Singly-linked Tail queue access methods.
278 */
279#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
280#define STAILQ_FIRST(head) ((head)->stqh_first)
281#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
282
283
284/*
285 * Simple queue definitions.
286 */
287#define SIMPLEQ_HEAD(name, type) \
288struct name { \
289 struct type *sqh_first; /* first element */ \
290 struct type **sqh_last; /* addr of last next element */ \
291}
292
293#define SIMPLEQ_HEAD_INITIALIZER(head) \
294 { NULL, &(head).sqh_first }
295
296#define SIMPLEQ_ENTRY(type) \
297struct { \
298 struct type *sqe_next; /* next element */ \
299}
300
301/*
302 * Simple queue functions.
303 */
304#define SIMPLEQ_INIT(head) do { \
305 (head)->sqh_first = NULL; \
306 (head)->sqh_last = &(head)->sqh_first; \
307} while (/*CONSTCOND*/0)
308
309#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
310 if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
311 (head)->sqh_last = &(elm)->field.sqe_next; \
312 (head)->sqh_first = (elm); \
313} while (/*CONSTCOND*/0)
314
315#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
316 (elm)->field.sqe_next = NULL; \
317 *(head)->sqh_last = (elm); \
318 (head)->sqh_last = &(elm)->field.sqe_next; \
319} while (/*CONSTCOND*/0)
320
321#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
322 if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
323 (head)->sqh_last = &(elm)->field.sqe_next; \
324 (listelm)->field.sqe_next = (elm); \
325} while (/*CONSTCOND*/0)
326
327#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
328 if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
329 (head)->sqh_last = &(head)->sqh_first; \
330} while (/*CONSTCOND*/0)
331
332#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
333 if ((head)->sqh_first == (elm)) { \
334 SIMPLEQ_REMOVE_HEAD((head), field); \
335 } else { \
336 struct type *curelm = (head)->sqh_first; \
337 while (curelm->field.sqe_next != (elm)) \
338 curelm = curelm->field.sqe_next; \
339 if ((curelm->field.sqe_next = \
340 curelm->field.sqe_next->field.sqe_next) == NULL) \
341 (head)->sqh_last = &(curelm)->field.sqe_next; \
342 } \
343} while (/*CONSTCOND*/0)
344
345#define SIMPLEQ_FOREACH(var, head, field) \
346 for ((var) = ((head)->sqh_first); \
347 (var); \
348 (var) = ((var)->field.sqe_next))
349
350/*
351 * Simple queue access methods.
352 */
353#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
354#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
355#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
356
357
358/*
359 * Tail queue definitions.
360 */
361#define _TAILQ_HEAD(name, type, qual) \
362struct name { \
363 qual type *tqh_first; /* first element */ \
364 qual type *qual *tqh_last; /* addr of last next element */ \
365}
366#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
367
368#define TAILQ_HEAD_INITIALIZER(head) \
369 { NULL, &(head).tqh_first }
370
371#define _TAILQ_ENTRY(type, qual) \
372struct { \
373 qual type *tqe_next; /* next element */ \
374 qual type *qual *tqe_prev; /* address of previous next element */\
375}
376#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
377
378/*
379 * Tail queue functions.
380 */
381#define TAILQ_INIT(head) do { \
382 (head)->tqh_first = NULL; \
383 (head)->tqh_last = &(head)->tqh_first; \
384} while (/*CONSTCOND*/0)
385
386#define TAILQ_INSERT_HEAD(head, elm, field) do { \
387 if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
388 (head)->tqh_first->field.tqe_prev = \
389 &(elm)->field.tqe_next; \
390 else \
391 (head)->tqh_last = &(elm)->field.tqe_next; \
392 (head)->tqh_first = (elm); \
393 (elm)->field.tqe_prev = &(head)->tqh_first; \
394} while (/*CONSTCOND*/0)
395
396#define TAILQ_INSERT_TAIL(head, elm, field) do { \
397 (elm)->field.tqe_next = NULL; \
398 (elm)->field.tqe_prev = (head)->tqh_last; \
399 *(head)->tqh_last = (elm); \
400 (head)->tqh_last = &(elm)->field.tqe_next; \
401} while (/*CONSTCOND*/0)
402
403#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
404 if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
405 (elm)->field.tqe_next->field.tqe_prev = \
406 &(elm)->field.tqe_next; \
407 else \
408 (head)->tqh_last = &(elm)->field.tqe_next; \
409 (listelm)->field.tqe_next = (elm); \
410 (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
411} while (/*CONSTCOND*/0)
412
413#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
414 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
415 (elm)->field.tqe_next = (listelm); \
416 *(listelm)->field.tqe_prev = (elm); \
417 (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
418} while (/*CONSTCOND*/0)
419
420#define TAILQ_REMOVE(head, elm, field) do { \
421 if (((elm)->field.tqe_next) != NULL) \
422 (elm)->field.tqe_next->field.tqe_prev = \
423 (elm)->field.tqe_prev; \
424 else \
425 (head)->tqh_last = (elm)->field.tqe_prev; \
426 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
427} while (/*CONSTCOND*/0)
428
429#define TAILQ_FOREACH(var, head, field) \
430 for ((var) = ((head)->tqh_first); \
431 (var); \
432 (var) = ((var)->field.tqe_next))
433
434#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
435 for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
436 (var); \
437 (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
438
439/*
440 * Tail queue access methods.
441 */
442#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
443#define TAILQ_FIRST(head) ((head)->tqh_first)
444#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
445
446#define TAILQ_LAST(head, headname) \
447 (*(((struct headname *)((head)->tqh_last))->tqh_last))
448#define TAILQ_PREV(elm, headname, field) \
449 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
450
451
452/*
453 * Circular queue definitions.
454 */
455#define CIRCLEQ_HEAD(name, type) \
456struct name { \
457 struct type *cqh_first; /* first element */ \
458 struct type *cqh_last; /* last element */ \
459}
460
461#define CIRCLEQ_HEAD_INITIALIZER(head) \
462 { (void *)&head, (void *)&head }
463
464#define CIRCLEQ_ENTRY(type) \
465struct { \
466 struct type *cqe_next; /* next element */ \
467 struct type *cqe_prev; /* previous element */ \
468}
469
470/*
471 * Circular queue functions.
472 */
473#define CIRCLEQ_INIT(head) do { \
474 (head)->cqh_first = (void *)(head); \
475 (head)->cqh_last = (void *)(head); \
476} while (/*CONSTCOND*/0)
477
478#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
479 (elm)->field.cqe_next = (listelm)->field.cqe_next; \
480 (elm)->field.cqe_prev = (listelm); \
481 if ((listelm)->field.cqe_next == (void *)(head)) \
482 (head)->cqh_last = (elm); \
483 else \
484 (listelm)->field.cqe_next->field.cqe_prev = (elm); \
485 (listelm)->field.cqe_next = (elm); \
486} while (/*CONSTCOND*/0)
487
488#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
489 (elm)->field.cqe_next = (listelm); \
490 (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
491 if ((listelm)->field.cqe_prev == (void *)(head)) \
492 (head)->cqh_first = (elm); \
493 else \
494 (listelm)->field.cqe_prev->field.cqe_next = (elm); \
495 (listelm)->field.cqe_prev = (elm); \
496} while (/*CONSTCOND*/0)
497
498#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
499 (elm)->field.cqe_next = (head)->cqh_first; \
500 (elm)->field.cqe_prev = (void *)(head); \
501 if ((head)->cqh_last == (void *)(head)) \
502 (head)->cqh_last = (elm); \
503 else \
504 (head)->cqh_first->field.cqe_prev = (elm); \
505 (head)->cqh_first = (elm); \
506} while (/*CONSTCOND*/0)
507
508#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
509 (elm)->field.cqe_next = (void *)(head); \
510 (elm)->field.cqe_prev = (head)->cqh_last; \
511 if ((head)->cqh_first == (void *)(head)) \
512 (head)->cqh_first = (elm); \
513 else \
514 (head)->cqh_last->field.cqe_next = (elm); \
515 (head)->cqh_last = (elm); \
516} while (/*CONSTCOND*/0)
517
518#define CIRCLEQ_REMOVE(head, elm, field) do { \
519 if ((elm)->field.cqe_next == (void *)(head)) \
520 (head)->cqh_last = (elm)->field.cqe_prev; \
521 else \
522 (elm)->field.cqe_next->field.cqe_prev = \
523 (elm)->field.cqe_prev; \
524 if ((elm)->field.cqe_prev == (void *)(head)) \
525 (head)->cqh_first = (elm)->field.cqe_next; \
526 else \
527 (elm)->field.cqe_prev->field.cqe_next = \
528 (elm)->field.cqe_next; \
529} while (/*CONSTCOND*/0)
530
531#define CIRCLEQ_FOREACH(var, head, field) \
532 for ((var) = ((head)->cqh_first); \
533 (var) != (const void *)(head); \
534 (var) = ((var)->field.cqe_next))
535
536#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
537 for ((var) = ((head)->cqh_last); \
538 (var) != (const void *)(head); \
539 (var) = ((var)->field.cqe_prev))
540
541/*
542 * Circular queue access methods.
543 */
544#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
545#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
546#define CIRCLEQ_LAST(head) ((head)->cqh_last)
547#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
548#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
549
550#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
551 (((elm)->field.cqe_next == (void *)(head)) \
552 ? ((head)->cqh_first) \
553 : (elm->field.cqe_next))
554#define CIRCLEQ_LOOP_PREV(head, elm, field) \
555 (((elm)->field.cqe_prev == (void *)(head)) \
556 ? ((head)->cqh_last) \
557 : (elm->field.cqe_prev))
558
559#endif /* sys/queue.h */