• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  * 4. 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  * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $
31  */
32 
33 #ifndef _QUEUE_H_
34 #define _QUEUE_H_
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 /*
41  * This file defines five types of data structures: singly-linked lists,
42  * singly-linked tail queues, lists, tail queues, and circular queues.
43  *
44  * A singly-linked list is headed by a single forward pointer. The elements
45  * are singly linked for minimum space and pointer manipulation overhead at
46  * the expense of O(n) removal for arbitrary elements. New elements can be
47  * added to the list after an existing element or at the head of the list.
48  * Elements being removed from the head of the list should use the explicit
49  * macro for this purpose for optimum efficiency. A singly-linked list may
50  * only be traversed in the forward direction.  Singly-linked lists are ideal
51  * for applications with large datasets and few or no removals or for
52  * implementing a LIFO queue.
53  *
54  * A singly-linked tail queue is headed by a pair of pointers, one to the
55  * head of the list and the other to the tail of the list. The elements are
56  * singly linked for minimum space and pointer manipulation overhead at the
57  * expense of O(n) removal for arbitrary elements. New elements can be added
58  * to the list after an existing element, at the head of the list, or at the
59  * end of the list. Elements being removed from the head of the tail queue
60  * should use the explicit macro for this purpose for optimum efficiency.
61  * A singly-linked tail queue may only be traversed in the forward direction.
62  * Singly-linked tail queues are ideal for applications with large datasets
63  * and few or no removals or for implementing a FIFO queue.
64  *
65  * A list is headed by a single forward pointer (or an array of forward
66  * pointers for a hash table header). The elements are doubly linked
67  * 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
69  * or after an existing element or at the head of the list. A list
70  * may only be traversed in the forward direction.
71  *
72  * A tail 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
76  * after an existing element, at the head of the list, or at the end of
77  * the list. A tail queue may be traversed in either direction.
78  *
79  * A circle queue is headed by a pair of pointers, one to the head of the
80  * list and the other to the tail of the list. The elements are doubly
81  * linked so that an arbitrary element can be removed without a need to
82  * traverse the list. New elements can be added to the list before or after
83  * an existing element, at the head of the list, or at the end of the list.
84  * A circle queue may be traversed in either direction, but has a more
85  * complex end of list detection.
86  *
87  * For details on the use of these macros, see the queue(3) manual page.
88  *
89  *
90  *                      SLIST   LIST    STAILQ  TAILQ   CIRCLEQ
91  * _HEAD                +       +       +       +       +
92  * _HEAD_INITIALIZER    +       +       +       +       +
93  * _ENTRY               +       +       +       +       +
94  * _INIT                +       +       +       +       +
95  * _EMPTY               +       +       +       +       +
96  * _FIRST               +       +       +       +       +
97  * _NEXT                +       +       +       +       +
98  * _PREV                -       -       -       +       +
99  * _LAST                -       -       +       +       +
100  * _FOREACH             +       +       +       +       +
101  * _FOREACH_REVERSE     -       -       -       +       +
102  * _INSERT_HEAD         +       +       +       +       +
103  * _INSERT_BEFORE       -       +       -       +       +
104  * _INSERT_AFTER        +       +       +       +       +
105  * _INSERT_TAIL         -       -       +       +       +
106  * _REMOVE_HEAD         +       -       +       -       -
107  * _REMOVE              +       +       +       +       +
108  *
109  */
110 
111 /*
112  * Singly-linked List declarations.
113  */
114 #define SLIST_HEAD(name, type)                          \
115 struct name {                                           \
116     struct type *slh_first; /* first element */         \
117 }
118 
119 #define SLIST_HEAD_INITIALIZER(head)                    \
120     { NULL }
121 
122 #define SLIST_ENTRY(type)                               \
123 struct {                                                \
124     struct type *sle_next;  /* next element */          \
125 }
126 
127 /*
128  * Singly-linked List functions.
129  */
130 #define SLIST_EMPTY(head)   ((head)->slh_first == NULL)
131 
132 #define SLIST_FIRST(head)   ((head)->slh_first)
133 
134 #define SLIST_FOREACH(var, head, field)                 \
135     for ((var) = SLIST_FIRST((head));                   \
136         (var);                                          \
137         (var) = SLIST_NEXT((var), field))
138 
139 #define SLIST_INIT(head) do {                           \
140         SLIST_FIRST((head)) = NULL;                     \
141 } while (0)
142 
143 #define SLIST_INSERT_AFTER(slistelm, elm, field) do {           \
144     SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);   \
145     SLIST_NEXT((slistelm), field) = (elm);                      \
146 } while (0)
147 
148 #define SLIST_INSERT_HEAD(head, elm, field) do {            \
149     SLIST_NEXT((elm), field) = SLIST_FIRST((head));         \
150     SLIST_FIRST((head)) = (elm);                            \
151 } while (0)
152 
153 #define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
154 
155 #define SLIST_REMOVE(head, elm, type, field) do {           \
156     if (SLIST_FIRST((head)) == (elm)) {                     \
157         SLIST_REMOVE_HEAD((head), field);                   \
158     }                                                       \
159     else {                                                  \
160         struct type *curelm = SLIST_FIRST((head));          \
161         while (SLIST_NEXT(curelm, field) != (elm))          \
162             curelm = SLIST_NEXT(curelm, field);             \
163         SLIST_NEXT(curelm, field) =                         \
164             SLIST_NEXT(SLIST_NEXT(curelm, field), field);   \
165     }                                                       \
166 } while (0)
167 
168 #define SLIST_REMOVE_HEAD(head, field) do {                         \
169     SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);   \
170 } while (0)
171 
172 /*
173  * Singly-linked Tail queue declarations.
174  */
175 #define STAILQ_HEAD(name, type)                     \
176 struct name {                               \
177     struct type *stqh_first; /* first element */         \
178     struct type **stqh_last; /* addr of last next element */     \
179 }
180 
181 #define STAILQ_HEAD_INITIALIZER(head)                   \
182     { NULL, &(head).stqh_first }
183 
184 #define STAILQ_ENTRY(type)                      \
185 struct {                                \
186     struct type *stqe_next; /* next element */          \
187 }
188 
189 /*
190  * Singly-linked Tail queue functions.
191  */
192 #define STAILQ_EMPTY(head)  ((head)->stqh_first == NULL)
193 
194 #define STAILQ_FIRST(head)  ((head)->stqh_first)
195 
196 #define STAILQ_FOREACH(var, head, field)                \
197     for ((var) = STAILQ_FIRST((head));               \
198        (var);                           \
199        (var) = STAILQ_NEXT((var), field))
200 
201 #define STAILQ_INIT(head) do {                      \
202     STAILQ_FIRST((head)) = NULL;                    \
203     (head)->stqh_last = &STAILQ_FIRST((head));          \
204 } while (0)
205 
206 #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {       \
207     if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL) \
208         (head)->stqh_last = &STAILQ_NEXT((elm), field);     \
209     STAILQ_NEXT((tqelm), field) = (elm);                \
210 } while (0)
211 
212 #define STAILQ_INSERT_HEAD(head, elm, field) do {           \
213     if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
214         (head)->stqh_last = &STAILQ_NEXT((elm), field);     \
215     STAILQ_FIRST((head)) = (elm);                   \
216 } while (0)
217 
218 #define STAILQ_INSERT_TAIL(head, elm, field) do {           \
219     STAILQ_NEXT((elm), field) = NULL;               \
220     *(head)->stqh_last = (elm);                 \
221     (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
222 } while (0)
223 
224 #define STAILQ_LAST(head, type, field)                  \
225     (STAILQ_EMPTY(head) ?                       \
226         NULL :                          \
227             ((struct type *)                    \
228         ((char *)((head)->stqh_last) - offsetof(struct type, field))))
229 
230 #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
231 
232 #define STAILQ_REMOVE(head, elm, type, field) do {          \
233     if (STAILQ_FIRST((head)) == (elm)) {                \
234         STAILQ_REMOVE_HEAD(head, field);            \
235     }                               \
236     else {                              \
237         struct type *curelm = STAILQ_FIRST((head));     \
238         while (STAILQ_NEXT(curelm, field) != (elm))     \
239             curelm = STAILQ_NEXT(curelm, field);        \
240         if ((STAILQ_NEXT(curelm, field) =           \
241              STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL) \
242             (head)->stqh_last = &STAILQ_NEXT((curelm), field); \
243     }                               \
244 } while (0)
245 
246 #define STAILQ_REMOVE_HEAD(head, field) do {                \
247     if ((STAILQ_FIRST((head)) =                 \
248          STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)     \
249         (head)->stqh_last = &STAILQ_FIRST((head));      \
250 } while (0)
251 
252 #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {         \
253     if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
254         (head)->stqh_last = &STAILQ_FIRST((head));      \
255 } while (0)
256 
257 #define STAILQ_REMOVE_AFTER(head, elm, field) do {          \
258     if ((STAILQ_NEXT(elm, field) =                  \
259          STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)  \
260         (head)->stqh_last = &STAILQ_NEXT((elm), field);     \
261 } while (0)
262 
263 /*
264  * List declarations.
265  */
266 #define LIST_HEAD(name, type)                       \
267 struct name {                               \
268     struct type *lh_first;  /* first element */         \
269 }
270 
271 #define LIST_HEAD_INITIALIZER(head)                 \
272     { NULL }
273 
274 #define LIST_ENTRY(type)                        \
275 struct {                                \
276     struct type *le_next;   /* next element */          \
277     struct type **le_prev;  /* address of previous next element */  \
278 }
279 
280 /*
281  * List functions.
282  */
283 
284 #define LIST_EMPTY(head)    ((head)->lh_first == NULL)
285 
286 #define LIST_FIRST(head)    ((head)->lh_first)
287 
288 #define LIST_FOREACH(var, head, field)                  \
289     for ((var) = LIST_FIRST((head));                \
290         (var);                          \
291         (var) = LIST_NEXT((var), field))
292 
293 #define LIST_INIT(head) do {                        \
294     LIST_FIRST((head)) = NULL;                  \
295 } while (0)
296 
297 #define LIST_INSERT_AFTER(listelm, elm, field) do {         \
298     if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \
299         LIST_NEXT((listelm), field)->field.le_prev =        \
300             &LIST_NEXT((elm), field);               \
301     LIST_NEXT((listelm), field) = (elm);                \
302     (elm)->field.le_prev = &LIST_NEXT((listelm), field);        \
303 } while (0)
304 
305 #define LIST_INSERT_BEFORE(listelm, elm, field) do {            \
306     (elm)->field.le_prev = (listelm)->field.le_prev;        \
307     LIST_NEXT((elm), field) = (listelm);                \
308     *(listelm)->field.le_prev = (elm);              \
309     (listelm)->field.le_prev = &LIST_NEXT((elm), field);        \
310 } while (0)
311 
312 #define LIST_INSERT_HEAD(head, elm, field) do {             \
313     if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
314         LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \
315     LIST_FIRST((head)) = (elm);                 \
316     (elm)->field.le_prev = &LIST_FIRST((head));         \
317 } while (0)
318 
319 #define LIST_NEXT(elm, field)   ((elm)->field.le_next)
320 
321 #define LIST_REMOVE(elm, field) do {                    \
322     if (LIST_NEXT((elm), field) != NULL)                \
323         LIST_NEXT((elm), field)->field.le_prev =        \
324             (elm)->field.le_prev;               \
325     *(elm)->field.le_prev = LIST_NEXT((elm), field);        \
326 } while (0)
327 
328 /*
329  * Tail queue declarations.
330  */
331 #define TAILQ_HEAD(name, type)                      \
332 struct name {                               \
333     struct type *tqh_first; /* first element */         \
334     struct type **tqh_last; /* addr of last next element */     \
335 }
336 
337 #define TAILQ_HEAD_INITIALIZER(head)                    \
338     { NULL, &(head).tqh_first }
339 
340 #define TAILQ_ENTRY(type)                       \
341 struct {                                \
342     struct type *tqe_next;  /* next element */          \
343     struct type **tqe_prev; /* address of previous next element */  \
344 }
345 
346 /*
347  * Tail queue functions.
348  */
349 #define TAILQ_EMPTY(head)   ((head)->tqh_first == NULL)
350 
351 #define TAILQ_FIRST(head)   ((head)->tqh_first)
352 
353 #define TAILQ_FOREACH(var, head, field)                 \
354     for ((var) = TAILQ_FIRST((head));               \
355         (var);                          \
356         (var) = TAILQ_NEXT((var), field))
357 
358 #define TAILQ_FOREACH_REVERSE(var, head, headname, field)       \
359     for ((var) = TAILQ_LAST((head), headname);          \
360         (var);                          \
361         (var) = TAILQ_PREV((var), headname, field))
362 
363 #define TAILQ_INIT(head) do {                       \
364     TAILQ_FIRST((head)) = NULL;                 \
365     (head)->tqh_last = &TAILQ_FIRST((head));            \
366 } while (0)
367 
368 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {      \
369     if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL) \
370         TAILQ_NEXT((elm), field)->field.tqe_prev =      \
371             &TAILQ_NEXT((elm), field);              \
372     else                                \
373         (head)->tqh_last = &TAILQ_NEXT((elm), field);       \
374     TAILQ_NEXT((listelm), field) = (elm);               \
375     (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);      \
376 } while (0)
377 
378 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {           \
379     (elm)->field.tqe_prev = (listelm)->field.tqe_prev;      \
380     TAILQ_NEXT((elm), field) = (listelm);               \
381     *(listelm)->field.tqe_prev = (elm);             \
382     (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);      \
383 } while (0)
384 
385 #define TAILQ_INSERT_HEAD(head, elm, field) do {            \
386     if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)   \
387         TAILQ_FIRST((head))->field.tqe_prev =           \
388             &TAILQ_NEXT((elm), field);              \
389     else                                \
390         (head)->tqh_last = &TAILQ_NEXT((elm), field);       \
391     TAILQ_FIRST((head)) = (elm);                    \
392     (elm)->field.tqe_prev = &TAILQ_FIRST((head));           \
393 } while (0)
394 
395 #define TAILQ_INSERT_TAIL(head, elm, field) do {            \
396     TAILQ_NEXT((elm), field) = NULL;                \
397     (elm)->field.tqe_prev = (head)->tqh_last;           \
398     *(head)->tqh_last = (elm);                  \
399     (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
400 } while (0)
401 
402 #define TAILQ_LAST(head, headname)                  \
403     (*(((struct headname *)((head)->tqh_last))->tqh_last))
404 
405 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
406 
407 #define TAILQ_PREV(elm, headname, field)                \
408     (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
409 
410 #define TAILQ_REMOVE(head, elm, field) do {             \
411     if ((TAILQ_NEXT((elm), field)) != NULL)             \
412         TAILQ_NEXT((elm), field)->field.tqe_prev =      \
413             (elm)->field.tqe_prev;              \
414     else                                \
415         (head)->tqh_last = (elm)->field.tqe_prev;       \
416     *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);      \
417 } while (0)
418 
419 /*
420  * Circular queue declarations.
421  */
422 #define CIRCLEQ_HEAD(name, type)                    \
423 struct name {                               \
424     struct type *cqh_first;     /* first element */     \
425     struct type *cqh_last;      /* last element */      \
426 }
427 
428 #define CIRCLEQ_HEAD_INITIALIZER(head)                  \
429     { (void *)&(head), (void *)&(head) }
430 
431 #define CIRCLEQ_ENTRY(type)                     \
432 struct {                                \
433     struct type *cqe_next;      /* next element */      \
434     struct type *cqe_prev;      /* previous element */      \
435 }
436 
437 /*
438  * Circular queue functions.
439  */
440 #define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
441 
442 #define CIRCLEQ_FIRST(head) ((head)->cqh_first)
443 
444 #define CIRCLEQ_FOREACH(var, head, field)               \
445     for ((var) = CIRCLEQ_FIRST((head));             \
446         (var) != (void *)(head) || ((var) = NULL);          \
447         (var) = CIRCLEQ_NEXT((var), field))
448 
449 #define CIRCLEQ_FOREACH_REVERSE(var, head, field)           \
450     for ((var) = CIRCLEQ_LAST((head));              \
451         (var) != (void *)(head) || ((var) = NULL);          \
452         (var) = CIRCLEQ_PREV((var), field))
453 
454 #define CIRCLEQ_INIT(head) do {                     \
455     CIRCLEQ_FIRST((head)) = (void *)(head);             \
456     CIRCLEQ_LAST((head)) = (void *)(head);              \
457 } while (0)
458 
459 #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {        \
460     CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field);    \
461     CIRCLEQ_PREV((elm), field) = (listelm);             \
462     if (CIRCLEQ_NEXT((listelm), field) == (void *)(head))       \
463         CIRCLEQ_LAST((head)) = (elm);               \
464     else                                \
465         CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm); \
466     CIRCLEQ_NEXT((listelm), field) = (elm);             \
467 } while (0)
468 
469 #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {       \
470     CIRCLEQ_NEXT((elm), field) = (listelm);             \
471     CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field);    \
472     if (CIRCLEQ_PREV((listelm), field) == (void *)(head))       \
473         CIRCLEQ_FIRST((head)) = (elm);              \
474     else                                \
475         CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm); \
476     CIRCLEQ_PREV((listelm), field) = (elm);             \
477 } while (0)
478 
479 #define CIRCLEQ_INSERT_HEAD(head, elm, field) do {          \
480     CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head));     \
481     CIRCLEQ_PREV((elm), field) = (void *)(head);            \
482     if (CIRCLEQ_LAST((head)) == (void *)(head))         \
483         CIRCLEQ_LAST((head)) = (elm);               \
484     else                                \
485         CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \
486     CIRCLEQ_FIRST((head)) = (elm);                  \
487 } while (0)
488 
489 #define CIRCLEQ_INSERT_TAIL(head, elm, field) do {          \
490     CIRCLEQ_NEXT((elm), field) = (void *)(head);            \
491     CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head));      \
492     if (CIRCLEQ_FIRST((head)) == (void *)(head))            \
493         CIRCLEQ_FIRST((head)) = (elm);              \
494     else                                \
495         CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm);  \
496     CIRCLEQ_LAST((head)) = (elm);                   \
497 } while (0)
498 
499 #define CIRCLEQ_LAST(head)  ((head)->cqh_last)
500 
501 #define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
502 
503 #define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
504 
505 #define CIRCLEQ_REMOVE(head, elm, field) do {               \
506     if (CIRCLEQ_NEXT((elm), field) == (void *)(head))       \
507         CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field);  \
508     else                                \
509         CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) =   \
510             CIRCLEQ_PREV((elm), field);             \
511     if (CIRCLEQ_PREV((elm), field) == (void *)(head))       \
512         CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \
513     else                                \
514         CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) =   \
515             CIRCLEQ_NEXT((elm), field);             \
516 } while (0)
517 
518 #ifdef __cplusplus
519 }
520 #endif
521 
522 #endif /* !_QUEUE_H_ */