Initial import from FreeBSD RELENG_4:
[games.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  *
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 */