kernel tree reorganization stage 1: Major cvs repository work (not logged as
[dragonfly.git] / sys / netproto / atm / 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: src/sys/netatm/queue.h,v 1.2 1999/08/28 00:48:41 peter Exp $
27  *      @(#) $DragonFly: src/sys/netproto/atm/queue.h,v 1.2 2003/06/17 04:28:49 dillon Exp $
28  *
29  */
30
31 /*
32  * Core ATM Services
33  * -----------------
34  *
35  * General queueing/linking definitions
36  *
37  */
38
39 #ifndef _NETATM_QUEUE_H
40 #define _NETATM_QUEUE_H
41
42 /*
43  * Structure defining the queue controls for a doubly linked queue
44  */
45 struct q_queue {
46         caddr_t         q_head;         /* Head of queue */
47         caddr_t         q_tail;         /* Tail of queue */
48 };
49 typedef struct q_queue Queue_t;
50
51 /*
52  * Structure defining the queue elements of a doubly linked queue
53  */
54 struct q_elem {
55         caddr_t         q_forw;         /* Forward link */
56         caddr_t         q_back;         /* Backward link */
57 };
58 typedef struct q_elem Qelem_t;
59
60 /*
61  * Macro to add a control block onto the tail of a doubly linked queue
62  *      e = control block to add
63  *      t = control block structure type
64  *      el = name of control block's q_elem field
65  *      q = pointer to queue controls
66  */
67 #define ENQUEUE(e,t,el,q)                                       \
68 {                                                               \
69         (e)->el.q_forw = NULL;                                  \
70         (e)->el.q_back = (q).q_tail;                            \
71         if ((q).q_head == NULL) {                               \
72                 (q).q_head = (caddr_t)(e);                      \
73                 (q).q_tail = (caddr_t)(e);                      \
74         } else {                                                \
75                 ((t *)(q).q_tail)->el.q_forw = (caddr_t)(e);    \
76                 (q).q_tail = (caddr_t)(e);                      \
77         }                                                       \
78 }
79
80 /*
81  * Macro to remove a control block from a doubly linked queue
82  *      e = control block to remove
83  *      t = control block structure type
84  *      el = name of control block's q_elem field
85  *      q = pointer to queue controls
86  */
87 #define DEQUEUE(e,t,el,q)                                       \
88 {                                                               \
89         /* Ensure control block is on queue */                  \
90         if ((e)->el.q_forw || (q).q_tail == (caddr_t)(e)) {     \
91                 if ((e)->el.q_forw)                             \
92                         ((t *)(e)->el.q_forw)->el.q_back = (e)->el.q_back;\
93                 else                                            \
94                         (q).q_tail = (e)->el.q_back;            \
95                 if ((e)->el.q_back)                             \
96                         ((t *)(e)->el.q_back)->el.q_forw = (e)->el.q_forw;\
97                 else                                            \
98                         (q).q_head = (e)->el.q_forw;            \
99         }                                                       \
100         (e)->el.q_back = (e)->el.q_forw = NULL;                 \
101 }
102
103 /*
104  * Macro to return the head of a doubly linked queue
105  *      q = pointer to queue controls
106  *      t = control block structure type
107  */
108 #define Q_HEAD(q,t)     ((t *)(q).q_head)
109
110 /*
111  * Macro to return the next control block of a doubly linked queue
112  *      e = current control block
113  *      t = control block structure type
114  *      el = name of control block's q_elem field
115  */
116 #define Q_NEXT(e,t,el)  ((t *)(e)->el.q_forw)
117
118
119 /*
120  * Macro to add a control block onto the head of a singly linked chain
121  *      u = control block to add
122  *      t = structure type
123  *      h = head of chain
124  *      l = name of link field
125  */
126 #define LINK2HEAD(u,t,h,l)                                      \
127 {                                                               \
128         (u)->l = (h);                                           \
129         (h) = (u);                                              \
130 }
131
132 /*
133  * Macro to add a control block onto the tail of a singly linked chain
134  *      u = control block to add
135  *      t = structure type
136  *      h = head of chain
137  *      l = name of link field
138  */
139 #define LINK2TAIL(u,t,h,l)                                      \
140 {                                                               \
141         (u)->l = (t *)NULL;                                     \
142         /* Check for empty chain */                             \
143         if ((h) == (t *)NULL) {                                 \
144                 (h) = (u);                                      \
145         } else {                                                \
146                 t       *tp;                                    \
147                 /* Loop until we find the end of chain */       \
148                 for (tp = (h); tp->l != (t *)NULL; tp = tp->l)  \
149                         ;                                       \
150                 tp->l = (u);                                    \
151         }                                                       \
152 }
153
154 /*
155  * Macro to remove a control block from a singly linked chain
156  *      u = control block to unlink
157  *      t = structure type
158  *      h = head of chain
159  *      l = name of link field
160  */
161 #define UNLINK(u,t,h,l)                                         \
162 {                                                               \
163         /* Check for control block at head of chain */          \
164         if ((u) == (h)) {                                       \
165                 (h) = (u)->l;                                   \
166         } else {                                                \
167                 t       *tp;                                    \
168                 /* Loop until we find the control block */      \
169                 for (tp = (h); tp != (t *)NULL; tp = tp->l) {   \
170                         if (tp->l == (u))                       \
171                                 break;                          \
172                 }                                               \
173                 if (tp) {                                       \
174                         /* Remove it from chain */              \
175                         tp->l = (u)->l;                         \
176                 }                                               \
177         }                                                       \
178         (u)->l = (t *)NULL;                                     \
179 }
180
181 /*
182  * Macro to remove a control block from a singly linked chain and return
183  * an indication of whether the block was found
184  *      u = control block to unlink
185  *      t = structure type
186  *      h = head of chain
187  *      l = name of link field
188  *      f = flag; 1 => control block found on chain; else 0
189  */
190 #define UNLINKF(u,t,h,l,f)                                      \
191 {                                                               \
192         /* Check for control block at head of chain */          \
193         if ((u) == (h)) {                                       \
194                 (h) = (u)->l;                                   \
195                 (f) = 1;                                        \
196         } else {                                                \
197                 t       *tp;                                    \
198                 /* Loop until we find the control block */      \
199                 for (tp = (h); tp != (t *)NULL; tp = tp->l) {   \
200                         if (tp->l == (u))                       \
201                                 break;                          \
202                 }                                               \
203                 if (tp) {                                       \
204                         /* Remove it from chain */              \
205                         tp->l = (u)->l;                         \
206                         (f) = 1;                                \
207                 } else                                          \
208                         /* It wasn't on the chain */            \
209                         (f) = 0;                                \
210         }                                                       \
211         (u)->l = (t *)NULL;                                     \
212 }
213
214 #endif  /* _NETATM_QUEUE_H */