FreeBSD/Linux Kernel Cross Reference
sys/netatm/queue.h
1 /*-
2 *
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
6 *
7 *
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
12 *
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
20 *
21 * Copyright 1994-1998 Network Computing Services, Inc.
22 *
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
25 *
26 * @(#) $FreeBSD$
27 *
28 */
29
30 /*
31 * Core ATM Services
32 * -----------------
33 *
34 * General queueing/linking definitions
35 *
36 */
37
38 #ifndef _NETATM_QUEUE_H
39 #define _NETATM_QUEUE_H
40
41 /*
42 * Structure defining the queue controls for a doubly linked queue
43 */
44 struct q_queue {
45 caddr_t q_head; /* Head of queue */
46 caddr_t q_tail; /* Tail of queue */
47 };
48 typedef struct q_queue Queue_t;
49
50 /*
51 * Structure defining the queue elements of a doubly linked queue
52 */
53 struct q_elem {
54 caddr_t q_forw; /* Forward link */
55 caddr_t q_back; /* Backward link */
56 };
57 typedef struct q_elem Qelem_t;
58
59 /*
60 * Macro to add a control block onto the tail of a doubly linked queue
61 * e = control block to add
62 * t = control block structure type
63 * el = name of control block's q_elem field
64 * q = pointer to queue controls
65 */
66 #define ENQUEUE(e,t,el,q) \
67 { \
68 (e)->el.q_forw = NULL; \
69 (e)->el.q_back = (q).q_tail; \
70 if ((q).q_head == NULL) { \
71 (q).q_head = (caddr_t)(e); \
72 (q).q_tail = (caddr_t)(e); \
73 } else { \
74 ((t *)(q).q_tail)->el.q_forw = (caddr_t)(e); \
75 (q).q_tail = (caddr_t)(e); \
76 } \
77 }
78
79 /*
80 * Macro to remove a control block from a doubly linked queue
81 * e = control block to remove
82 * t = control block structure type
83 * el = name of control block's q_elem field
84 * q = pointer to queue controls
85 */
86 #define DEQUEUE(e,t,el,q) \
87 { \
88 /* Ensure control block is on queue */ \
89 if ((e)->el.q_forw || (q).q_tail == (caddr_t)(e)) { \
90 if ((e)->el.q_forw) \
91 ((t *)(e)->el.q_forw)->el.q_back = (e)->el.q_back;\
92 else \
93 (q).q_tail = (e)->el.q_back; \
94 if ((e)->el.q_back) \
95 ((t *)(e)->el.q_back)->el.q_forw = (e)->el.q_forw;\
96 else \
97 (q).q_head = (e)->el.q_forw; \
98 } \
99 (e)->el.q_back = (e)->el.q_forw = NULL; \
100 }
101
102 /*
103 * Macro to return the head of a doubly linked queue
104 * q = pointer to queue controls
105 * t = control block structure type
106 */
107 #define Q_HEAD(q,t) ((t *)(q).q_head)
108
109 /*
110 * Macro to return the next control block of a doubly linked queue
111 * e = current control block
112 * t = control block structure type
113 * el = name of control block's q_elem field
114 */
115 #define Q_NEXT(e,t,el) ((t *)(e)->el.q_forw)
116
117
118 /*
119 * Macro to add a control block onto the head of a singly linked chain
120 * u = control block to add
121 * t = structure type
122 * h = head of chain
123 * l = name of link field
124 */
125 #define LINK2HEAD(u,t,h,l) \
126 { \
127 (u)->l = (h); \
128 (h) = (u); \
129 }
130
131 /*
132 * Macro to add a control block onto the tail of a singly linked chain
133 * u = control block to add
134 * t = structure type
135 * h = head of chain
136 * l = name of link field
137 */
138 #define LINK2TAIL(u,t,h,l) \
139 { \
140 (u)->l = (t *)NULL; \
141 /* Check for empty chain */ \
142 if ((h) == (t *)NULL) { \
143 (h) = (u); \
144 } else { \
145 t *tp; \
146 /* Loop until we find the end of chain */ \
147 for (tp = (h); tp->l != (t *)NULL; tp = tp->l) \
148 ; \
149 tp->l = (u); \
150 } \
151 }
152
153 /*
154 * Macro to remove a control block from a singly linked chain
155 * u = control block to unlink
156 * t = structure type
157 * h = head of chain
158 * l = name of link field
159 */
160 #define UNLINK(u,t,h,l) \
161 { \
162 /* Check for control block at head of chain */ \
163 if ((u) == (h)) { \
164 (h) = (u)->l; \
165 } else { \
166 t *tp; \
167 /* Loop until we find the control block */ \
168 for (tp = (h); tp != (t *)NULL; tp = tp->l) { \
169 if (tp->l == (u)) \
170 break; \
171 } \
172 if (tp) { \
173 /* Remove it from chain */ \
174 tp->l = (u)->l; \
175 } \
176 } \
177 (u)->l = (t *)NULL; \
178 }
179
180 /*
181 * Macro to remove a control block from a singly linked chain and return
182 * an indication of whether the block was found
183 * u = control block to unlink
184 * t = structure type
185 * h = head of chain
186 * l = name of link field
187 * f = flag; 1 => control block found on chain; else 0
188 */
189 #define UNLINKF(u,t,h,l,f) \
190 { \
191 /* Check for control block at head of chain */ \
192 if ((u) == (h)) { \
193 (h) = (u)->l; \
194 (f) = 1; \
195 } else { \
196 t *tp; \
197 /* Loop until we find the control block */ \
198 for (tp = (h); tp != (t *)NULL; tp = tp->l) { \
199 if (tp->l == (u)) \
200 break; \
201 } \
202 if (tp) { \
203 /* Remove it from chain */ \
204 tp->l = (u)->l; \
205 (f) = 1; \
206 } else \
207 /* It wasn't on the chain */ \
208 (f) = 0; \
209 } \
210 (u)->l = (t *)NULL; \
211 }
212
213 #endif /* _NETATM_QUEUE_H */
Cache object: 2bfa9b4753b5aaa8efca97d14cd7ee53
|