pthread_queue.h revision 1.1.2.1 1 /* $Id: pthread_queue.h,v 1.1.2.1 2001/07/13 02:04:33 nathanw Exp $ */
2
3 /*
4 * Copyright
5 */
6
7 /* pthread_queue.h
8 * Definition of a queue interface for the pthread library.
9 * Style modeled on the sys/queue.h macros; implementation taken from
10 * the tail queue, with the added property of static initializability
11 * (and a corresponding extra cost in the _INSERT_TAIL() function.
12 */
13
14
15
16 /*
17 * Queue definitions.
18 */
19 #define PTQ_HEAD(name, type) \
20 struct name { \
21 struct type *ptqh_first;/* first element */ \
22 struct type **ptqh_last;/* addr of last next element */ \
23 }
24
25 #define PTQ_HEAD_INITIALIZER { NULL, NULL }
26
27
28 #define PTQ_ENTRY(type) \
29 struct { \
30 struct type *ptqe_next; /* next element */ \
31 struct type **ptqe_prev;/* address of previous next element */ \
32 }
33
34 /*
35 * Queue functions.
36 */
37
38 #define PTQ_INIT(head) do { \
39 (head)->ptqh_first = NULL; \
40 (head)->ptqh_last = &(head)->ptqh_first; \
41 } while (/*CONSTCOND*/0)
42
43 #define PTQ_INSERT_HEAD(head, elm, field) do { \
44 if (((elm)->field.ptqe_next = (head)->ptqh_first) != NULL) \
45 (head)->ptqh_first->field.ptqe_prev = \
46 &(elm)->field.ptqe_next; \
47 else \
48 (head)->ptqh_last = &(elm)->field.ptqe_next; \
49 (head)->ptqh_first = (elm); \
50 (elm)->field.ptqe_prev = &(head)->ptqh_first; \
51 } while (/*CONSTCOND*/0)
52
53 #define PTQ_INSERT_TAIL(head, elm, field) do { \
54 (elm)->field.ptqe_next = NULL; \
55 if ((head)->ptqh_last == NULL) \
56 (head)->ptqh_last = &(head)->ptqh_first; \
57 (elm)->field.ptqe_prev = (head)->ptqh_last; \
58 *(head)->ptqh_last = (elm); \
59 (head)->ptqh_last = &(elm)->field.ptqe_next; \
60 } while (/*CONSTCOND*/0)
61
62 #define PTQ_INSERT_AFTER(head, listelm, elm, field) do { \
63 if (((elm)->field.ptqe_next = (listelm)->field.ptqe_next) != NULL)\
64 (elm)->field.ptqe_next->field.ptqe_prev = \
65 &(elm)->field.ptqe_next; \
66 else \
67 (head)->ptqh_last = &(elm)->field.ptqe_next; \
68 (listelm)->field.ptqe_next = (elm); \
69 (elm)->field.ptqe_prev = &(listelm)->field.ptqe_next; \
70 } while (/*CONSTCOND*/0)
71
72 #define PTQ_INSERT_BEFORE(listelm, elm, field) do { \
73 (elm)->field.ptqe_prev = (listelm)->field.ptqe_prev; \
74 (elm)->field.ptqe_next = (listelm); \
75 *(listelm)->field.ptqe_prev = (elm); \
76 (listelm)->field.ptqe_prev = &(elm)->field.ptqe_next; \
77 } while (/*CONSTCOND*/0)
78
79 #define PTQ_REMOVE(head, elm, field) do { \
80 if (((elm)->field.ptqe_next) != NULL) \
81 (elm)->field.ptqe_next->field.ptqe_prev = \
82 (elm)->field.ptqe_prev; \
83 else \
84 (head)->ptqh_last = (elm)->field.ptqe_prev; \
85 *(elm)->field.ptqe_prev = (elm)->field.ptqe_next; \
86 } while (/*CONSTCOND*/0)
87
88 /*
89 * Queue access methods.
90 */
91 #define PTQ_EMPTY(head) ((head)->ptqh_first == NULL)
92 #define PTQ_FIRST(head) ((head)->ptqh_first)
93 #define PTQ_NEXT(elm, field) ((elm)->field.ptqe_next)
94
95 #define PTQ_LAST(head, headname) \
96 (*(((struct headname *)((head)->ptqh_last))->ptqh_last))
97 #define PTQ_PREV(elm, headname, field) \
98 (*(((struct headname *)((elm)->field.ptqe_prev))->ptqh_last))
99
100 #define PTQ_FOREACH(var, head, field) \
101 for ((var) = ((head)->ptqh_first); \
102 (var); \
103 (var) = ((var)->field.ptqe_next))
104
105 #define PTQ_FOREACH_REVERSE(var, head, headname, field) \
106 for ((var) = (*(((struct headname *)((head)->ptqh_last))->ptqh_last)); \
107 (var); \
108 (var) = (*(((struct headname *)((var)->field.ptqe_prev))->ptqh_last)))
109