Grid Community Toolkit
6.2.1629922860 (tag: v6.2.20210826)
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
gsi_openssh
source
openbsd-compat
sys-queue.h
1
/* $OpenBSD: queue.h,v 1.45 2018/07/12 14:22:54 sashan 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
/* OPENBSD ORIGINAL: sys/sys/queue.h */
36
37
#ifndef _FAKE_QUEUE_H_
38
#define _FAKE_QUEUE_H_
39
40
/*
41
* Require for OS/X and other platforms that have old/broken/incomplete
42
* <sys/queue.h>.
43
*/
44
#undef CIRCLEQ_EMPTY
45
#undef CIRCLEQ_END
46
#undef CIRCLEQ_ENTRY
47
#undef CIRCLEQ_FIRST
48
#undef CIRCLEQ_FOREACH
49
#undef CIRCLEQ_FOREACH_REVERSE
50
#undef CIRCLEQ_HEAD
51
#undef CIRCLEQ_HEAD_INITIALIZER
52
#undef CIRCLEQ_INIT
53
#undef CIRCLEQ_INSERT_AFTER
54
#undef CIRCLEQ_INSERT_BEFORE
55
#undef CIRCLEQ_INSERT_HEAD
56
#undef CIRCLEQ_INSERT_TAIL
57
#undef CIRCLEQ_LAST
58
#undef CIRCLEQ_NEXT
59
#undef CIRCLEQ_PREV
60
#undef CIRCLEQ_REMOVE
61
#undef CIRCLEQ_REPLACE
62
#undef LIST_EMPTY
63
#undef LIST_END
64
#undef LIST_ENTRY
65
#undef LIST_FIRST
66
#undef LIST_FOREACH
67
#undef LIST_FOREACH_SAFE
68
#undef LIST_HEAD
69
#undef LIST_HEAD_INITIALIZER
70
#undef LIST_INIT
71
#undef LIST_INSERT_AFTER
72
#undef LIST_INSERT_BEFORE
73
#undef LIST_INSERT_HEAD
74
#undef LIST_NEXT
75
#undef LIST_REMOVE
76
#undef LIST_REPLACE
77
#undef SIMPLEQ_CONCAT
78
#undef SIMPLEQ_EMPTY
79
#undef SIMPLEQ_END
80
#undef SIMPLEQ_ENTRY
81
#undef SIMPLEQ_FIRST
82
#undef SIMPLEQ_FOREACH
83
#undef SIMPLEQ_FOREACH_SAFE
84
#undef SIMPLEQ_HEAD
85
#undef SIMPLEQ_HEAD_INITIALIZER
86
#undef SIMPLEQ_INIT
87
#undef SIMPLEQ_INSERT_AFTER
88
#undef SIMPLEQ_INSERT_HEAD
89
#undef SIMPLEQ_INSERT_TAIL
90
#undef SIMPLEQ_NEXT
91
#undef SIMPLEQ_REMOVE_AFTER
92
#undef SIMPLEQ_REMOVE_HEAD
93
#undef SLIST_EMPTY
94
#undef SLIST_END
95
#undef SLIST_ENTRY
96
#undef SLIST_FIRST
97
#undef SLIST_FOREACH
98
#undef SLIST_FOREACH_PREVPTR
99
#undef SLIST_FOREACH_SAFE
100
#undef SLIST_HEAD
101
#undef SLIST_HEAD_INITIALIZER
102
#undef SLIST_INIT
103
#undef SLIST_INSERT_AFTER
104
#undef SLIST_INSERT_HEAD
105
#undef SLIST_NEXT
106
#undef SLIST_REMOVE
107
#undef SLIST_REMOVE_AFTER
108
#undef SLIST_REMOVE_HEAD
109
#undef SLIST_REMOVE_NEXT
110
#undef TAILQ_CONCAT
111
#undef TAILQ_EMPTY
112
#undef TAILQ_END
113
#undef TAILQ_ENTRY
114
#undef TAILQ_FIRST
115
#undef TAILQ_FOREACH
116
#undef TAILQ_FOREACH_REVERSE
117
#undef TAILQ_FOREACH_REVERSE_SAFE
118
#undef TAILQ_FOREACH_SAFE
119
#undef TAILQ_HEAD
120
#undef TAILQ_HEAD_INITIALIZER
121
#undef TAILQ_INIT
122
#undef TAILQ_INSERT_AFTER
123
#undef TAILQ_INSERT_BEFORE
124
#undef TAILQ_INSERT_HEAD
125
#undef TAILQ_INSERT_TAIL
126
#undef TAILQ_LAST
127
#undef TAILQ_NEXT
128
#undef TAILQ_PREV
129
#undef TAILQ_REMOVE
130
#undef TAILQ_REPLACE
131
132
/*
133
* This file defines five types of data structures: singly-linked lists,
134
* lists, simple queues, tail queues and XOR simple queues.
135
*
136
*
137
* A singly-linked list is headed by a single forward pointer. The elements
138
* are singly linked for minimum space and pointer manipulation overhead at
139
* the expense of O(n) removal for arbitrary elements. New elements can be
140
* added to the list after an existing element or at the head of the list.
141
* Elements being removed from the head of the list should use the explicit
142
* macro for this purpose for optimum efficiency. A singly-linked list may
143
* only be traversed in the forward direction. Singly-linked lists are ideal
144
* for applications with large datasets and few or no removals or for
145
* implementing a LIFO queue.
146
*
147
* A list is headed by a single forward pointer (or an array of forward
148
* pointers for a hash table header). The elements are doubly linked
149
* so that an arbitrary element can be removed without a need to
150
* traverse the list. New elements can be added to the list before
151
* or after an existing element or at the head of the list. A list
152
* may only be traversed in the forward direction.
153
*
154
* A simple queue is headed by a pair of pointers, one to the head of the
155
* list and the other to the tail of the list. The elements are singly
156
* linked to save space, so elements can only be removed from the
157
* head of the list. New elements can be added to the list before or after
158
* an existing element, at the head of the list, or at the end of the
159
* list. A simple queue may only be traversed in the forward direction.
160
*
161
* A tail queue is headed by a pair of pointers, one to the head of the
162
* list and the other to the tail of the list. The elements are doubly
163
* linked so that an arbitrary element can be removed without a need to
164
* traverse the list. New elements can be added to the list before or
165
* after an existing element, at the head of the list, or at the end of
166
* the list. A tail queue may be traversed in either direction.
167
*
168
* An XOR simple queue is used in the same way as a regular simple queue.
169
* The difference is that the head structure also includes a "cookie" that
170
* is XOR'd with the queue pointer (first, last or next) to generate the
171
* real pointer value.
172
*
173
* For details on the use of these macros, see the queue(3) manual page.
174
*/
175
176
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
177
#define _Q_INVALID ((void *)-1)
178
#define _Q_INVALIDATE(a) (a) = _Q_INVALID
179
#else
180
#define _Q_INVALIDATE(a)
181
#endif
182
183
/*
184
* Singly-linked List definitions.
185
*/
186
#define SLIST_HEAD(name, type) \
187
struct name { \
188
struct type *slh_first;
/* first element */
\
189
}
190
191
#define SLIST_HEAD_INITIALIZER(head) \
192
{ NULL }
193
194
#define SLIST_ENTRY(type) \
195
struct { \
196
struct type *sle_next;
/* next element */
\
197
}
198
199
/*
200
* Singly-linked List access methods.
201
*/
202
#define SLIST_FIRST(head) ((head)->slh_first)
203
#define SLIST_END(head) NULL
204
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
205
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
206
207
#define SLIST_FOREACH(var, head, field) \
208
for((var) = SLIST_FIRST(head); \
209
(var) != SLIST_END(head); \
210
(var) = SLIST_NEXT(var, field))
211
212
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
213
for ((var) = SLIST_FIRST(head); \
214
(var) && ((tvar) = SLIST_NEXT(var, field), 1); \
215
(var) = (tvar))
216
217
/*
218
* Singly-linked List functions.
219
*/
220
#define SLIST_INIT(head) { \
221
SLIST_FIRST(head) = SLIST_END(head); \
222
}
223
224
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
225
(elm)->field.sle_next = (slistelm)->field.sle_next; \
226
(slistelm)->field.sle_next = (elm); \
227
} while (0)
228
229
#define SLIST_INSERT_HEAD(head, elm, field) do { \
230
(elm)->field.sle_next = (head)->slh_first; \
231
(head)->slh_first = (elm); \
232
} while (0)
233
234
#define SLIST_REMOVE_AFTER(elm, field) do { \
235
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
236
} while (0)
237
238
#define SLIST_REMOVE_HEAD(head, field) do { \
239
(head)->slh_first = (head)->slh_first->field.sle_next; \
240
} while (0)
241
242
#define SLIST_REMOVE(head, elm, type, field) do { \
243
if ((head)->slh_first == (elm)) { \
244
SLIST_REMOVE_HEAD((head), field); \
245
} else { \
246
struct type *curelm = (head)->slh_first; \
247
\
248
while (curelm->field.sle_next != (elm)) \
249
curelm = curelm->field.sle_next; \
250
curelm->field.sle_next = \
251
curelm->field.sle_next->field.sle_next; \
252
} \
253
_Q_INVALIDATE((elm)->field.sle_next); \
254
} while (0)
255
256
/*
257
* List definitions.
258
*/
259
#define LIST_HEAD(name, type) \
260
struct name { \
261
struct type *lh_first;
/* first element */
\
262
}
263
264
#define LIST_HEAD_INITIALIZER(head) \
265
{ NULL }
266
267
#define LIST_ENTRY(type) \
268
struct { \
269
struct type *le_next;
/* next element */
\
270
struct type **le_prev;
/* address of previous next element */
\
271
}
272
273
/*
274
* List access methods.
275
*/
276
#define LIST_FIRST(head) ((head)->lh_first)
277
#define LIST_END(head) NULL
278
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
279
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
280
281
#define LIST_FOREACH(var, head, field) \
282
for((var) = LIST_FIRST(head); \
283
(var)!= LIST_END(head); \
284
(var) = LIST_NEXT(var, field))
285
286
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
287
for ((var) = LIST_FIRST(head); \
288
(var) && ((tvar) = LIST_NEXT(var, field), 1); \
289
(var) = (tvar))
290
291
/*
292
* List functions.
293
*/
294
#define LIST_INIT(head) do { \
295
LIST_FIRST(head) = LIST_END(head); \
296
} while (0)
297
298
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
299
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
300
(listelm)->field.le_next->field.le_prev = \
301
&(elm)->field.le_next; \
302
(listelm)->field.le_next = (elm); \
303
(elm)->field.le_prev = &(listelm)->field.le_next; \
304
} while (0)
305
306
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
307
(elm)->field.le_prev = (listelm)->field.le_prev; \
308
(elm)->field.le_next = (listelm); \
309
*(listelm)->field.le_prev = (elm); \
310
(listelm)->field.le_prev = &(elm)->field.le_next; \
311
} while (0)
312
313
#define LIST_INSERT_HEAD(head, elm, field) do { \
314
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
315
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
316
(head)->lh_first = (elm); \
317
(elm)->field.le_prev = &(head)->lh_first; \
318
} while (0)
319
320
#define LIST_REMOVE(elm, field) do { \
321
if ((elm)->field.le_next != NULL) \
322
(elm)->field.le_next->field.le_prev = \
323
(elm)->field.le_prev; \
324
*(elm)->field.le_prev = (elm)->field.le_next; \
325
_Q_INVALIDATE((elm)->field.le_prev); \
326
_Q_INVALIDATE((elm)->field.le_next); \
327
} while (0)
328
329
#define LIST_REPLACE(elm, elm2, field) do { \
330
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
331
(elm2)->field.le_next->field.le_prev = \
332
&(elm2)->field.le_next; \
333
(elm2)->field.le_prev = (elm)->field.le_prev; \
334
*(elm2)->field.le_prev = (elm2); \
335
_Q_INVALIDATE((elm)->field.le_prev); \
336
_Q_INVALIDATE((elm)->field.le_next); \
337
} while (0)
338
339
/*
340
* Simple queue definitions.
341
*/
342
#define SIMPLEQ_HEAD(name, type) \
343
struct name { \
344
struct type *sqh_first;
/* first element */
\
345
struct type **sqh_last;
/* addr of last next element */
\
346
}
347
348
#define SIMPLEQ_HEAD_INITIALIZER(head) \
349
{ NULL, &(head).sqh_first }
350
351
#define SIMPLEQ_ENTRY(type) \
352
struct { \
353
struct type *sqe_next;
/* next element */
\
354
}
355
356
/*
357
* Simple queue access methods.
358
*/
359
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
360
#define SIMPLEQ_END(head) NULL
361
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
362
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
363
364
#define SIMPLEQ_FOREACH(var, head, field) \
365
for((var) = SIMPLEQ_FIRST(head); \
366
(var) != SIMPLEQ_END(head); \
367
(var) = SIMPLEQ_NEXT(var, field))
368
369
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
370
for ((var) = SIMPLEQ_FIRST(head); \
371
(var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
372
(var) = (tvar))
373
374
/*
375
* Simple queue functions.
376
*/
377
#define SIMPLEQ_INIT(head) do { \
378
(head)->sqh_first = NULL; \
379
(head)->sqh_last = &(head)->sqh_first; \
380
} while (0)
381
382
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
383
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
384
(head)->sqh_last = &(elm)->field.sqe_next; \
385
(head)->sqh_first = (elm); \
386
} while (0)
387
388
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
389
(elm)->field.sqe_next = NULL; \
390
*(head)->sqh_last = (elm); \
391
(head)->sqh_last = &(elm)->field.sqe_next; \
392
} while (0)
393
394
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
395
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
396
(head)->sqh_last = &(elm)->field.sqe_next; \
397
(listelm)->field.sqe_next = (elm); \
398
} while (0)
399
400
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
401
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
402
(head)->sqh_last = &(head)->sqh_first; \
403
} while (0)
404
405
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
406
if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
407
== NULL) \
408
(head)->sqh_last = &(elm)->field.sqe_next; \
409
} while (0)
410
411
#define SIMPLEQ_CONCAT(head1, head2) do { \
412
if (!SIMPLEQ_EMPTY((head2))) { \
413
*(head1)->sqh_last = (head2)->sqh_first; \
414
(head1)->sqh_last = (head2)->sqh_last; \
415
SIMPLEQ_INIT((head2)); \
416
} \
417
} while (0)
418
419
/*
420
* XOR Simple queue definitions.
421
*/
422
#define XSIMPLEQ_HEAD(name, type) \
423
struct name { \
424
struct type *sqx_first;
/* first element */
\
425
struct type **sqx_last;
/* addr of last next element */
\
426
unsigned long sqx_cookie; \
427
}
428
429
#define XSIMPLEQ_ENTRY(type) \
430
struct { \
431
struct type *sqx_next;
/* next element */
\
432
}
433
434
/*
435
* XOR Simple queue access methods.
436
*/
437
#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \
438
(unsigned long)(ptr)))
439
#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first))
440
#define XSIMPLEQ_END(head) NULL
441
#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
442
#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
443
444
445
#define XSIMPLEQ_FOREACH(var, head, field) \
446
for ((var) = XSIMPLEQ_FIRST(head); \
447
(var) != XSIMPLEQ_END(head); \
448
(var) = XSIMPLEQ_NEXT(head, var, field))
449
450
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
451
for ((var) = XSIMPLEQ_FIRST(head); \
452
(var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
453
(var) = (tvar))
454
455
/*
456
* XOR Simple queue functions.
457
*/
458
#define XSIMPLEQ_INIT(head) do { \
459
arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
460
(head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \
461
(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
462
} while (0)
463
464
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
465
if (((elm)->field.sqx_next = (head)->sqx_first) == \
466
XSIMPLEQ_XOR(head, NULL)) \
467
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
468
(head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \
469
} while (0)
470
471
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
472
(elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \
473
*(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
474
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
475
} while (0)
476
477
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
478
if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \
479
XSIMPLEQ_XOR(head, NULL)) \
480
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
481
(listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \
482
} while (0)
483
484
#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \
485
if (((head)->sqx_first = XSIMPLEQ_XOR(head, \
486
(head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
487
(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
488
} while (0)
489
490
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
491
if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \
492
(elm)->field.sqx_next)->field.sqx_next) \
493
== XSIMPLEQ_XOR(head, NULL)) \
494
(head)->sqx_last = \
495
XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
496
} while (0)
497
498
499
/*
500
* Tail queue definitions.
501
*/
502
#define TAILQ_HEAD(name, type) \
503
struct name { \
504
struct type *tqh_first;
/* first element */
\
505
struct type **tqh_last;
/* addr of last next element */
\
506
}
507
508
#define TAILQ_HEAD_INITIALIZER(head) \
509
{ NULL, &(head).tqh_first }
510
511
#define TAILQ_ENTRY(type) \
512
struct { \
513
struct type *tqe_next;
/* next element */
\
514
struct type **tqe_prev;
/* address of previous next element */
\
515
}
516
517
/*
518
* Tail queue access methods.
519
*/
520
#define TAILQ_FIRST(head) ((head)->tqh_first)
521
#define TAILQ_END(head) NULL
522
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
523
#define TAILQ_LAST(head, headname) \
524
(*(((struct headname *)((head)->tqh_last))->tqh_last))
525
/* XXX */
526
#define TAILQ_PREV(elm, headname, field) \
527
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
528
#define TAILQ_EMPTY(head) \
529
(TAILQ_FIRST(head) == TAILQ_END(head))
530
531
#define TAILQ_FOREACH(var, head, field) \
532
for((var) = TAILQ_FIRST(head); \
533
(var) != TAILQ_END(head); \
534
(var) = TAILQ_NEXT(var, field))
535
536
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
537
for ((var) = TAILQ_FIRST(head); \
538
(var) != TAILQ_END(head) && \
539
((tvar) = TAILQ_NEXT(var, field), 1); \
540
(var) = (tvar))
541
542
543
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
544
for((var) = TAILQ_LAST(head, headname); \
545
(var) != TAILQ_END(head); \
546
(var) = TAILQ_PREV(var, headname, field))
547
548
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
549
for ((var) = TAILQ_LAST(head, headname); \
550
(var) != TAILQ_END(head) && \
551
((tvar) = TAILQ_PREV(var, headname, field), 1); \
552
(var) = (tvar))
553
554
/*
555
* Tail queue functions.
556
*/
557
#define TAILQ_INIT(head) do { \
558
(head)->tqh_first = NULL; \
559
(head)->tqh_last = &(head)->tqh_first; \
560
} while (0)
561
562
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
563
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
564
(head)->tqh_first->field.tqe_prev = \
565
&(elm)->field.tqe_next; \
566
else \
567
(head)->tqh_last = &(elm)->field.tqe_next; \
568
(head)->tqh_first = (elm); \
569
(elm)->field.tqe_prev = &(head)->tqh_first; \
570
} while (0)
571
572
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
573
(elm)->field.tqe_next = NULL; \
574
(elm)->field.tqe_prev = (head)->tqh_last; \
575
*(head)->tqh_last = (elm); \
576
(head)->tqh_last = &(elm)->field.tqe_next; \
577
} while (0)
578
579
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
580
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
581
(elm)->field.tqe_next->field.tqe_prev = \
582
&(elm)->field.tqe_next; \
583
else \
584
(head)->tqh_last = &(elm)->field.tqe_next; \
585
(listelm)->field.tqe_next = (elm); \
586
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
587
} while (0)
588
589
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
590
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
591
(elm)->field.tqe_next = (listelm); \
592
*(listelm)->field.tqe_prev = (elm); \
593
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
594
} while (0)
595
596
#define TAILQ_REMOVE(head, elm, field) do { \
597
if (((elm)->field.tqe_next) != NULL) \
598
(elm)->field.tqe_next->field.tqe_prev = \
599
(elm)->field.tqe_prev; \
600
else \
601
(head)->tqh_last = (elm)->field.tqe_prev; \
602
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
603
_Q_INVALIDATE((elm)->field.tqe_prev); \
604
_Q_INVALIDATE((elm)->field.tqe_next); \
605
} while (0)
606
607
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
608
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
609
(elm2)->field.tqe_next->field.tqe_prev = \
610
&(elm2)->field.tqe_next; \
611
else \
612
(head)->tqh_last = &(elm2)->field.tqe_next; \
613
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
614
*(elm2)->field.tqe_prev = (elm2); \
615
_Q_INVALIDATE((elm)->field.tqe_prev); \
616
_Q_INVALIDATE((elm)->field.tqe_next); \
617
} while (0)
618
619
#define TAILQ_CONCAT(head1, head2, field) do { \
620
if (!TAILQ_EMPTY(head2)) { \
621
*(head1)->tqh_last = (head2)->tqh_first; \
622
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
623
(head1)->tqh_last = (head2)->tqh_last; \
624
TAILQ_INIT((head2)); \
625
} \
626
} while (0)
627
628
#endif
/* !_SYS_QUEUE_H_ */
Generated by
1.8.5