]> rtime.felk.cvut.cz Git - arc.git/blob - include/sys/queue.h
Added kernel_extra example. Added CW support again.
[arc.git] / include / sys / queue.h
1 /*
2  * Copyright (c) 1991, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by the University of
16  *      California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *      @(#)queue.h     8.5 (Berkeley) 8/20/94
34  * $FreeBSD: src/sys/sys/queue.h,v 1.48 2002/04/17 14:00:37 tmm Exp $
35  */
36
37 #ifndef _SYS_QUEUE_H_
38 #define _SYS_QUEUE_H_
39
40 //#include <machine/ansi.h>     /* for __offsetof */
41 #include <stddef.h>     /* for __offsetof */
42
43
44
45
46 /*
47  * This file defines four types of data structures: singly-linked lists,
48  * singly-linked tail queues, lists and tail queues.
49  *
50  * A singly-linked list is headed by a single forward pointer. The elements
51  * are singly linked for minimum space and pointer manipulation overhead at
52  * the expense of O(n) removal for arbitrary elements. New elements can be
53  * added to the list after an existing element or at the head of the list.
54  * Elements being removed from the head of the list should use the explicit
55  * macro for this purpose for optimum efficiency. A singly-linked list may
56  * only be traversed in the forward direction.  Singly-linked lists are ideal
57  * for applications with large datasets and few or no removals or for
58  * implementing a LIFO queue.
59  *
60  * A singly-linked tail queue is headed by a pair of pointers, one to the
61  * head of the list and the other to the tail of the list. The elements are
62  * singly linked for minimum space and pointer manipulation overhead at the
63  * expense of O(n) removal for arbitrary elements. New elements can be added
64  * to the list after an existing element, at the head of the list, or at the
65  * end of the list. Elements being removed from the head of the tail queue
66  * should use the explicit macro for this purpose for optimum efficiency.
67  * A singly-linked tail queue may only be traversed in the forward direction.
68  * Singly-linked tail queues are ideal for applications with large datasets
69  * and few or no removals or for implementing a FIFO queue.
70  *
71  * A list is headed by a single forward pointer (or an array of forward
72  * pointers for a hash table header). The elements are doubly linked
73  * so that an arbitrary element can be removed without a need to
74  * traverse the list. New elements can be added to the list before
75  * or after an existing element or at the head of the list. A list
76  * may only be traversed in the forward direction.
77  *
78  * A tail queue is headed by a pair of pointers, one to the head of the
79  * list and the other to the tail of the list. The elements are doubly
80  * linked so that an arbitrary element can be removed without a need to
81  * traverse the list. New elements can be added to the list before or
82  * after an existing element, at the head of the list, or at the end of
83  * the list. A tail queue may be traversed in either direction.
84  *
85  * For details on the use of these macros, see the queue(3) manual page.
86  *
87  *
88  *                      SLIST   LIST    STAILQ  TAILQ
89  * _HEAD                +       +       +       +
90  * _HEAD_INITIALIZER    +       +       +       +
91  * _ENTRY               +       +       +       +
92  * _INIT                +       +       +       +
93  * _EMPTY               +       +       +       +
94  * _FIRST               +       +       +       +
95  * _NEXT                +       +       +       +
96  * _PREV                -       -       -       +
97  * _LAST                -       -       +       +
98  * _FOREACH             +       +       +       +
99  * _FOREACH_REVERSE     -       -       -       +
100  * _INSERT_HEAD         +       +       +       +
101  * _INSERT_BEFORE       -       +       -       +
102  * _INSERT_AFTER        +       +       +       +
103  * _INSERT_TAIL         -       -       +       +
104  * _CONCAT              -       -       +       +
105  * _REMOVE_HEAD         +       -       +       -
106  * _REMOVE              +       +       +       +
107  *
108  */
109
110 /*
111  * Singly-linked List declarations.
112  */
113 #define SLIST_HEAD(name, type)                                          \
114 struct name {                                                           \
115         struct type *slh_first; /* first element */                     \
116 }
117
118 #define SLIST_HEAD_INITIALIZER(head)                                    \
119         { NULL }
120  
121 #define SLIST_ENTRY(type)                                               \
122 struct {                                                                \
123         struct type *sle_next;  /* next element */                      \
124 }
125  
126 /*
127  * Singly-linked List functions.
128  */
129 #define SLIST_EMPTY(head)       ((head)->slh_first == NULL)
130
131 #define SLIST_FIRST(head)       ((head)->slh_first)
132
133 #define SLIST_FOREACH(var, head, field)                                 \
134         for ((var) = SLIST_FIRST((head));                               \
135             (var);                                                      \
136             (var) = SLIST_NEXT((var), field))
137
138 #define SLIST_INIT(head) do {                                           \
139         SLIST_FIRST((head)) = NULL;                                     \
140 } while (0)
141
142 #define SLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
143         SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);       \
144         SLIST_NEXT((slistelm), field) = (elm);                          \
145 } while (0)
146
147 #define SLIST_INSERT_HEAD(head, elm, field) do {                        \
148         SLIST_NEXT((elm), field) = SLIST_FIRST((head));                 \
149         SLIST_FIRST((head)) = (elm);                                    \
150 } while (0)
151
152 #define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
153
154 #define SLIST_REMOVE(head, elm, type, field) do {                       \
155         if (SLIST_FIRST((head)) == (elm)) {                             \
156                 SLIST_REMOVE_HEAD((head), field);                       \
157         }                                                               \
158         else {                                                          \
159                 struct type *curelm = SLIST_FIRST((head));              \
160                 while (SLIST_NEXT(curelm, field) != (elm))              \
161                         curelm = SLIST_NEXT(curelm, field);             \
162                 SLIST_NEXT(curelm, field) =                             \
163                     SLIST_NEXT(SLIST_NEXT(curelm, field), field);       \
164         }                                                               \
165 } while (0)
166
167 #define SLIST_REMOVE_HEAD(head, field) do {                             \
168         SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);   \
169 } while (0)
170
171 /*
172  * Singly-linked Tail queue declarations.
173  */
174 #define STAILQ_HEAD(name, type)                                         \
175 struct name {                                                           \
176         struct type *stqh_first;/* first element */                     \
177         struct type **stqh_last;/* addr of last next element */         \
178 }
179
180 #define STAILQ_HEAD_INITIALIZER(head)                                   \
181         { NULL, &(head).stqh_first }
182
183 #define STAILQ_ENTRY(type)                                              \
184 struct {                                                                \
185         struct type *stqe_next; /* next element */                      \
186 }
187
188 /*
189  * Singly-linked Tail queue functions.
190  */
191 #define STAILQ_CONCAT(head1, head2) do {                                \
192         if (!STAILQ_EMPTY((head2))) {                                   \
193                 *(head1)->stqh_last = (head2)->stqh_first;              \
194                 (head1)->stqh_last = (head2)->stqh_last;                \
195                 STAILQ_INIT((head2));                                   \
196         }                                                               \
197 } while (0)
198
199 #define STAILQ_EMPTY(head)      ((head)->stqh_first == NULL)
200
201 #define STAILQ_FIRST(head)      ((head)->stqh_first)
202
203 #define STAILQ_FOREACH(var, head, field)                                \
204         for((var) = STAILQ_FIRST((head));                               \
205            (var);                                                       \
206            (var) = STAILQ_NEXT((var), field))
207
208 #define STAILQ_INIT(head) do {                                          \
209         STAILQ_FIRST((head)) = NULL;                                    \
210         (head)->stqh_last = &STAILQ_FIRST((head));                      \
211 } while (0)
212
213 #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {               \
214         if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
215                 (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
216         STAILQ_NEXT((tqelm), field) = (elm);                            \
217 } while (0)
218
219 #define STAILQ_INSERT_HEAD(head, elm, field) do {                       \
220         if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
221                 (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
222         STAILQ_FIRST((head)) = (elm);                                   \
223 } while (0)
224
225 #define STAILQ_INSERT_TAIL(head, elm, field) do {                       \
226         STAILQ_NEXT((elm), field) = NULL;                               \
227         *(head)->stqh_last = (elm);                                     \
228         (head)->stqh_last = &STAILQ_NEXT((elm), field);                 \
229 } while (0)
230
231 #define STAILQ_LAST(head, type, field)                                  \
232         (STAILQ_EMPTY((head)) ?                                         \
233                 NULL :                                                  \
234                 ((struct type *)                                        \
235                 ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
236
237 #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
238
239 #define STAILQ_REMOVE(head, elm, type, field) do {                      \
240         if (STAILQ_FIRST((head)) == (elm)) {                            \
241                 STAILQ_REMOVE_HEAD((head), field);                      \
242         }                                                               \
243         else {                                                          \
244                 struct type *curelm = STAILQ_FIRST((head));             \
245                 while (STAILQ_NEXT(curelm, field) != (elm))             \
246                         curelm = STAILQ_NEXT(curelm, field);            \
247                 if ((STAILQ_NEXT(curelm, field) =                       \
248                      STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
249                         (head)->stqh_last = &STAILQ_NEXT((curelm), field);\
250         }                                                               \
251 } while (0)
252
253 #define STAILQ_REMOVE_HEAD(head, field) do {                            \
254         if ((STAILQ_FIRST((head)) =                                     \
255              STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)         \
256                 (head)->stqh_last = &STAILQ_FIRST((head));              \
257 } while (0)
258
259 #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {                 \
260         if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
261                 (head)->stqh_last = &STAILQ_FIRST((head));              \
262 } while (0)
263
264 /*
265  * List declarations.
266  */
267 #define LIST_HEAD(name, type)                                           \
268 struct name {                                                           \
269         struct type *lh_first;  /* first element */                     \
270 }
271
272 #define LIST_HEAD_INITIALIZER(head)                                     \
273         { NULL }
274
275 #define LIST_ENTRY(type)                                                \
276 struct {                                                                \
277         struct type *le_next;   /* next element */                      \
278         struct type **le_prev;  /* address of previous next element */  \
279 }
280
281 /*
282  * List functions.
283  */
284
285 #define LIST_EMPTY(head)        ((head)->lh_first == NULL)
286
287 #define LIST_FIRST(head)        ((head)->lh_first)
288
289 #define LIST_FOREACH(var, head, field)                                  \
290         for ((var) = LIST_FIRST((head));                                \
291             (var);                                                      \
292             (var) = LIST_NEXT((var), field))
293
294 #define LIST_INIT(head) do {                                            \
295         LIST_FIRST((head)) = NULL;                                      \
296 } while (0)
297
298 #define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
299         if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
300                 LIST_NEXT((listelm), field)->field.le_prev =            \
301                     &LIST_NEXT((elm), field);                           \
302         LIST_NEXT((listelm), field) = (elm);                            \
303         (elm)->field.le_prev = &LIST_NEXT((listelm), field);            \
304 } while (0)
305
306 #define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
307         (elm)->field.le_prev = (listelm)->field.le_prev;                \
308         LIST_NEXT((elm), field) = (listelm);                            \
309         *(listelm)->field.le_prev = (elm);                              \
310         (listelm)->field.le_prev = &LIST_NEXT((elm), field);            \
311 } while (0)
312
313 #define LIST_INSERT_HEAD(head, elm, field) do {                         \
314         if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)     \
315                 LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
316         LIST_FIRST((head)) = (elm);                                     \
317         (elm)->field.le_prev = &LIST_FIRST((head));                     \
318 } while (0)
319
320 #define LIST_NEXT(elm, field)   ((elm)->field.le_next)
321
322 #define LIST_REMOVE(elm, field) do {                                    \
323         if (LIST_NEXT((elm), field) != NULL)                            \
324                 LIST_NEXT((elm), field)->field.le_prev =                \
325                     (elm)->field.le_prev;                               \
326         *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
327 } while (0)
328
329 /*
330  * Tail queue declarations.
331  */
332 #define TAILQ_HEAD(name, type)                                          \
333 struct name {                                                           \
334         struct type *tqh_first; /* first element */                     \
335         struct type **tqh_last; /* addr of last next element */         \
336 }
337
338 #define TAILQ_HEAD_INITIALIZER(head)                                    \
339         { NULL, &(head).tqh_first }
340
341 #define TAILQ_ENTRY(type)                                               \
342 struct {                                                                \
343         struct type *tqe_next;  /* next element */                      \
344         struct type **tqe_prev; /* address of previous next element */  \
345 }
346
347 /*
348  * Tail queue functions.
349  */
350 #define TAILQ_CONCAT(head1, head2, field) do {                          \
351         if (!TAILQ_EMPTY(head2)) {                                      \
352                 *(head1)->tqh_last = (head2)->tqh_first;                \
353                 (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
354                 (head1)->tqh_last = (head2)->tqh_last;                  \
355                 TAILQ_INIT((head2));                                    \
356         }                                                               \
357 } while (0)
358
359 #define TAILQ_EMPTY(head)       ((head)->tqh_first == NULL)
360
361 #define TAILQ_FIRST(head)       ((head)->tqh_first)
362
363 #define TAILQ_FOREACH(var, head, field)                                 \
364         for ((var) = TAILQ_FIRST((head));                               \
365             (var);                                                      \
366             (var) = TAILQ_NEXT((var), field))
367
368 #define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
369         for ((var) = TAILQ_LAST((head), headname);                      \
370             (var);                                                      \
371             (var) = TAILQ_PREV((var), headname, field))
372
373 #define TAILQ_INIT(head) do {                                           \
374         TAILQ_FIRST((head)) = NULL;                                     \
375         (head)->tqh_last = &TAILQ_FIRST((head));                        \
376 } while (0)
377
378 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
379         if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
380                 TAILQ_NEXT((elm), field)->field.tqe_prev =              \
381                     &TAILQ_NEXT((elm), field);                          \
382         else                                                            \
383                 (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
384         TAILQ_NEXT((listelm), field) = (elm);                           \
385         (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);          \
386 } while (0)
387
388 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
389         (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
390         TAILQ_NEXT((elm), field) = (listelm);                           \
391         *(listelm)->field.tqe_prev = (elm);                             \
392         (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);          \
393 } while (0)
394
395 #define TAILQ_INSERT_HEAD(head, elm, field) do {                        \
396         if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)   \
397                 TAILQ_FIRST((head))->field.tqe_prev =                   \
398                     &TAILQ_NEXT((elm), field);                          \
399         else                                                            \
400                 (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
401         TAILQ_FIRST((head)) = (elm);                                    \
402         (elm)->field.tqe_prev = &TAILQ_FIRST((head));                   \
403 } while (0)
404
405 #define TAILQ_INSERT_TAIL(head, elm, field) do {                        \
406         TAILQ_NEXT((elm), field) = NULL;                                \
407         (elm)->field.tqe_prev = (head)->tqh_last;                       \
408         *(head)->tqh_last = (elm);                                      \
409         (head)->tqh_last = &TAILQ_NEXT((elm), field);                   \
410 } while (0)
411
412 #define TAILQ_LAST(head, headname)                                      \
413         (*(((struct headname *)((head)->tqh_last))->tqh_last))
414
415 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
416
417 #define TAILQ_PREV(elm, headname, field)                                \
418         (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
419
420 #define TAILQ_REMOVE(head, elm, field) do {                             \
421         if ((TAILQ_NEXT((elm), field)) != NULL)                         \
422                 TAILQ_NEXT((elm), field)->field.tqe_prev =              \
423                     (elm)->field.tqe_prev;                              \
424         else                                                            \
425                 (head)->tqh_last = (elm)->field.tqe_prev;               \
426         *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);              \
427 } while (0)
428
429
430 #ifdef _KERNEL
431
432 /*
433  * XXX insque() and remque() are an old way of handling certain queues.
434  * They bogusly assumes that all queue heads look alike.
435  */
436
437 struct quehead {
438         struct quehead *qh_link;
439         struct quehead *qh_rlink;
440 };
441
442 #ifdef  __GNUC__
443
444 static __inline void
445 insque(void *a, void *b)
446 {
447         struct quehead *element = (struct quehead *)a,
448                  *head = (struct quehead *)b;
449
450         element->qh_link = head->qh_link;
451         element->qh_rlink = head;
452         head->qh_link = element;
453         element->qh_link->qh_rlink = element;
454 }
455
456 static __inline void
457 remque(void *a)
458 {
459         struct quehead *element = (struct quehead *)a;
460
461         element->qh_link->qh_rlink = element->qh_rlink;
462         element->qh_rlink->qh_link = element->qh_link;
463         element->qh_rlink = 0;
464 }
465
466 #else /* !__GNUC__ */
467
468 void    insque(void *a, void *b);
469 void    remque(void *a);
470
471 #endif /* __GNUC__ */
472
473 #endif /* _KERNEL */
474
475 #endif /* !_SYS_QUEUE_H_ */