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