1 /*
2  * <sys/queue.h> implementation for systems that don't have it.
3  *
4  * Copyright (c) 1991, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *      @(#)queue.h     8.5 (Berkeley) 8/20/94
32  * $FreeBSD: src/sys/sys/queue.h,v 1.32.2.4 2001/03/31 03:33:39 hsu Exp $
33  */
34 
35 #ifndef SYS_QUEUE_H
36 #define SYS_QUEUE_H
37 
38 /*
39  * This file defines four types of data structures: singly-linked lists,
40  * singly-linked tail queues, lists and tail queues.
41  *
42  * A singly-linked list is headed by a single forward pointer. The elements
43  * are singly linked for minimum space and pointer manipulation overhead at
44  * the expense of O(n) removal for arbitrary elements. New elements can be
45  * added to the list after an existing element or at the head of the list.
46  * Elements being removed from the head of the list should use the explicit
47  * macro for this purpose for optimum efficiency. A singly-linked list may
48  * only be traversed in the forward direction.  Singly-linked lists are ideal
49  * for applications with large datasets and few or no removals or for
50  * implementing a LIFO queue.
51  *
52  * A singly-linked tail queue is headed by a pair of pointers, one to the
53  * head of the list and the other to the tail of the list. The elements are
54  * singly linked for minimum space and pointer manipulation overhead at the
55  * expense of O(n) removal for arbitrary elements. New elements can be added
56  * to the list after an existing element, at the head of the list, or at the
57  * end of the list. Elements being removed from the head of the tail queue
58  * should use the explicit macro for this purpose for optimum efficiency.
59  * A singly-linked tail queue may only be traversed in the forward direction.
60  * Singly-linked tail queues are ideal for applications with large datasets
61  * and few or no removals or for implementing a FIFO queue.
62  *
63  * A list is headed by a single forward pointer (or an array of forward
64  * pointers for a hash table header). The elements are doubly linked
65  * so that an arbitrary element can be removed without a need to
66  * traverse the list. New elements can be added to the list before
67  * or after an existing element or at the head of the list. A list
68  * may only be traversed in the forward direction.
69  *
70  * A tail queue is headed by a pair of pointers, one to the head of the
71  * list and the other to the tail of the list. The elements are doubly
72  * linked so that an arbitrary element can be removed without a need to
73  * traverse the list. New elements can be added to the list before or
74  * after an existing element, at the head of the list, or at the end of
75  * the list. A tail queue may be traversed in either direction.
76  *
77  * For details on the use of these macros, see the queue(3) manual page.
78  *
79  *
80  *                              SLIST   LIST    STAILQ  TAILQ
81  * _HEAD                        +       +       +       +
82  * _HEAD_INITIALIZER            +       +       +       +
83  * _ENTRY                       +       +       +       +
84  * _INIT                        +       +       +       +
85  * _EMPTY                       +       +       +       +
86  * _FIRST                       +       +       +       +
87  * _NEXT                        +       +       +       +
88  * _PREV                        -       -       -       +
89  * _LAST                        -       -       +       +
90  * _FOREACH                     +       +       +       +
91  * _FOREACH_SAFE                +       +       +       +
92  * _FOREACH_REVERSE             -       -       -       +
93  * _FOREACH_REVERSE_SAFE        -       -       -       +
94  * _INSERT_HEAD                 +       +       +       +
95  * _INSERT_BEFORE               -       +       -       +
96  * _INSERT_AFTER                +       +       +       +
97  * _INSERT_TAIL                 -       -       +       +
98  * _CONCAT                      -       -       +       +
99  * _REMOVE_HEAD                 +       -       +       -
100  * _REMOVE                      +       +       +       +
101  *
102  */
103 
104 /*
105  * Singly-linked List declarations.
106  */
107 #define SLIST_HEAD(name, type)                                          \
108 struct name {                                                           \
109         struct type *slh_first; /* first element */                     \
110 }
111 
112 #define SLIST_HEAD_INITIALIZER(head)                                    \
113         { NULL }
114 
115 #define SLIST_ENTRY(type)                                               \
116 struct {                                                                \
117         struct type *sle_next;  /* next element */                      \
118 }
119 
120 /*
121  * Singly-linked List functions.
122  */
123 #define SLIST_EMPTY(head)       ((head)->slh_first == NULL)
124 
125 #define SLIST_FIRST(head)       ((head)->slh_first)
126 
127 #define SLIST_FOREACH(var, head, field)                                 \
128         for ((var) = SLIST_FIRST((head));                               \
129             (var);                                                      \
130             (var) = SLIST_NEXT((var), field))
131 
132 #define SLIST_FOREACH_SAFE(var, head, field, tvar)                      \
133         for ((var) = SLIST_FIRST((head));                               \
134             (var) && ((tvar) = SLIST_NEXT((var), field), 1);            \
135             (var) = (tvar))
136 
137 #define SLIST_FOREACH_PREVPTR(var, varp, head, field)                   \
138         for ((varp) = &SLIST_FIRST((head));                             \
139             ((var) = *(varp)) != NULL;                                  \
140             (varp) = &SLIST_NEXT((var), field))
141 
142 #define SLIST_INIT(head) do {                                           \
143         SLIST_FIRST((head)) = NULL;                                     \
144 } while (0)
145 
146 #define SLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
147         SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);       \
148         SLIST_NEXT((slistelm), field) = (elm);                          \
149 } while (0)
150 
151 #define SLIST_INSERT_HEAD(head, elm, field) do {                        \
152         SLIST_NEXT((elm), field) = SLIST_FIRST((head));                 \
153         SLIST_FIRST((head)) = (elm);                                    \
154 } while (0)
155 
156 #define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
157 
158 #define SLIST_REMOVE(head, elm, type, field) do {                       \
159         if (SLIST_FIRST((head)) == (elm)) {                             \
160                 SLIST_REMOVE_HEAD((head), field);                       \
161         }                                                               \
162         else {                                                          \
163                 struct type *curelm = SLIST_FIRST((head));              \
164                 while (SLIST_NEXT(curelm, field) != (elm))              \
165                         curelm = SLIST_NEXT(curelm, field);             \
166                 SLIST_NEXT(curelm, field) =                             \
167                     SLIST_NEXT(SLIST_NEXT(curelm, field), field);       \
168         }                                                               \
169 } while (0)
170 
171 #define SLIST_REMOVE_HEAD(head, field) do {                             \
172         SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);   \
173 } while (0)
174 
175 /*
176  * Singly-linked Tail queue declarations.
177  */
178 #define STAILQ_HEAD(name, type)                                         \
179 struct name {                                                           \
180         struct type *stqh_first;/* first element */                     \
181         struct type **stqh_last;/* addr of last next element */         \
182 }
183 
184 #define STAILQ_HEAD_INITIALIZER(head)                                   \
185         { NULL, &(head).stqh_first }
186 
187 #define STAILQ_ENTRY(type)                                              \
188 struct {                                                                \
189         struct type *stqe_next; /* next element */                      \
190 }
191 
192 /*
193  * Singly-linked Tail queue functions.
194  */
195 #define STAILQ_CONCAT(head1, head2) do {                                \
196         if (!STAILQ_EMPTY((head2))) {                                   \
197                 *(head1)->stqh_last = (head2)->stqh_first;              \
198                 (head1)->stqh_last = (head2)->stqh_last;                \
199                 STAILQ_INIT((head2));                                   \
200         }                                                               \
201 } while (0)
202 
203 #define STAILQ_EMPTY(head)      ((head)->stqh_first == NULL)
204 
205 #define STAILQ_FIRST(head)      ((head)->stqh_first)
206 
207 #define STAILQ_FOREACH(var, head, field)                                \
208         for((var) = STAILQ_FIRST((head));                               \
209            (var);                                                       \
210            (var) = STAILQ_NEXT((var), field))
211 
212 
213 #define STAILQ_FOREACH_SAFE(var, head, field, tvar)                     \
214         for ((var) = STAILQ_FIRST((head));                              \
215             (var) && ((tvar) = STAILQ_NEXT((var), field), 1);           \
216             (var) = (tvar))
217 
218 #define STAILQ_INIT(head) do {                                          \
219         STAILQ_FIRST((head)) = NULL;                                    \
220         (head)->stqh_last = &STAILQ_FIRST((head));                      \
221 } while (0)
222 
223 #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {               \
224         if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
225                 (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
226         STAILQ_NEXT((tqelm), field) = (elm);                            \
227 } while (0)
228 
229 #define STAILQ_INSERT_HEAD(head, elm, field) do {                       \
230         if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
231                 (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
232         STAILQ_FIRST((head)) = (elm);                                   \
233 } while (0)
234 
235 #define STAILQ_INSERT_TAIL(head, elm, field) do {                       \
236         STAILQ_NEXT((elm), field) = NULL;                               \
237         *(head)->stqh_last = (elm);                                     \
238         (head)->stqh_last = &STAILQ_NEXT((elm), field);                 \
239 } while (0)
240 
241 #define STAILQ_LAST(head, type, field)                                  \
242         (STAILQ_EMPTY((head)) ?                                         \
243                 NULL :                                                  \
244                 ((struct type *)                                        \
245                 ((char *)((head)->stqh_last) - offsetof(struct type, field))))
246 
247 #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
248 
249 #define STAILQ_REMOVE(head, elm, type, field) do {                      \
250         if (STAILQ_FIRST((head)) == (elm)) {                            \
251                 STAILQ_REMOVE_HEAD((head), field);                      \
252         }                                                               \
253         else {                                                          \
254                 struct type *curelm = STAILQ_FIRST((head));             \
255                 while (STAILQ_NEXT(curelm, field) != (elm))             \
256                         curelm = STAILQ_NEXT(curelm, field);            \
257                 if ((STAILQ_NEXT(curelm, field) =                       \
258                      STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
259                         (head)->stqh_last = &STAILQ_NEXT((curelm), field);\
260         }                                                               \
261 } while (0)
262 
263 #define STAILQ_REMOVE_HEAD(head, field) do {                            \
264         if ((STAILQ_FIRST((head)) =                                     \
265              STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)         \
266                 (head)->stqh_last = &STAILQ_FIRST((head));              \
267 } while (0)
268 
269 #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {                 \
270         if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
271                 (head)->stqh_last = &STAILQ_FIRST((head));              \
272 } while (0)
273 
274 /*
275  * List declarations.
276  */
277 #define LIST_HEAD(name, type)                                           \
278 struct name {                                                           \
279         struct type *lh_first;  /* first element */                     \
280 }
281 
282 #define LIST_HEAD_INITIALIZER(head)                                     \
283         { NULL }
284 
285 #define LIST_ENTRY(type)                                                \
286 struct {                                                                \
287         struct type *le_next;   /* next element */                      \
288         struct type **le_prev;  /* address of previous next element */  \
289 }
290 
291 /*
292  * List functions.
293  */
294 
295 #define LIST_EMPTY(head)        ((head)->lh_first == NULL)
296 
297 #define LIST_FIRST(head)        ((head)->lh_first)
298 
299 #define LIST_FOREACH(var, head, field)                                  \
300         for ((var) = LIST_FIRST((head));                                \
301             (var);                                                      \
302             (var) = LIST_NEXT((var), field))
303 
304 #define LIST_FOREACH_SAFE(var, head, field, tvar)                       \
305         for ((var) = LIST_FIRST((head));                                \
306             (var) && ((tvar) = LIST_NEXT((var), field), 1);             \
307             (var) = (tvar))
308 
309 #define LIST_INIT(head) do {                                            \
310         LIST_FIRST((head)) = NULL;                                      \
311 } while (0)
312 
313 #define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
314         if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
315                 LIST_NEXT((listelm), field)->field.le_prev =            \
316                     &LIST_NEXT((elm), field);                           \
317         LIST_NEXT((listelm), field) = (elm);                            \
318         (elm)->field.le_prev = &LIST_NEXT((listelm), field);            \
319 } while (0)
320 
321 #define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
322         (elm)->field.le_prev = (listelm)->field.le_prev;                \
323         LIST_NEXT((elm), field) = (listelm);                            \
324         *(listelm)->field.le_prev = (elm);                              \
325         (listelm)->field.le_prev = &LIST_NEXT((elm), field);            \
326 } while (0)
327 
328 #define LIST_INSERT_HEAD(head, elm, field) do {                         \
329         if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)     \
330                 LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
331         LIST_FIRST((head)) = (elm);                                     \
332         (elm)->field.le_prev = &LIST_FIRST((head));                     \
333 } while (0)
334 
335 #define LIST_NEXT(elm, field)   ((elm)->field.le_next)
336 
337 #define LIST_REMOVE(elm, field) do {                                    \
338         if (LIST_NEXT((elm), field) != NULL)                            \
339                 LIST_NEXT((elm), field)->field.le_prev =                \
340                     (elm)->field.le_prev;                               \
341         *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
342 } while (0)
343 
344 /*
345  * Tail queue declarations.
346  */
347 #define TAILQ_HEAD(name, type)                                          \
348 struct name {                                                           \
349         struct type *tqh_first; /* first element */                     \
350         struct type **tqh_last; /* addr of last next element */         \
351 }
352 
353 #define TAILQ_HEAD_INITIALIZER(head)                                    \
354         { NULL, &(head).tqh_first }
355 
356 #define TAILQ_ENTRY(type)                                               \
357 struct {                                                                \
358         struct type *tqe_next;  /* next element */                      \
359         struct type **tqe_prev; /* address of previous next element */  \
360 }
361 
362 /*
363  * Tail queue functions.
364  */
365 #define TAILQ_CONCAT(head1, head2, field) do {                          \
366         if (!TAILQ_EMPTY(head2)) {                                      \
367                 *(head1)->tqh_last = (head2)->tqh_first;                \
368                 (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
369                 (head1)->tqh_last = (head2)->tqh_last;                  \
370                 TAILQ_INIT((head2));                                    \
371         }                                                               \
372 } while (0)
373 
374 #define TAILQ_EMPTY(head)       ((head)->tqh_first == NULL)
375 
376 #define TAILQ_FIRST(head)       ((head)->tqh_first)
377 
378 #define TAILQ_FOREACH(var, head, field)                                 \
379         for ((var) = TAILQ_FIRST((head));                               \
380             (var);                                                      \
381             (var) = TAILQ_NEXT((var), field))
382 
383 #define TAILQ_FOREACH_SAFE(var, head, field, tvar)                      \
384         for ((var) = TAILQ_FIRST((head));                               \
385             (var) && ((tvar) = TAILQ_NEXT((var), field), 1);            \
386             (var) = (tvar))
387 
388 #define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
389         for ((var) = TAILQ_LAST((head), headname);                      \
390             (var);                                                      \
391             (var) = TAILQ_PREV((var), headname, field))
392 
393 #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)    \
394         for ((var) = TAILQ_LAST((head), headname);                      \
395             (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);  \
396             (var) = (tvar))
397 
398 #define TAILQ_INIT(head) do {                                           \
399         TAILQ_FIRST((head)) = NULL;                                     \
400         (head)->tqh_last = &TAILQ_FIRST((head));                        \
401 } while (0)
402 
403 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
404         if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
405                 TAILQ_NEXT((elm), field)->field.tqe_prev =              \
406                     &TAILQ_NEXT((elm), field);                          \
407         else {                                                          \
408                 (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
409         }                                                               \
410         TAILQ_NEXT((listelm), field) = (elm);                           \
411         (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);          \
412 } while (0)
413 
414 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
415         (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
416         TAILQ_NEXT((elm), field) = (listelm);                           \
417         *(listelm)->field.tqe_prev = (elm);                             \
418         (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);          \
419 } while (0)
420 
421 #define TAILQ_INSERT_HEAD(head, elm, field) do {                        \
422         if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)   \
423                 TAILQ_FIRST((head))->field.tqe_prev =                   \
424                     &TAILQ_NEXT((elm), field);                          \
425         else                                                            \
426                 (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
427         TAILQ_FIRST((head)) = (elm);                                    \
428         (elm)->field.tqe_prev = &TAILQ_FIRST((head));                   \
429 } while (0)
430 
431 #define TAILQ_INSERT_TAIL(head, elm, field) do {                        \
432         TAILQ_NEXT((elm), field) = NULL;                                \
433         (elm)->field.tqe_prev = (head)->tqh_last;                       \
434         *(head)->tqh_last = (elm);                                      \
435         (head)->tqh_last = &TAILQ_NEXT((elm), field);                   \
436 } while (0)
437 
438 #define TAILQ_LAST(head, headname)                                      \
439         (*(((struct headname *)((head)->tqh_last))->tqh_last))
440 
441 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
442 
443 #define TAILQ_PREV(elm, headname, field)                                \
444         (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
445 
446 #define TAILQ_REMOVE(head, elm, field) do {                             \
447         if ((TAILQ_NEXT((elm), field)) != NULL)                         \
448                 TAILQ_NEXT((elm), field)->field.tqe_prev =              \
449                     (elm)->field.tqe_prev;                              \
450         else {                                                          \
451                 (head)->tqh_last = (elm)->field.tqe_prev;               \
452         }                                                               \
453         *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);              \
454 } while (0)
455 
456 #endif /* !SYS_QUEUE_H */
457