Coverage Report

Created: 2025-07-11 07:04

/src/open62541/deps/open62541_queue.h
Line
Count
Source (jump to first uncovered line)
1
/*  $OpenBSD: queue.h,v 1.38 2013/07/03 15:05:21 fgsch Exp $  */
2
/*  $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
3
4
/*
5
 * Copyright (c) 1991, 1993
6
 *  The Regents of the University of California.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. Neither the name of the University nor the names of its contributors
17
 *    may be used to endorse or promote products derived from this software
18
 *    without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
 * SUCH DAMAGE.
31
 *
32
 *  @(#)queue.h 8.5 (Berkeley) 8/20/94
33
 */
34
35
#ifndef _SYS_QUEUE_H_
36
#define _SYS_QUEUE_H_
37
38
/*
39
 * This file defines five types of data structures: singly-linked lists, 
40
 * lists, simple queues, tail queues, and circular queues.
41
 *
42
 *
43
 * A singly-linked list is headed by a single forward pointer. The elements
44
 * are singly linked for minimum space and pointer manipulation overhead at
45
 * the expense of O(n) removal for arbitrary elements. New elements can be
46
 * added to the list after an existing element or at the head of the list.
47
 * Elements being removed from the head of the list should use the explicit
48
 * macro for this purpose for optimum efficiency. A singly-linked list may
49
 * only be traversed in the forward direction.  Singly-linked lists are ideal
50
 * for applications with large datasets and few or no removals or for
51
 * implementing a LIFO queue.
52
 *
53
 * A list is headed by a single forward pointer (or an array of forward
54
 * pointers for a hash table header). The elements are doubly linked
55
 * so that an arbitrary element can be removed without a need to
56
 * traverse the list. New elements can be added to the list before
57
 * or after an existing element or at the head of the list. A list
58
 * may only be traversed in the forward direction.
59
 *
60
 * A simple queue is headed by a pair of pointers, one the head of the
61
 * list and the other to the tail of the list. The elements are singly
62
 * linked to save space, so elements can only be removed from the
63
 * head of the list. New elements can be added to the list before or after
64
 * an existing element, at the head of the list, or at the end of the
65
 * list. A simple queue may only be traversed in the forward direction.
66
 *
67
 * A tail queue is headed by a pair of pointers, one to the head of the
68
 * list and the other to the tail of the list. The elements are doubly
69
 * linked so that an arbitrary element can be removed without a need to
70
 * traverse the list. New elements can be added to the list before or
71
 * after an existing element, at the head of the list, or at the end of
72
 * the list. A tail queue may be traversed in either direction.
73
 *
74
 * A circle queue is headed by a pair of pointers, one to the head of the
75
 * list and the other to the tail of the list. The elements are doubly
76
 * linked so that an arbitrary element can be removed without a need to
77
 * traverse the list. New elements can be added to the list before or after
78
 * an existing element, at the head of the list, or at the end of the list.
79
 * A circle queue may be traversed in either direction, but has a more
80
 * complex end of list detection.
81
 *
82
 * For details on the use of these macros, see the queue(3) manual page.
83
 */
84
85
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
86
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
87
#else
88
#define _Q_INVALIDATE(a)
89
#endif
90
91
/*
92
 * Singly-linked List definitions.
93
 */
94
#define SLIST_HEAD(name, type)            \
95
struct name {               \
96
    struct type *slh_first; /* first element */     \
97
}
98
 
99
#define SLIST_HEAD_INITIALIZER(head)          \
100
    { NULL }
101
102
#define SLIST_ENTRY(type)           \
103
struct {                \
104
    struct type *sle_next;  /* next element */      \
105
}
106
 
107
/*
108
 * Singly-linked List access methods.
109
 */
110
#define SLIST_FIRST(head) ((head)->slh_first)
111
#define SLIST_END(head)   NULL
112
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
113
#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
114
115
#define SLIST_FOREACH(var, head, field)         \
116
    for((var) = SLIST_FIRST(head);          \
117
        (var) != SLIST_END(head);         \
118
        (var) = SLIST_NEXT(var, field))
119
120
#define SLIST_FOREACH_SAFE(var, head, field, tvar)      \
121
    for ((var) = SLIST_FIRST(head);       \
122
        (var) && ((tvar) = SLIST_NEXT(var, field), 1);    \
123
        (var) = (tvar))
124
125
/*
126
 * Singly-linked List functions.
127
 */
128
#define SLIST_INIT(head) do {           \
129
    SLIST_FIRST(head) = SLIST_END(head);        \
130
} while(0)
131
132
#define SLIST_INSERT_AFTER(slistelm, elm, field) do {     \
133
    (elm)->field.sle_next = (slistelm)->field.sle_next;   \
134
    (slistelm)->field.sle_next = (elm);       \
135
} while (0)
136
137
#define SLIST_INSERT_HEAD(head, elm, field) do {      \
138
    (elm)->field.sle_next = (head)->slh_first;      \
139
    (head)->slh_first = (elm);          \
140
} while (0)
141
142
#define SLIST_REMOVE_AFTER(elm, field) do {       \
143
    (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;  \
144
} while (0)
145
146
#define SLIST_REMOVE_HEAD(head, field) do {       \
147
    (head)->slh_first = (head)->slh_first->field.sle_next;    \
148
} while (0)
149
150
#define SLIST_REMOVE(head, elm, type, field) do {     \
151
    if ((head)->slh_first == (elm)) {       \
152
        SLIST_REMOVE_HEAD((head), field);     \
153
    } else {              \
154
        struct type *curelm = (head)->slh_first;    \
155
                                    \
156
        while (curelm->field.sle_next != (elm))     \
157
            curelm = curelm->field.sle_next;    \
158
        curelm->field.sle_next =        \
159
            curelm->field.sle_next->field.sle_next;   \
160
        _Q_INVALIDATE((elm)->field.sle_next);     \
161
    }               \
162
} while (0)
163
164
/*
165
 * List definitions.
166
 */
167
#define LIST_HEAD(name, type)           \
168
struct name {               \
169
    struct type *lh_first;  /* first element */     \
170
}
171
172
#define LIST_HEAD_INITIALIZER(head)         \
173
    { NULL }
174
175
#define LIST_ENTRY(type)            \
176
struct {                \
177
    struct type *le_next; /* next element */      \
178
    struct type **le_prev;  /* address of previous next element */  \
179
}
180
181
/*
182
 * List access methods
183
 */
184
1.80k
#define LIST_FIRST(head)    ((head)->lh_first)
185
603
#define LIST_END(head)      NULL
186
0
#define LIST_EMPTY(head)    (LIST_FIRST(head) == LIST_END(head))
187
0
#define LIST_NEXT(elm, field)   ((elm)->field.le_next)
188
189
#define LIST_FOREACH(var, head, field)          \
190
402
    for((var) = LIST_FIRST(head);         \
191
402
        (var)!= LIST_END(head);         \
192
402
        (var) = LIST_NEXT(var, field))
193
194
#define LIST_FOREACH_SAFE(var, head, field, tvar)     \
195
1.20k
    for ((var) = LIST_FIRST(head);       \
196
1.20k
        (var) && ((tvar) = LIST_NEXT(var, field), 1);   \
197
1.20k
        (var) = (tvar))
198
199
/*
200
 * List functions.
201
 */
202
201
#define LIST_INIT(head) do {           \
203
201
    LIST_FIRST(head) = LIST_END(head);       \
204
201
} while (0)
205
206
0
#define LIST_INSERT_AFTER(listelm, elm, field) do {     \
207
0
    if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
208
0
        (listelm)->field.le_next->field.le_prev =   \
209
0
            &(elm)->field.le_next;       \
210
0
    (listelm)->field.le_next = (elm);       \
211
0
    (elm)->field.le_prev = &(listelm)->field.le_next;   \
212
0
} while (0)
213
214
#define LIST_INSERT_BEFORE(listelm, elm, field) do {      \
215
    (elm)->field.le_prev = (listelm)->field.le_prev;    \
216
    (elm)->field.le_next = (listelm);       \
217
    *(listelm)->field.le_prev = (elm);        \
218
    (listelm)->field.le_prev = &(elm)->field.le_next;   \
219
} while (0)
220
221
0
#define LIST_INSERT_HEAD(head, elm, field) do {       \
222
0
    if (((elm)->field.le_next = (head)->lh_first) != NULL)   \
223
0
        (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
224
0
    (head)->lh_first = (elm);         \
225
0
    (elm)->field.le_prev = &(head)->lh_first;     \
226
0
} while (0)
227
228
0
#define LIST_REMOVE(elm, field) do {         \
229
0
    if ((elm)->field.le_next != NULL)       \
230
0
        (elm)->field.le_next->field.le_prev =     \
231
0
            (elm)->field.le_prev;       \
232
0
    *(elm)->field.le_prev = (elm)->field.le_next;     \
233
0
    _Q_INVALIDATE((elm)->field.le_prev);        \
234
0
    _Q_INVALIDATE((elm)->field.le_next);        \
235
0
} while (0)
236
237
#define LIST_REPLACE(elm, elm2, field) do {       \
238
    if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
239
        (elm2)->field.le_next->field.le_prev =      \
240
            &(elm2)->field.le_next;       \
241
    (elm2)->field.le_prev = (elm)->field.le_prev;     \
242
    *(elm2)->field.le_prev = (elm2);        \
243
    _Q_INVALIDATE((elm)->field.le_prev);        \
244
    _Q_INVALIDATE((elm)->field.le_next);        \
245
} while (0)
246
247
/*
248
 * Simple queue definitions.
249
 */
250
#define SIMPLEQ_HEAD(name, type)          \
251
struct name {               \
252
    struct type *sqh_first; /* first element */     \
253
    struct type **sqh_last; /* addr of last next element */   \
254
}
255
256
#define SIMPLEQ_HEAD_INITIALIZER(head)          \
257
    { NULL, &(head).sqh_first }
258
259
#define SIMPLEQ_ENTRY(type)           \
260
struct {                \
261
    struct type *sqe_next;  /* next element */      \
262
}
263
264
/*
265
 * Simple queue access methods.
266
 */
267
402
#define SIMPLEQ_FIRST(head)     ((head)->sqh_first)
268
#define SIMPLEQ_END(head)     NULL
269
#define SIMPLEQ_EMPTY(head)     (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
270
0
#define SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
271
272
#define SIMPLEQ_FOREACH(var, head, field)       \
273
    for((var) = SIMPLEQ_FIRST(head);        \
274
        (var) != SIMPLEQ_END(head);         \
275
        (var) = SIMPLEQ_NEXT(var, field))
276
277
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar)      \
278
0
    for ((var) = SIMPLEQ_FIRST(head);       \
279
0
        (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1);   \
280
0
        (var) = (tvar))
281
282
/*
283
 * Simple queue functions.
284
 */
285
201
#define SIMPLEQ_INIT(head) do {           \
286
201
    (head)->sqh_first = NULL;         \
287
201
    (head)->sqh_last = &(head)->sqh_first;        \
288
201
} while (0)
289
290
0
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {     \
291
0
    if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
292
0
        (head)->sqh_last = &(elm)->field.sqe_next;   \
293
0
    (head)->sqh_first = (elm);          \
294
0
} while (0)
295
296
0
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
297
0
    (elm)->field.sqe_next = NULL;         \
298
0
    *(head)->sqh_last = (elm);          \
299
0
    (head)->sqh_last = &(elm)->field.sqe_next;      \
300
0
} while (0)
301
302
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {    \
303
    if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
304
        (head)->sqh_last = &(elm)->field.sqe_next;    \
305
    (listelm)->field.sqe_next = (elm);        \
306
} while (0)
307
308
0
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
309
0
    if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
0
        (head)->sqh_last = &(head)->sqh_first;     \
311
0
} while (0)
312
313
0
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {     \
314
0
    if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
315
0
        == NULL)             \
316
0
        (head)->sqh_last = &(elm)->field.sqe_next;   \
317
0
} while (0)
318
319
/*
320
 * XOR Simple queue definitions.
321
 */
322
#define XSIMPLEQ_HEAD(name, type)         \
323
struct name {               \
324
    struct type *sqx_first; /* first element */     \
325
    struct type **sqx_last; /* addr of last next element */   \
326
    unsigned long sqx_cookie;         \
327
}
328
329
#define XSIMPLEQ_ENTRY(type)            \
330
struct {                \
331
    struct type *sqx_next;  /* next element */      \
332
}
333
334
/*
335
 * XOR Simple queue access methods.
336
 */
337
#define XSIMPLEQ_XOR(head, ptr)     ((__typeof(ptr))((head)->sqx_cookie ^ \
338
                    (unsigned long)(ptr)))
339
#define XSIMPLEQ_FIRST(head)      XSIMPLEQ_XOR(head, ((head)->sqx_first))
340
#define XSIMPLEQ_END(head)      NULL
341
#define XSIMPLEQ_EMPTY(head)      (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
342
#define XSIMPLEQ_NEXT(head, elm, field)    XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
343
344
345
#define XSIMPLEQ_FOREACH(var, head, field)        \
346
    for ((var) = XSIMPLEQ_FIRST(head);        \
347
        (var) != XSIMPLEQ_END(head);        \
348
        (var) = XSIMPLEQ_NEXT(head, var, field))
349
350
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar)     \
351
    for ((var) = XSIMPLEQ_FIRST(head);        \
352
        (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
353
        (var) = (tvar))
354
355
/*
356
 * XOR Simple queue functions.
357
 */
358
#define XSIMPLEQ_INIT(head) do {          \
359
    arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
360
    (head)->sqx_first = XSIMPLEQ_XOR(head, NULL);     \
361
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first);  \
362
} while (0)
363
364
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do {     \
365
    if (((elm)->field.sqx_next = (head)->sqx_first) ==    \
366
        XSIMPLEQ_XOR(head, NULL))         \
367
        (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
368
    (head)->sqx_first = XSIMPLEQ_XOR(head, (elm));      \
369
} while (0)
370
371
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
372
    (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL);   \
373
    *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
374
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);  \
375
} while (0)
376
377
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {   \
378
    if (((elm)->field.sqx_next = (listelm)->field.sqx_next) ==  \
379
        XSIMPLEQ_XOR(head, NULL))         \
380
        (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
381
    (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm));    \
382
} while (0)
383
384
#define XSIMPLEQ_REMOVE_HEAD(head, field) do {        \
385
    if (((head)->sqx_first = XSIMPLEQ_XOR(head,     \
386
        (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
387
        (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
388
} while (0)
389
390
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do {      \
391
    if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head,     \
392
        (elm)->field.sqx_next)->field.sqx_next)     \
393
        == XSIMPLEQ_XOR(head, NULL))        \
394
        (head)->sqx_last =          \
395
            XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);   \
396
} while (0)
397
398
            
399
/*
400
 * Tail queue definitions.
401
 */
402
#define TAILQ_HEAD(name, type)            \
403
struct name {               \
404
    struct type *tqh_first; /* first element */     \
405
    struct type **tqh_last; /* addr of last next element */   \
406
}
407
408
#define TAILQ_HEAD_INITIALIZER(head)          \
409
    { NULL, &(head).tqh_first }
410
411
#define TAILQ_ENTRY(type)           \
412
struct {                \
413
    struct type *tqe_next;  /* next element */      \
414
    struct type **tqe_prev; /* address of previous next element */  \
415
}
416
417
/* 
418
 * tail queue access methods 
419
 */
420
2.01k
#define TAILQ_FIRST(head)   ((head)->tqh_first)
421
4.02k
#define TAILQ_END(head)     NULL
422
201
#define TAILQ_NEXT(elm, field)    ((elm)->field.tqe_next)
423
#define TAILQ_LAST(head, headname)          \
424
0
    (*(((struct headname *)((head)->tqh_last))->tqh_last))
425
/* XXX */
426
#define TAILQ_PREV(elm, headname, field)        \
427
0
    (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
428
#define TAILQ_EMPTY(head)           \
429
201
    (TAILQ_FIRST(head) == TAILQ_END(head))
430
431
#define TAILQ_FOREACH(var, head, field)         \
432
201
    for((var) = TAILQ_FIRST(head);         \
433
201
        (var) != TAILQ_END(head);         \
434
201
        (var) = TAILQ_NEXT(var, field))
435
436
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)      \
437
1.60k
    for ((var) = TAILQ_FIRST(head);         \
438
1.80k
        (var) != TAILQ_END(head) &&         \
439
1.80k
        ((tvar) = TAILQ_NEXT(var, field), 1);     \
440
1.60k
        (var) = (tvar))
441
442
443
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)   \
444
    for((var) = TAILQ_LAST(head, headname);       \
445
        (var) != TAILQ_END(head);         \
446
        (var) = TAILQ_PREV(var, headname, field))
447
448
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)  \
449
    for ((var) = TAILQ_LAST(head, headname);      \
450
        (var) != TAILQ_END(head) &&         \
451
        ((tvar) = TAILQ_PREV(var, headname, field), 1);   \
452
        (var) = (tvar))
453
454
/*
455
 * Tail queue functions.
456
 */
457
2.41k
#define TAILQ_INIT(head) do {           \
458
2.41k
    (head)->tqh_first = NULL;         \
459
2.41k
    (head)->tqh_last = &(head)->tqh_first;        \
460
2.41k
} while (0)
461
462
0
#define TAILQ_INSERT_HEAD(head, elm, field) do {     \
463
0
    if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
464
0
        (head)->tqh_first->field.tqe_prev =     \
465
0
            &(elm)->field.tqe_next;       \
466
0
    else                \
467
0
        (head)->tqh_last = &(elm)->field.tqe_next;   \
468
0
    (head)->tqh_first = (elm);          \
469
0
    (elm)->field.tqe_prev = &(head)->tqh_first;     \
470
0
} while (0)
471
472
201
#define TAILQ_INSERT_TAIL(head, elm, field) do {     \
473
201
    (elm)->field.tqe_next = NULL;         \
474
201
    (elm)->field.tqe_prev = (head)->tqh_last;     \
475
201
    *(head)->tqh_last = (elm);          \
476
201
    (head)->tqh_last = &(elm)->field.tqe_next;      \
477
201
} while (0)
478
479
0
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {   \
480
0
    if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
481
0
        (elm)->field.tqe_next->field.tqe_prev =     \
482
0
            &(elm)->field.tqe_next;       \
483
0
    else                \
484
0
        (head)->tqh_last = &(elm)->field.tqe_next;   \
485
0
    (listelm)->field.tqe_next = (elm);        \
486
0
    (elm)->field.tqe_prev = &(listelm)->field.tqe_next;   \
487
0
} while (0)
488
489
0
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {     \
490
0
    (elm)->field.tqe_prev = (listelm)->field.tqe_prev;    \
491
0
    (elm)->field.tqe_next = (listelm);        \
492
0
    *(listelm)->field.tqe_prev = (elm);       \
493
0
    (listelm)->field.tqe_prev = &(elm)->field.tqe_next;   \
494
0
} while (0)
495
496
201
#define TAILQ_REMOVE(head, elm, field) do {       \
497
201
    if (((elm)->field.tqe_next) != NULL)       \
498
201
        (elm)->field.tqe_next->field.tqe_prev =     \
499
0
            (elm)->field.tqe_prev;       \
500
201
    else                \
501
201
        (head)->tqh_last = (elm)->field.tqe_prev;   \
502
201
    *(elm)->field.tqe_prev = (elm)->field.tqe_next;     \
503
201
    _Q_INVALIDATE((elm)->field.tqe_prev);       \
504
201
    _Q_INVALIDATE((elm)->field.tqe_next);       \
505
201
} while (0)
506
507
#define TAILQ_REPLACE(head, elm, elm2, field) do {      \
508
    if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
509
        (elm2)->field.tqe_next->field.tqe_prev =    \
510
            &(elm2)->field.tqe_next;        \
511
    else                \
512
        (head)->tqh_last = &(elm2)->field.tqe_next;   \
513
    (elm2)->field.tqe_prev = (elm)->field.tqe_prev;     \
514
    *(elm2)->field.tqe_prev = (elm2);       \
515
    _Q_INVALIDATE((elm)->field.tqe_prev);       \
516
    _Q_INVALIDATE((elm)->field.tqe_next);       \
517
} while (0)
518
519
/*
520
 * Circular queue definitions.
521
 */
522
#define CIRCLEQ_HEAD(name, type)          \
523
struct name {               \
524
    struct type *cqh_first;   /* first element */   \
525
    struct type *cqh_last;    /* last element */    \
526
}
527
528
#define CIRCLEQ_HEAD_INITIALIZER(head)          \
529
    { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
530
531
#define CIRCLEQ_ENTRY(type)           \
532
struct {                \
533
    struct type *cqe_next;    /* next element */    \
534
    struct type *cqe_prev;    /* previous element */    \
535
}
536
537
/*
538
 * Circular queue access methods 
539
 */
540
#define CIRCLEQ_FIRST(head)   ((head)->cqh_first)
541
#define CIRCLEQ_LAST(head)    ((head)->cqh_last)
542
#define CIRCLEQ_END(head)   ((void *)(head))
543
#define CIRCLEQ_NEXT(elm, field)  ((elm)->field.cqe_next)
544
#define CIRCLEQ_PREV(elm, field)  ((elm)->field.cqe_prev)
545
#define CIRCLEQ_EMPTY(head)           \
546
    (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
547
548
#define CIRCLEQ_FOREACH(var, head, field)       \
549
    for((var) = CIRCLEQ_FIRST(head);        \
550
        (var) != CIRCLEQ_END(head);         \
551
        (var) = CIRCLEQ_NEXT(var, field))
552
553
#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar)      \
554
    for ((var) = CIRCLEQ_FIRST(head);       \
555
        (var) != CIRCLEQ_END(head) &&       \
556
        ((tvar) = CIRCLEQ_NEXT(var, field), 1);     \
557
        (var) = (tvar))
558
559
#define CIRCLEQ_FOREACH_REVERSE(var, head, field)     \
560
    for((var) = CIRCLEQ_LAST(head);         \
561
        (var) != CIRCLEQ_END(head);         \
562
        (var) = CIRCLEQ_PREV(var, field))
563
564
#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)  \
565
    for ((var) = CIRCLEQ_LAST(head, headname);      \
566
        (var) != CIRCLEQ_END(head) &&         \
567
        ((tvar) = CIRCLEQ_PREV(var, headname, field), 1);   \
568
        (var) = (tvar))
569
570
/*
571
 * Circular queue functions.
572
 */
573
#define CIRCLEQ_INIT(head) do {           \
574
    (head)->cqh_first = CIRCLEQ_END(head);        \
575
    (head)->cqh_last = CIRCLEQ_END(head);       \
576
} while (0)
577
578
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {    \
579
    (elm)->field.cqe_next = (listelm)->field.cqe_next;    \
580
    (elm)->field.cqe_prev = (listelm);        \
581
    if ((listelm)->field.cqe_next == CIRCLEQ_END(head))   \
582
        (head)->cqh_last = (elm);       \
583
    else                \
584
        (listelm)->field.cqe_next->field.cqe_prev = (elm);  \
585
    (listelm)->field.cqe_next = (elm);        \
586
} while (0)
587
588
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {   \
589
    (elm)->field.cqe_next = (listelm);        \
590
    (elm)->field.cqe_prev = (listelm)->field.cqe_prev;    \
591
    if ((listelm)->field.cqe_prev == CIRCLEQ_END(head))   \
592
        (head)->cqh_first = (elm);        \
593
    else                \
594
        (listelm)->field.cqe_prev->field.cqe_next = (elm);  \
595
    (listelm)->field.cqe_prev = (elm);        \
596
} while (0)
597
598
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do {      \
599
    (elm)->field.cqe_next = (head)->cqh_first;      \
600
    (elm)->field.cqe_prev = CIRCLEQ_END(head);      \
601
    if ((head)->cqh_last == CIRCLEQ_END(head))      \
602
        (head)->cqh_last = (elm);       \
603
    else                \
604
        (head)->cqh_first->field.cqe_prev = (elm);    \
605
    (head)->cqh_first = (elm);          \
606
} while (0)
607
608
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do {      \
609
    (elm)->field.cqe_next = CIRCLEQ_END(head);      \
610
    (elm)->field.cqe_prev = (head)->cqh_last;     \
611
    if ((head)->cqh_first == CIRCLEQ_END(head))     \
612
        (head)->cqh_first = (elm);        \
613
    else                \
614
        (head)->cqh_last->field.cqe_next = (elm);   \
615
    (head)->cqh_last = (elm);         \
616
} while (0)
617
618
#define CIRCLEQ_REMOVE(head, elm, field) do {       \
619
    if ((elm)->field.cqe_next == CIRCLEQ_END(head))     \
620
        (head)->cqh_last = (elm)->field.cqe_prev;   \
621
    else                \
622
        (elm)->field.cqe_next->field.cqe_prev =     \
623
            (elm)->field.cqe_prev;        \
624
    if ((elm)->field.cqe_prev == CIRCLEQ_END(head))     \
625
        (head)->cqh_first = (elm)->field.cqe_next;    \
626
    else                \
627
        (elm)->field.cqe_prev->field.cqe_next =     \
628
            (elm)->field.cqe_next;        \
629
    _Q_INVALIDATE((elm)->field.cqe_prev);       \
630
    _Q_INVALIDATE((elm)->field.cqe_next);       \
631
} while (0)
632
633
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do {      \
634
    if (((elm2)->field.cqe_next = (elm)->field.cqe_next) ==   \
635
        CIRCLEQ_END(head))            \
636
        (head)->cqh_last = (elm2);        \
637
    else                \
638
        (elm2)->field.cqe_next->field.cqe_prev = (elm2);  \
639
    if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) ==   \
640
        CIRCLEQ_END(head))            \
641
        (head)->cqh_first = (elm2);       \
642
    else                \
643
        (elm2)->field.cqe_prev->field.cqe_next = (elm2);  \
644
    _Q_INVALIDATE((elm)->field.cqe_prev);       \
645
    _Q_INVALIDATE((elm)->field.cqe_next);       \
646
} while (0)
647
648
#endif  /* !_SYS_QUEUE_H_ */