Asterisk - The Open Source Telephony Project  18.5.0
queue.h
Go to the documentation of this file.
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  * 3. All advertising materials mentioning features or use of this software
14  * must display the following acknowledgement:
15  * This product includes software developed by the University of
16  * California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  * may be used to endorse or promote products derived from this software
19  * without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * @(#)queue.h 8.5 (Berkeley) 8/20/94
34  * $FreeBSD: src/sys/sys/queue.h,v 1.24.2.4 2000/05/05 01:41:41 archie Exp $
35  */
36 
37 #ifndef _SYS_QUEUE_H_
38 #define _SYS_QUEUE_H_
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  * _ENTRY + + + + +
93  * _INIT + + + + +
94  * _EMPTY + + + + +
95  * _FIRST + + + + +
96  * _NEXT + + + + +
97  * _PREV - - - + +
98  * _LAST - - + + +
99  * _FOREACH + + + + +
100  * _FOREACH_REVERSE - - - + +
101  * _INSERT_HEAD + + + + +
102  * _INSERT_BEFORE - + - + +
103  * _INSERT_AFTER + + + + +
104  * _INSERT_TAIL - - + + +
105  * _REMOVE_HEAD + - + - -
106  * _REMOVE + + + + +
107  *
108  */
109 
110 /*
111  * Singly-linked List definitions.
112  */
113 #define SLIST_HEAD(name, type) \
114 struct name { \
115  struct type *slh_first; /* first element */ \
116 }
117 
118 #define SLIST_HEAD_INITIALIZER(head) \
119  { NULL }
120 
121 #define SLIST_ENTRY(type) \
122 struct { \
123  struct type *sle_next; /* next element */ \
124 }
125 
126 /*
127  * Singly-linked List functions.
128  */
129 #define SLIST_EMPTY(head) ((head)->slh_first == NULL)
130 
131 #define SLIST_FIRST(head) ((head)->slh_first)
132 
133 #define SLIST_FOREACH(var, head, field) \
134  for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
135 
136 #define SLIST_INIT(head) { \
137  (head)->slh_first = NULL; \
138 }
139 
140 #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
141  (elm)->field.sle_next = (slistelm)->field.sle_next; \
142  (slistelm)->field.sle_next = (elm); \
143 } while (0)
144 
145 #define SLIST_INSERT_HEAD(head, elm, field) do { \
146  (elm)->field.sle_next = (head)->slh_first; \
147  (head)->slh_first = (elm); \
148 } while (0)
149 
150 #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
151 
152 #define SLIST_REMOVE_HEAD(head, field) do { \
153  (head)->slh_first = (head)->slh_first->field.sle_next; \
154 } while (0)
155 
156 #define SLIST_REMOVE(head, elm, type, field) do { \
157  if ((head)->slh_first == (elm)) { \
158  SLIST_REMOVE_HEAD((head), field); \
159  } \
160  else { \
161  struct type *curelm = (head)->slh_first; \
162  while( curelm->field.sle_next != (elm) ) \
163  curelm = curelm->field.sle_next; \
164  curelm->field.sle_next = \
165  curelm->field.sle_next->field.sle_next; \
166  } \
167 } while (0)
168 
169 /*
170  * Singly-linked Tail queue definitions.
171  */
172 #define STAILQ_HEAD(name, type) \
173 struct name { \
174  struct type *stqh_first;/* first element */ \
175  struct type **stqh_last;/* addr of last next element */ \
176 }
177 
178 #define STAILQ_HEAD_INITIALIZER(head) \
179  { NULL, &(head).stqh_first }
180 
181 #define STAILQ_ENTRY(type) \
182 struct { \
183  struct type *stqe_next; /* next element */ \
184 }
185 
186 /*
187  * Singly-linked Tail queue functions.
188  */
189 #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
190 
191 #define STAILQ_INIT(head) do { \
192  (head)->stqh_first = NULL; \
193  (head)->stqh_last = &(head)->stqh_first; \
194 } while (0)
195 
196 #define STAILQ_FIRST(head) ((head)->stqh_first)
197 #define STAILQ_LAST(head) (*(head)->stqh_last)
198 
199 #define STAILQ_FOREACH(var, head, field) \
200  for((var) = (head)->stqh_first; (var); (var) = (var)->field.stqe_next)
201 
202 #define STAILQ_INSERT_HEAD(head, elm, field) do { \
203  if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
204  (head)->stqh_last = &(elm)->field.stqe_next; \
205  (head)->stqh_first = (elm); \
206 } while (0)
207 
208 #define STAILQ_INSERT_TAIL(head, elm, field) do { \
209  (elm)->field.stqe_next = NULL; \
210  *(head)->stqh_last = (elm); \
211  (head)->stqh_last = &(elm)->field.stqe_next; \
212 } while (0)
213 
214 #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
215  if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\
216  (head)->stqh_last = &(elm)->field.stqe_next; \
217  (tqelm)->field.stqe_next = (elm); \
218 } while (0)
219 
220 #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
221 
222 #define STAILQ_REMOVE_HEAD(head, field) do { \
223  if (((head)->stqh_first = \
224  (head)->stqh_first->field.stqe_next) == NULL) \
225  (head)->stqh_last = &(head)->stqh_first; \
226 } while (0)
227 
228 #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
229  if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \
230  (head)->stqh_last = &(head)->stqh_first; \
231 } while (0)
232 
233 #define STAILQ_REMOVE(head, elm, type, field) do { \
234  if ((head)->stqh_first == (elm)) { \
235  STAILQ_REMOVE_HEAD(head, field); \
236  } \
237  else { \
238  struct type *curelm = (head)->stqh_first; \
239  while( curelm->field.stqe_next != (elm) ) \
240  curelm = curelm->field.stqe_next; \
241  if((curelm->field.stqe_next = \
242  curelm->field.stqe_next->field.stqe_next) == NULL) \
243  (head)->stqh_last = &(curelm)->field.stqe_next; \
244  } \
245 } while (0)
246 
247 /*
248  * List definitions.
249  */
250 #define LIST_HEAD(name, type) \
251 struct name { \
252  struct type *lh_first; /* first element */ \
253 }
254 
255 #define LIST_HEAD_INITIALIZER(head) \
256  { NULL }
257 
258 #define LIST_ENTRY(type) \
259 struct { \
260  struct type *le_next; /* next element */ \
261  struct type **le_prev; /* address of previous next element */ \
262 }
263 
264 /*
265  * List functions.
266  */
267 
268 #define LIST_EMPTY(head) ((head)->lh_first == NULL)
269 
270 #define LIST_FIRST(head) ((head)->lh_first)
271 
272 #define LIST_FOREACH(var, head, field) \
273  for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next)
274 
275 #define LIST_INIT(head) do { \
276  (head)->lh_first = NULL; \
277 } while (0)
278 
279 #define LIST_INSERT_AFTER(listelm, elm, field) do { \
280  if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
281  (listelm)->field.le_next->field.le_prev = \
282  &(elm)->field.le_next; \
283  (listelm)->field.le_next = (elm); \
284  (elm)->field.le_prev = &(listelm)->field.le_next; \
285 } while (0)
286 
287 #define LIST_INSERT_BEFORE(listelm, elm, field) do { \
288  (elm)->field.le_prev = (listelm)->field.le_prev; \
289  (elm)->field.le_next = (listelm); \
290  *(listelm)->field.le_prev = (elm); \
291  (listelm)->field.le_prev = &(elm)->field.le_next; \
292 } while (0)
293 
294 #define LIST_INSERT_HEAD(head, elm, field) do { \
295  if (((elm)->field.le_next = (head)->lh_first) != NULL) \
296  (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
297  (head)->lh_first = (elm); \
298  (elm)->field.le_prev = &(head)->lh_first; \
299 } while (0)
300 
301 #define LIST_NEXT(elm, field) ((elm)->field.le_next)
302 
303 #define LIST_REMOVE(elm, field) do { \
304  if ((elm)->field.le_next != NULL) \
305  (elm)->field.le_next->field.le_prev = \
306  (elm)->field.le_prev; \
307  *(elm)->field.le_prev = (elm)->field.le_next; \
308 } while (0)
309 
310 /*
311  * Tail queue definitions.
312  */
313 #define TAILQ_HEAD(name, type) \
314 struct name { \
315  struct type *tqh_first; /* first element */ \
316  struct type **tqh_last; /* addr of last next element */ \
317 }
318 
319 #define TAILQ_HEAD_INITIALIZER(head) \
320  { NULL, &(head).tqh_first }
321 
322 #define TAILQ_ENTRY(type) \
323 struct { \
324  struct type *tqe_next; /* next element */ \
325  struct type **tqe_prev; /* address of previous next element */ \
326 }
327 
328 /*
329  * Tail queue functions.
330  */
331 #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
332 
333 #define TAILQ_FOREACH(var, head, field) \
334  for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field))
335 
336 #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
337  for ((var) = TAILQ_LAST((head), headname); \
338  (var); \
339  (var) = TAILQ_PREV((var), headname, field))
340 
341 #define TAILQ_FIRST(head) ((head)->tqh_first)
342 
343 #define TAILQ_LAST(head, headname) \
344  (*(((struct headname *)((head)->tqh_last))->tqh_last))
345 
346 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
347 
348 #define TAILQ_PREV(elm, headname, field) \
349  (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
350 
351 #define TAILQ_INIT(head) do { \
352  (head)->tqh_first = NULL; \
353  (head)->tqh_last = &(head)->tqh_first; \
354 } while (0)
355 
356 #define TAILQ_INSERT_HEAD(head, elm, field) do { \
357  if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
358  (head)->tqh_first->field.tqe_prev = \
359  &(elm)->field.tqe_next; \
360  else \
361  (head)->tqh_last = &(elm)->field.tqe_next; \
362  (head)->tqh_first = (elm); \
363  (elm)->field.tqe_prev = &(head)->tqh_first; \
364 } while (0)
365 
366 #define TAILQ_INSERT_TAIL(head, elm, field) do { \
367  (elm)->field.tqe_next = NULL; \
368  (elm)->field.tqe_prev = (head)->tqh_last; \
369  *(head)->tqh_last = (elm); \
370  (head)->tqh_last = &(elm)->field.tqe_next; \
371 } while (0)
372 
373 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
374  if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
375  (elm)->field.tqe_next->field.tqe_prev = \
376  &(elm)->field.tqe_next; \
377  else \
378  (head)->tqh_last = &(elm)->field.tqe_next; \
379  (listelm)->field.tqe_next = (elm); \
380  (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
381 } while (0)
382 
383 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
384  (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
385  (elm)->field.tqe_next = (listelm); \
386  *(listelm)->field.tqe_prev = (elm); \
387  (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
388 } while (0)
389 
390 #define TAILQ_REMOVE(head, elm, field) do { \
391  if (((elm)->field.tqe_next) != NULL) \
392  (elm)->field.tqe_next->field.tqe_prev = \
393  (elm)->field.tqe_prev; \
394  else \
395  (head)->tqh_last = (elm)->field.tqe_prev; \
396  *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
397 } while (0)
398 
399 /*
400  * Circular queue definitions.
401  */
402 #define CIRCLEQ_HEAD(name, type) \
403 struct name { \
404  struct type *cqh_first; /* first element */ \
405  struct type *cqh_last; /* last element */ \
406 }
407 
408 #define CIRCLEQ_ENTRY(type) \
409 struct { \
410  struct type *cqe_next; /* next element */ \
411  struct type *cqe_prev; /* previous element */ \
412 }
413 
414 /*
415  * Circular queue functions.
416  */
417 #define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
418 
419 #define CIRCLEQ_FIRST(head) ((head)->cqh_first)
420 
421 #define CIRCLEQ_FOREACH(var, head, field) \
422  for((var) = (head)->cqh_first; \
423  (var) != (void *)(head); \
424  (var) = (var)->field.cqe_next)
425 
426 #define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
427  for((var) = (head)->cqh_last; \
428  (var) != (void *)(head); \
429  (var) = (var)->field.cqe_prev)
430 
431 #define CIRCLEQ_INIT(head) do { \
432  (head)->cqh_first = (void *)(head); \
433  (head)->cqh_last = (void *)(head); \
434 } while (0)
435 
436 #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
437  (elm)->field.cqe_next = (listelm)->field.cqe_next; \
438  (elm)->field.cqe_prev = (listelm); \
439  if ((listelm)->field.cqe_next == (void *)(head)) \
440  (head)->cqh_last = (elm); \
441  else \
442  (listelm)->field.cqe_next->field.cqe_prev = (elm); \
443  (listelm)->field.cqe_next = (elm); \
444 } while (0)
445 
446 #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
447  (elm)->field.cqe_next = (listelm); \
448  (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
449  if ((listelm)->field.cqe_prev == (void *)(head)) \
450  (head)->cqh_first = (elm); \
451  else \
452  (listelm)->field.cqe_prev->field.cqe_next = (elm); \
453  (listelm)->field.cqe_prev = (elm); \
454 } while (0)
455 
456 #define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
457  (elm)->field.cqe_next = (head)->cqh_first; \
458  (elm)->field.cqe_prev = (void *)(head); \
459  if ((head)->cqh_last == (void *)(head)) \
460  (head)->cqh_last = (elm); \
461  else \
462  (head)->cqh_first->field.cqe_prev = (elm); \
463  (head)->cqh_first = (elm); \
464 } while (0)
465 
466 #define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
467  (elm)->field.cqe_next = (void *)(head); \
468  (elm)->field.cqe_prev = (head)->cqh_last; \
469  if ((head)->cqh_first == (void *)(head)) \
470  (head)->cqh_first = (elm); \
471  else \
472  (head)->cqh_last->field.cqe_next = (elm); \
473  (head)->cqh_last = (elm); \
474 } while (0)
475 
476 #define CIRCLEQ_LAST(head) ((head)->cqh_last)
477 
478 #define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
479 
480 #define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
481 
482 #define CIRCLEQ_REMOVE(head, elm, field) do { \
483  if ((elm)->field.cqe_next == (void *)(head)) \
484  (head)->cqh_last = (elm)->field.cqe_prev; \
485  else \
486  (elm)->field.cqe_next->field.cqe_prev = \
487  (elm)->field.cqe_prev; \
488  if ((elm)->field.cqe_prev == (void *)(head)) \
489  (head)->cqh_first = (elm)->field.cqe_next; \
490  else \
491  (elm)->field.cqe_prev->field.cqe_next = \
492  (elm)->field.cqe_next; \
493 } while (0)
494 
495 #ifdef KERNEL
496 
497 /*
498  * XXX insque() and remque() are an old way of handling certain queues.
499  * They bogusly assumes that all queue heads look alike.
500  */
501 
502 struct quehead {
503  struct quehead *qh_link;
504  struct quehead *qh_rlink;
505 };
506 
507 #ifdef __GNUC__
508 
509 static __inline void
510 insque(void *a, void *b)
511 {
512  struct quehead *element = a, *head = b;
513 
514  element->qh_link = head->qh_link;
515  element->qh_rlink = head;
516  head->qh_link = element;
517  element->qh_link->qh_rlink = element;
518 }
519 
520 static __inline void
521 remque(void *a)
522 {
523  struct quehead *element = a;
524 
525  element->qh_link->qh_rlink = element->qh_rlink;
526  element->qh_rlink->qh_link = element->qh_link;
527  element->qh_rlink = 0;
528 }
529 
530 #else /* !__GNUC__ */
531 
532 void insque __P((void *a, void *b));
533 void remque __P((void *a));
534 
535 #endif /* __GNUC__ */
536 
537 #endif /* KERNEL */
538 
539 #endif /* !_SYS_QUEUE_H_ */
#define __P(p)
static struct test_val b
static struct test_val a