Annotation of embedaddon/pimd/libite/queue.h, revision 1.1.1.1
1.1 misho 1: /* $OpenBSD: queue.h,v 1.43 2015/12/28 19:38:40 millert 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: /*
39: * This file defines five types of data structures: singly-linked lists,
40: * lists, simple queues, tail queues and XOR simple 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 to 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: * An XOR simple queue is used in the same way as a regular simple queue.
75: * The difference is that the head structure also includes a "cookie" that
76: * is XOR'd with the queue pointer (first, last or next) to generate the
77: * real pointer value.
78: *
79: * For details on the use of these macros, see the queue(3) manual page.
80: */
81:
82: #if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
83: #define _Q_INVALIDATE(a) (a) = ((void *)-1)
84: #else
85: #define _Q_INVALIDATE(a)
86: #endif
87:
88: /*
89: * Singly-linked List definitions.
90: */
91: #define SLIST_HEAD(name, type) \
92: struct name { \
93: struct type *slh_first; /* first element */ \
94: }
95:
96: #define SLIST_HEAD_INITIALIZER(head) \
97: { NULL }
98:
99: #define SLIST_ENTRY(type) \
100: struct { \
101: struct type *sle_next; /* next element */ \
102: }
103:
104: /*
105: * Singly-linked List access methods.
106: */
107: #define SLIST_FIRST(head) ((head)->slh_first)
108: #define SLIST_END(head) NULL
109: #define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
110: #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
111:
112: #define SLIST_FOREACH(var, head, field) \
113: for((var) = SLIST_FIRST(head); \
114: (var) != SLIST_END(head); \
115: (var) = SLIST_NEXT(var, field))
116:
117: #define SLIST_FOREACH_SAFE(var, head, field, tvar) \
118: for ((var) = SLIST_FIRST(head); \
119: (var) && ((tvar) = SLIST_NEXT(var, field), 1); \
120: (var) = (tvar))
121:
122: /*
123: * Singly-linked List functions.
124: */
125: #define SLIST_INIT(head) { \
126: SLIST_FIRST(head) = SLIST_END(head); \
127: }
128:
129: #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
130: (elm)->field.sle_next = (slistelm)->field.sle_next; \
131: (slistelm)->field.sle_next = (elm); \
132: } while (0)
133:
134: #define SLIST_INSERT_HEAD(head, elm, field) do { \
135: (elm)->field.sle_next = (head)->slh_first; \
136: (head)->slh_first = (elm); \
137: } while (0)
138:
139: #define SLIST_REMOVE_AFTER(elm, field) do { \
140: (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
141: } while (0)
142:
143: #define SLIST_REMOVE_HEAD(head, field) do { \
144: (head)->slh_first = (head)->slh_first->field.sle_next; \
145: } while (0)
146:
147: #define SLIST_REMOVE(head, elm, type, field) do { \
148: if ((head)->slh_first == (elm)) { \
149: SLIST_REMOVE_HEAD((head), field); \
150: } else { \
151: struct type *curelm = (head)->slh_first; \
152: \
153: while (curelm->field.sle_next != (elm)) \
154: curelm = curelm->field.sle_next; \
155: curelm->field.sle_next = \
156: curelm->field.sle_next->field.sle_next; \
157: } \
158: _Q_INVALIDATE((elm)->field.sle_next); \
159: } while (0)
160:
161: /*
162: * List definitions.
163: */
164: #define LIST_HEAD(name, type) \
165: struct name { \
166: struct type *lh_first; /* first element */ \
167: }
168:
169: #define LIST_HEAD_INITIALIZER(head) \
170: { NULL }
171:
172: #define LIST_ENTRY(type) \
173: struct { \
174: struct type *le_next; /* next element */ \
175: struct type **le_prev; /* address of previous next element */ \
176: }
177:
178: /*
179: * List access methods.
180: */
181: #define LIST_FIRST(head) ((head)->lh_first)
182: #define LIST_END(head) NULL
183: #define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
184: #define LIST_NEXT(elm, field) ((elm)->field.le_next)
185:
186: #define LIST_FOREACH(var, head, field) \
187: for((var) = LIST_FIRST(head); \
188: (var)!= LIST_END(head); \
189: (var) = LIST_NEXT(var, field))
190:
191: #define LIST_FOREACH_SAFE(var, head, field, tvar) \
192: for ((var) = LIST_FIRST(head); \
193: (var) && ((tvar) = LIST_NEXT(var, field), 1); \
194: (var) = (tvar))
195:
196: /*
197: * List functions.
198: */
199: #define LIST_INIT(head) do { \
200: LIST_FIRST(head) = LIST_END(head); \
201: } while (0)
202:
203: #define LIST_INSERT_AFTER(listelm, elm, field) do { \
204: if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
205: (listelm)->field.le_next->field.le_prev = \
206: &(elm)->field.le_next; \
207: (listelm)->field.le_next = (elm); \
208: (elm)->field.le_prev = &(listelm)->field.le_next; \
209: } while (0)
210:
211: #define LIST_INSERT_BEFORE(listelm, elm, field) do { \
212: (elm)->field.le_prev = (listelm)->field.le_prev; \
213: (elm)->field.le_next = (listelm); \
214: *(listelm)->field.le_prev = (elm); \
215: (listelm)->field.le_prev = &(elm)->field.le_next; \
216: } while (0)
217:
218: #define LIST_INSERT_HEAD(head, elm, field) do { \
219: if (((elm)->field.le_next = (head)->lh_first) != NULL) \
220: (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
221: (head)->lh_first = (elm); \
222: (elm)->field.le_prev = &(head)->lh_first; \
223: } while (0)
224:
225: #define LIST_REMOVE(elm, field) do { \
226: if ((elm)->field.le_next != NULL) \
227: (elm)->field.le_next->field.le_prev = \
228: (elm)->field.le_prev; \
229: *(elm)->field.le_prev = (elm)->field.le_next; \
230: _Q_INVALIDATE((elm)->field.le_prev); \
231: _Q_INVALIDATE((elm)->field.le_next); \
232: } while (0)
233:
234: #define LIST_REPLACE(elm, elm2, field) do { \
235: if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
236: (elm2)->field.le_next->field.le_prev = \
237: &(elm2)->field.le_next; \
238: (elm2)->field.le_prev = (elm)->field.le_prev; \
239: *(elm2)->field.le_prev = (elm2); \
240: _Q_INVALIDATE((elm)->field.le_prev); \
241: _Q_INVALIDATE((elm)->field.le_next); \
242: } while (0)
243:
244: /*
245: * Simple queue definitions.
246: */
247: #define SIMPLEQ_HEAD(name, type) \
248: struct name { \
249: struct type *sqh_first; /* first element */ \
250: struct type **sqh_last; /* addr of last next element */ \
251: }
252:
253: #define SIMPLEQ_HEAD_INITIALIZER(head) \
254: { NULL, &(head).sqh_first }
255:
256: #define SIMPLEQ_ENTRY(type) \
257: struct { \
258: struct type *sqe_next; /* next element */ \
259: }
260:
261: /*
262: * Simple queue access methods.
263: */
264: #define SIMPLEQ_FIRST(head) ((head)->sqh_first)
265: #define SIMPLEQ_END(head) NULL
266: #define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
267: #define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
268:
269: #define SIMPLEQ_FOREACH(var, head, field) \
270: for((var) = SIMPLEQ_FIRST(head); \
271: (var) != SIMPLEQ_END(head); \
272: (var) = SIMPLEQ_NEXT(var, field))
273:
274: #define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
275: for ((var) = SIMPLEQ_FIRST(head); \
276: (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
277: (var) = (tvar))
278:
279: /*
280: * Simple queue functions.
281: */
282: #define SIMPLEQ_INIT(head) do { \
283: (head)->sqh_first = NULL; \
284: (head)->sqh_last = &(head)->sqh_first; \
285: } while (0)
286:
287: #define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
288: if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
289: (head)->sqh_last = &(elm)->field.sqe_next; \
290: (head)->sqh_first = (elm); \
291: } while (0)
292:
293: #define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
294: (elm)->field.sqe_next = NULL; \
295: *(head)->sqh_last = (elm); \
296: (head)->sqh_last = &(elm)->field.sqe_next; \
297: } while (0)
298:
299: #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
300: if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
301: (head)->sqh_last = &(elm)->field.sqe_next; \
302: (listelm)->field.sqe_next = (elm); \
303: } while (0)
304:
305: #define SIMPLEQ_REMOVE_HEAD(head, field) do { \
306: if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
307: (head)->sqh_last = &(head)->sqh_first; \
308: } while (0)
309:
310: #define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
311: if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
312: == NULL) \
313: (head)->sqh_last = &(elm)->field.sqe_next; \
314: } while (0)
315:
316: #define SIMPLEQ_CONCAT(head1, head2) do { \
317: if (!SIMPLEQ_EMPTY((head2))) { \
318: *(head1)->sqh_last = (head2)->sqh_first; \
319: (head1)->sqh_last = (head2)->sqh_last; \
320: SIMPLEQ_INIT((head2)); \
321: } \
322: } while (0)
323:
324: /*
325: * XOR Simple queue definitions.
326: */
327: #define XSIMPLEQ_HEAD(name, type) \
328: struct name { \
329: struct type *sqx_first; /* first element */ \
330: struct type **sqx_last; /* addr of last next element */ \
331: unsigned long sqx_cookie; \
332: }
333:
334: #define XSIMPLEQ_ENTRY(type) \
335: struct { \
336: struct type *sqx_next; /* next element */ \
337: }
338:
339: /*
340: * XOR Simple queue access methods.
341: */
342: #define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \
343: (unsigned long)(ptr)))
344: #define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first))
345: #define XSIMPLEQ_END(head) NULL
346: #define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
347: #define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
348:
349:
350: #define XSIMPLEQ_FOREACH(var, head, field) \
351: for ((var) = XSIMPLEQ_FIRST(head); \
352: (var) != XSIMPLEQ_END(head); \
353: (var) = XSIMPLEQ_NEXT(head, var, field))
354:
355: #define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
356: for ((var) = XSIMPLEQ_FIRST(head); \
357: (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
358: (var) = (tvar))
359:
360: /*
361: * XOR Simple queue functions.
362: */
363: #define XSIMPLEQ_INIT(head) do { \
364: arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
365: (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \
366: (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
367: } while (0)
368:
369: #define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
370: if (((elm)->field.sqx_next = (head)->sqx_first) == \
371: XSIMPLEQ_XOR(head, NULL)) \
372: (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
373: (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \
374: } while (0)
375:
376: #define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
377: (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \
378: *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
379: (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
380: } while (0)
381:
382: #define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
383: if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \
384: XSIMPLEQ_XOR(head, NULL)) \
385: (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
386: (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \
387: } while (0)
388:
389: #define XSIMPLEQ_REMOVE_HEAD(head, field) do { \
390: if (((head)->sqx_first = XSIMPLEQ_XOR(head, \
391: (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
392: (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
393: } while (0)
394:
395: #define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
396: if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \
397: (elm)->field.sqx_next)->field.sqx_next) \
398: == XSIMPLEQ_XOR(head, NULL)) \
399: (head)->sqx_last = \
400: XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
401: } while (0)
402:
403:
404: /*
405: * Tail queue definitions.
406: */
407: #define TAILQ_HEAD(name, type) \
408: struct name { \
409: struct type *tqh_first; /* first element */ \
410: struct type **tqh_last; /* addr of last next element */ \
411: }
412:
413: #define TAILQ_HEAD_INITIALIZER(head) \
414: { NULL, &(head).tqh_first }
415:
416: #define TAILQ_ENTRY(type) \
417: struct { \
418: struct type *tqe_next; /* next element */ \
419: struct type **tqe_prev; /* address of previous next element */ \
420: }
421:
422: /*
423: * Tail queue access methods.
424: */
425: #define TAILQ_FIRST(head) ((head)->tqh_first)
426: #define TAILQ_END(head) NULL
427: #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
428: #define TAILQ_LAST(head, headname) \
429: (*(((struct headname *)((head)->tqh_last))->tqh_last))
430: /* XXX */
431: #define TAILQ_PREV(elm, headname, field) \
432: (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
433: #define TAILQ_EMPTY(head) \
434: (TAILQ_FIRST(head) == TAILQ_END(head))
435:
436: #define TAILQ_FOREACH(var, head, field) \
437: for((var) = TAILQ_FIRST(head); \
438: (var) != TAILQ_END(head); \
439: (var) = TAILQ_NEXT(var, field))
440:
441: #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
442: for ((var) = TAILQ_FIRST(head); \
443: (var) != TAILQ_END(head) && \
444: ((tvar) = TAILQ_NEXT(var, field), 1); \
445: (var) = (tvar))
446:
447:
448: #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
449: for((var) = TAILQ_LAST(head, headname); \
450: (var) != TAILQ_END(head); \
451: (var) = TAILQ_PREV(var, headname, field))
452:
453: #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
454: for ((var) = TAILQ_LAST(head, headname); \
455: (var) != TAILQ_END(head) && \
456: ((tvar) = TAILQ_PREV(var, headname, field), 1); \
457: (var) = (tvar))
458:
459: /*
460: * Tail queue functions.
461: */
462: #define TAILQ_INIT(head) do { \
463: (head)->tqh_first = NULL; \
464: (head)->tqh_last = &(head)->tqh_first; \
465: } while (0)
466:
467: #define TAILQ_INSERT_HEAD(head, elm, field) do { \
468: if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
469: (head)->tqh_first->field.tqe_prev = \
470: &(elm)->field.tqe_next; \
471: else \
472: (head)->tqh_last = &(elm)->field.tqe_next; \
473: (head)->tqh_first = (elm); \
474: (elm)->field.tqe_prev = &(head)->tqh_first; \
475: } while (0)
476:
477: #define TAILQ_INSERT_TAIL(head, elm, field) do { \
478: (elm)->field.tqe_next = NULL; \
479: (elm)->field.tqe_prev = (head)->tqh_last; \
480: *(head)->tqh_last = (elm); \
481: (head)->tqh_last = &(elm)->field.tqe_next; \
482: } while (0)
483:
484: #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
485: if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
486: (elm)->field.tqe_next->field.tqe_prev = \
487: &(elm)->field.tqe_next; \
488: else \
489: (head)->tqh_last = &(elm)->field.tqe_next; \
490: (listelm)->field.tqe_next = (elm); \
491: (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
492: } while (0)
493:
494: #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
495: (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
496: (elm)->field.tqe_next = (listelm); \
497: *(listelm)->field.tqe_prev = (elm); \
498: (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
499: } while (0)
500:
501: #define TAILQ_REMOVE(head, elm, field) do { \
502: if (((elm)->field.tqe_next) != NULL) \
503: (elm)->field.tqe_next->field.tqe_prev = \
504: (elm)->field.tqe_prev; \
505: else \
506: (head)->tqh_last = (elm)->field.tqe_prev; \
507: *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
508: _Q_INVALIDATE((elm)->field.tqe_prev); \
509: _Q_INVALIDATE((elm)->field.tqe_next); \
510: } while (0)
511:
512: #define TAILQ_REPLACE(head, elm, elm2, field) do { \
513: if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
514: (elm2)->field.tqe_next->field.tqe_prev = \
515: &(elm2)->field.tqe_next; \
516: else \
517: (head)->tqh_last = &(elm2)->field.tqe_next; \
518: (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
519: *(elm2)->field.tqe_prev = (elm2); \
520: _Q_INVALIDATE((elm)->field.tqe_prev); \
521: _Q_INVALIDATE((elm)->field.tqe_next); \
522: } while (0)
523:
524: #define TAILQ_CONCAT(head1, head2, field) do { \
525: if (!TAILQ_EMPTY(head2)) { \
526: *(head1)->tqh_last = (head2)->tqh_first; \
527: (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
528: (head1)->tqh_last = (head2)->tqh_last; \
529: TAILQ_INIT((head2)); \
530: } \
531: } while (0)
532:
533: #endif /* !_SYS_QUEUE_H_ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>