File indexing completed on 2025-01-18 09:54:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #ifndef LIBBSD_SYS_QUEUE_H
0036 #define LIBBSD_SYS_QUEUE_H
0037
0038 #ifdef LIBBSD_OVERLAY
0039 #include <sys/cdefs.h>
0040 #else
0041 #include <bsd/sys/cdefs.h>
0042 #endif
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 #ifdef QUEUE_MACRO_DEBUG
0124 #warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH
0125 #define QUEUE_MACRO_DEBUG_TRACE
0126 #define QUEUE_MACRO_DEBUG_TRASH
0127 #endif
0128
0129 #ifdef QUEUE_MACRO_DEBUG_TRACE
0130
0131 struct qm_trace {
0132 unsigned long lastline;
0133 unsigned long prevline;
0134 const char *lastfile;
0135 const char *prevfile;
0136 };
0137
0138 #define TRACEBUF struct qm_trace trace;
0139 #define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } ,
0140
0141 #define QMD_TRACE_HEAD(head) do { \
0142 (head)->trace.prevline = (head)->trace.lastline; \
0143 (head)->trace.prevfile = (head)->trace.lastfile; \
0144 (head)->trace.lastline = __LINE__; \
0145 (head)->trace.lastfile = __FILE__; \
0146 } while (0)
0147
0148 #define QMD_TRACE_ELEM(elem) do { \
0149 (elem)->trace.prevline = (elem)->trace.lastline; \
0150 (elem)->trace.prevfile = (elem)->trace.lastfile; \
0151 (elem)->trace.lastline = __LINE__; \
0152 (elem)->trace.lastfile = __FILE__; \
0153 } while (0)
0154
0155 #else
0156 #define QMD_TRACE_ELEM(elem)
0157 #define QMD_TRACE_HEAD(head)
0158 #define TRACEBUF
0159 #define TRACEBUF_INITIALIZER
0160 #endif
0161
0162 #ifdef QUEUE_MACRO_DEBUG_TRASH
0163 #define QMD_SAVELINK(name, link) void **name = (void *)&(link)
0164 #define TRASHIT(x) do {(x) = (void *)-1;} while (0)
0165 #define QMD_IS_TRASHED(x) ((x) == (void *)(intptr_t)-1)
0166 #else
0167 #define QMD_SAVELINK(name, link)
0168 #define TRASHIT(x)
0169 #define QMD_IS_TRASHED(x) 0
0170 #endif
0171
0172 #ifdef __cplusplus
0173
0174
0175
0176 #define QUEUE_TYPEOF(type) type
0177 #else
0178 #define QUEUE_TYPEOF(type) struct type
0179 #endif
0180
0181
0182
0183
0184 #define SLIST_HEAD(name, type) \
0185 struct name { \
0186 struct type *slh_first; \
0187 }
0188
0189 #define SLIST_CLASS_HEAD(name, type) \
0190 struct name { \
0191 class type *slh_first; \
0192 }
0193
0194 #define SLIST_HEAD_INITIALIZER(head) \
0195 { NULL }
0196
0197 #define SLIST_ENTRY(type) \
0198 struct { \
0199 struct type *sle_next; \
0200 }
0201
0202 #define SLIST_CLASS_ENTRY(type) \
0203 struct { \
0204 class type *sle_next; \
0205 }
0206
0207
0208
0209
0210 #if (defined(_KERNEL) && defined(INVARIANTS))
0211 #define QMD_SLIST_CHECK_PREVPTR(prevp, elm) do { \
0212 if (*(prevp) != (elm)) \
0213 panic("Bad prevptr *(%p) == %p != %p", \
0214 (prevp), *(prevp), (elm)); \
0215 } while (0)
0216 #else
0217 #define QMD_SLIST_CHECK_PREVPTR(prevp, elm)
0218 #endif
0219
0220 #define SLIST_CONCAT(head1, head2, type, field) do { \
0221 QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \
0222 if (curelm == NULL) { \
0223 if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL) \
0224 SLIST_INIT(head2); \
0225 } else if (SLIST_FIRST(head2) != NULL) { \
0226 while (SLIST_NEXT(curelm, field) != NULL) \
0227 curelm = SLIST_NEXT(curelm, field); \
0228 SLIST_NEXT(curelm, field) = SLIST_FIRST(head2); \
0229 SLIST_INIT(head2); \
0230 } \
0231 } while (0)
0232
0233 #define SLIST_EMPTY(head) ((head)->slh_first == NULL)
0234
0235 #define SLIST_FIRST(head) ((head)->slh_first)
0236
0237 #define SLIST_FOREACH(var, head, field) \
0238 for ((var) = SLIST_FIRST((head)); \
0239 (var); \
0240 (var) = SLIST_NEXT((var), field))
0241
0242 #define SLIST_FOREACH_FROM(var, head, field) \
0243 for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
0244 (var); \
0245 (var) = SLIST_NEXT((var), field))
0246
0247 #define SLIST_FOREACH_SAFE(var, head, field, tvar) \
0248 for ((var) = SLIST_FIRST((head)); \
0249 (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
0250 (var) = (tvar))
0251
0252 #define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
0253 for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \
0254 (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
0255 (var) = (tvar))
0256
0257 #define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
0258 for ((varp) = &SLIST_FIRST((head)); \
0259 ((var) = *(varp)) != NULL; \
0260 (varp) = &SLIST_NEXT((var), field))
0261
0262 #define SLIST_INIT(head) do { \
0263 SLIST_FIRST((head)) = NULL; \
0264 } while (0)
0265
0266 #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
0267 SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
0268 SLIST_NEXT((slistelm), field) = (elm); \
0269 } while (0)
0270
0271 #define SLIST_INSERT_HEAD(head, elm, field) do { \
0272 SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
0273 SLIST_FIRST((head)) = (elm); \
0274 } while (0)
0275
0276 #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
0277
0278 #define SLIST_REMOVE(head, elm, type, field) do { \
0279 QMD_SAVELINK(oldnext, (elm)->field.sle_next); \
0280 if (SLIST_FIRST((head)) == (elm)) { \
0281 SLIST_REMOVE_HEAD((head), field); \
0282 } \
0283 else { \
0284 QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \
0285 while (SLIST_NEXT(curelm, field) != (elm)) \
0286 curelm = SLIST_NEXT(curelm, field); \
0287 SLIST_REMOVE_AFTER(curelm, field); \
0288 } \
0289 TRASHIT(*oldnext); \
0290 } while (0)
0291
0292 #define SLIST_REMOVE_AFTER(elm, field) do { \
0293 SLIST_NEXT(elm, field) = \
0294 SLIST_NEXT(SLIST_NEXT(elm, field), field); \
0295 } while (0)
0296
0297 #define SLIST_REMOVE_HEAD(head, field) do { \
0298 SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
0299 } while (0)
0300
0301 #define SLIST_REMOVE_PREVPTR(prevp, elm, field) do { \
0302 QMD_SLIST_CHECK_PREVPTR(prevp, elm); \
0303 *(prevp) = SLIST_NEXT(elm, field); \
0304 TRASHIT((elm)->field.sle_next); \
0305 } while (0)
0306
0307 #define SLIST_SWAP(head1, head2, type) do { \
0308 QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
0309 SLIST_FIRST(head1) = SLIST_FIRST(head2); \
0310 SLIST_FIRST(head2) = swap_first; \
0311 } while (0)
0312
0313 #define SLIST_END(head) NULL
0314
0315
0316
0317
0318 #define STAILQ_HEAD(name, type) \
0319 struct name { \
0320 struct type *stqh_first; \
0321 struct type **stqh_last; \
0322 }
0323
0324 #define STAILQ_CLASS_HEAD(name, type) \
0325 struct name { \
0326 class type *stqh_first; \
0327 class type **stqh_last; \
0328 }
0329
0330 #define STAILQ_HEAD_INITIALIZER(head) \
0331 { NULL, &(head).stqh_first }
0332
0333 #define STAILQ_ENTRY(type) \
0334 struct { \
0335 struct type *stqe_next; \
0336 }
0337
0338 #define STAILQ_CLASS_ENTRY(type) \
0339 struct { \
0340 class type *stqe_next; \
0341 }
0342
0343
0344
0345
0346 #define STAILQ_CONCAT(head1, head2) do { \
0347 if (!STAILQ_EMPTY((head2))) { \
0348 *(head1)->stqh_last = (head2)->stqh_first; \
0349 (head1)->stqh_last = (head2)->stqh_last; \
0350 STAILQ_INIT((head2)); \
0351 } \
0352 } while (0)
0353
0354 #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
0355
0356 #define STAILQ_FIRST(head) ((head)->stqh_first)
0357
0358 #define STAILQ_FOREACH(var, head, field) \
0359 for((var) = STAILQ_FIRST((head)); \
0360 (var); \
0361 (var) = STAILQ_NEXT((var), field))
0362
0363 #define STAILQ_FOREACH_FROM(var, head, field) \
0364 for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
0365 (var); \
0366 (var) = STAILQ_NEXT((var), field))
0367
0368 #define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
0369 for ((var) = STAILQ_FIRST((head)); \
0370 (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
0371 (var) = (tvar))
0372
0373 #define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
0374 for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \
0375 (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
0376 (var) = (tvar))
0377
0378 #define STAILQ_INIT(head) do { \
0379 STAILQ_FIRST((head)) = NULL; \
0380 (head)->stqh_last = &STAILQ_FIRST((head)); \
0381 } while (0)
0382
0383 #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
0384 if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
0385 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
0386 STAILQ_NEXT((tqelm), field) = (elm); \
0387 } while (0)
0388
0389 #define STAILQ_INSERT_HEAD(head, elm, field) do { \
0390 if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
0391 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
0392 STAILQ_FIRST((head)) = (elm); \
0393 } while (0)
0394
0395 #define STAILQ_INSERT_TAIL(head, elm, field) do { \
0396 STAILQ_NEXT((elm), field) = NULL; \
0397 *(head)->stqh_last = (elm); \
0398 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
0399 } while (0)
0400
0401 #define STAILQ_LAST(head, type, field) \
0402 (STAILQ_EMPTY((head)) ? NULL : \
0403 __containerof((head)->stqh_last, \
0404 QUEUE_TYPEOF(type), field.stqe_next))
0405
0406 #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
0407
0408 #define STAILQ_REMOVE(head, elm, type, field) do { \
0409 QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \
0410 if (STAILQ_FIRST((head)) == (elm)) { \
0411 STAILQ_REMOVE_HEAD((head), field); \
0412 } \
0413 else { \
0414 QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \
0415 while (STAILQ_NEXT(curelm, field) != (elm)) \
0416 curelm = STAILQ_NEXT(curelm, field); \
0417 STAILQ_REMOVE_AFTER(head, curelm, field); \
0418 } \
0419 TRASHIT(*oldnext); \
0420 } while (0)
0421
0422 #define STAILQ_REMOVE_AFTER(head, elm, field) do { \
0423 if ((STAILQ_NEXT(elm, field) = \
0424 STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
0425 (head)->stqh_last = &STAILQ_NEXT((elm), field); \
0426 } while (0)
0427
0428 #define STAILQ_REMOVE_HEAD(head, field) do { \
0429 if ((STAILQ_FIRST((head)) = \
0430 STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
0431 (head)->stqh_last = &STAILQ_FIRST((head)); \
0432 } while (0)
0433
0434 #define STAILQ_SWAP(head1, head2, type) do { \
0435 QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \
0436 QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \
0437 STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
0438 (head1)->stqh_last = (head2)->stqh_last; \
0439 STAILQ_FIRST(head2) = swap_first; \
0440 (head2)->stqh_last = swap_last; \
0441 if (STAILQ_EMPTY(head1)) \
0442 (head1)->stqh_last = &STAILQ_FIRST(head1); \
0443 if (STAILQ_EMPTY(head2)) \
0444 (head2)->stqh_last = &STAILQ_FIRST(head2); \
0445 } while (0)
0446
0447 #define STAILQ_END(head) NULL
0448
0449
0450
0451
0452
0453 #define LIST_HEAD(name, type) \
0454 struct name { \
0455 struct type *lh_first; \
0456 }
0457
0458 #define LIST_CLASS_HEAD(name, type) \
0459 struct name { \
0460 class type *lh_first; \
0461 }
0462
0463 #define LIST_HEAD_INITIALIZER(head) \
0464 { NULL }
0465
0466 #define LIST_ENTRY(type) \
0467 struct { \
0468 struct type *le_next; \
0469 struct type **le_prev; \
0470 }
0471
0472 #define LIST_CLASS_ENTRY(type) \
0473 struct { \
0474 class type *le_next; \
0475 class type **le_prev; \
0476 }
0477
0478
0479
0480
0481
0482 #if (defined(_KERNEL) && defined(INVARIANTS))
0483
0484
0485
0486
0487
0488
0489 #define QMD_LIST_CHECK_HEAD(head, field) do { \
0490 if (LIST_FIRST((head)) != NULL && \
0491 LIST_FIRST((head))->field.le_prev != \
0492 &LIST_FIRST((head))) \
0493 panic("Bad list head %p first->prev != head", (head)); \
0494 } while (0)
0495
0496
0497
0498
0499
0500
0501
0502 #define QMD_LIST_CHECK_NEXT(elm, field) do { \
0503 if (LIST_NEXT((elm), field) != NULL && \
0504 LIST_NEXT((elm), field)->field.le_prev != \
0505 &((elm)->field.le_next)) \
0506 panic("Bad link elm %p next->prev != elm", (elm)); \
0507 } while (0)
0508
0509
0510
0511
0512
0513
0514 #define QMD_LIST_CHECK_PREV(elm, field) do { \
0515 if (*(elm)->field.le_prev != (elm)) \
0516 panic("Bad link elm %p prev->next != elm", (elm)); \
0517 } while (0)
0518 #else
0519 #define QMD_LIST_CHECK_HEAD(head, field)
0520 #define QMD_LIST_CHECK_NEXT(elm, field)
0521 #define QMD_LIST_CHECK_PREV(elm, field)
0522 #endif
0523
0524 #define LIST_CONCAT(head1, head2, type, field) do { \
0525 QUEUE_TYPEOF(type) *curelm = LIST_FIRST(head1); \
0526 if (curelm == NULL) { \
0527 if ((LIST_FIRST(head1) = LIST_FIRST(head2)) != NULL) { \
0528 LIST_FIRST(head2)->field.le_prev = \
0529 &LIST_FIRST((head1)); \
0530 LIST_INIT(head2); \
0531 } \
0532 } else if (LIST_FIRST(head2) != NULL) { \
0533 while (LIST_NEXT(curelm, field) != NULL) \
0534 curelm = LIST_NEXT(curelm, field); \
0535 LIST_NEXT(curelm, field) = LIST_FIRST(head2); \
0536 LIST_FIRST(head2)->field.le_prev = &LIST_NEXT(curelm, field); \
0537 LIST_INIT(head2); \
0538 } \
0539 } while (0)
0540
0541 #define LIST_EMPTY(head) ((head)->lh_first == NULL)
0542
0543 #define LIST_FIRST(head) ((head)->lh_first)
0544
0545 #define LIST_FOREACH(var, head, field) \
0546 for ((var) = LIST_FIRST((head)); \
0547 (var); \
0548 (var) = LIST_NEXT((var), field))
0549
0550 #define LIST_FOREACH_FROM(var, head, field) \
0551 for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
0552 (var); \
0553 (var) = LIST_NEXT((var), field))
0554
0555 #define LIST_FOREACH_SAFE(var, head, field, tvar) \
0556 for ((var) = LIST_FIRST((head)); \
0557 (var) && ((tvar) = LIST_NEXT((var), field), 1); \
0558 (var) = (tvar))
0559
0560 #define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \
0561 for ((var) = ((var) ? (var) : LIST_FIRST((head))); \
0562 (var) && ((tvar) = LIST_NEXT((var), field), 1); \
0563 (var) = (tvar))
0564
0565 #define LIST_INIT(head) do { \
0566 LIST_FIRST((head)) = NULL; \
0567 } while (0)
0568
0569 #define LIST_INSERT_AFTER(listelm, elm, field) do { \
0570 QMD_LIST_CHECK_NEXT(listelm, field); \
0571 if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
0572 LIST_NEXT((listelm), field)->field.le_prev = \
0573 &LIST_NEXT((elm), field); \
0574 LIST_NEXT((listelm), field) = (elm); \
0575 (elm)->field.le_prev = &LIST_NEXT((listelm), field); \
0576 } while (0)
0577
0578 #define LIST_INSERT_BEFORE(listelm, elm, field) do { \
0579 QMD_LIST_CHECK_PREV(listelm, field); \
0580 (elm)->field.le_prev = (listelm)->field.le_prev; \
0581 LIST_NEXT((elm), field) = (listelm); \
0582 *(listelm)->field.le_prev = (elm); \
0583 (listelm)->field.le_prev = &LIST_NEXT((elm), field); \
0584 } while (0)
0585
0586 #define LIST_INSERT_HEAD(head, elm, field) do { \
0587 QMD_LIST_CHECK_HEAD((head), field); \
0588 if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
0589 LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
0590 LIST_FIRST((head)) = (elm); \
0591 (elm)->field.le_prev = &LIST_FIRST((head)); \
0592 } while (0)
0593
0594 #define LIST_NEXT(elm, field) ((elm)->field.le_next)
0595
0596 #define LIST_PREV(elm, head, type, field) \
0597 ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
0598 __containerof((elm)->field.le_prev, \
0599 QUEUE_TYPEOF(type), field.le_next))
0600
0601 #define LIST_REMOVE(elm, field) do { \
0602 QMD_SAVELINK(oldnext, (elm)->field.le_next); \
0603 QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
0604 QMD_LIST_CHECK_NEXT(elm, field); \
0605 QMD_LIST_CHECK_PREV(elm, field); \
0606 if (LIST_NEXT((elm), field) != NULL) \
0607 LIST_NEXT((elm), field)->field.le_prev = \
0608 (elm)->field.le_prev; \
0609 *(elm)->field.le_prev = LIST_NEXT((elm), field); \
0610 TRASHIT(*oldnext); \
0611 TRASHIT(*oldprev); \
0612 } while (0)
0613
0614 #define LIST_SWAP(head1, head2, type, field) do { \
0615 QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
0616 LIST_FIRST((head1)) = LIST_FIRST((head2)); \
0617 LIST_FIRST((head2)) = swap_tmp; \
0618 if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
0619 swap_tmp->field.le_prev = &LIST_FIRST((head1)); \
0620 if ((swap_tmp = LIST_FIRST((head2))) != NULL) \
0621 swap_tmp->field.le_prev = &LIST_FIRST((head2)); \
0622 } while (0)
0623
0624 #define LIST_END(head) NULL
0625
0626
0627
0628
0629 #define TAILQ_HEAD(name, type) \
0630 struct name { \
0631 struct type *tqh_first; \
0632 struct type **tqh_last; \
0633 TRACEBUF \
0634 }
0635
0636 #define TAILQ_CLASS_HEAD(name, type) \
0637 struct name { \
0638 class type *tqh_first; \
0639 class type **tqh_last; \
0640 TRACEBUF \
0641 }
0642
0643 #define TAILQ_HEAD_INITIALIZER(head) \
0644 { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
0645
0646 #define TAILQ_ENTRY(type) \
0647 struct { \
0648 struct type *tqe_next; \
0649 struct type **tqe_prev; \
0650 TRACEBUF \
0651 }
0652
0653 #define TAILQ_CLASS_ENTRY(type) \
0654 struct { \
0655 class type *tqe_next; \
0656 class type **tqe_prev; \
0657 TRACEBUF \
0658 }
0659
0660
0661
0662
0663 #if (defined(_KERNEL) && defined(INVARIANTS))
0664
0665
0666
0667
0668
0669
0670 #define QMD_TAILQ_CHECK_HEAD(head, field) do { \
0671 if (!TAILQ_EMPTY(head) && \
0672 TAILQ_FIRST((head))->field.tqe_prev != \
0673 &TAILQ_FIRST((head))) \
0674 panic("Bad tailq head %p first->prev != head", (head)); \
0675 } while (0)
0676
0677
0678
0679
0680
0681
0682 #define QMD_TAILQ_CHECK_TAIL(head, field) do { \
0683 if (*(head)->tqh_last != NULL) \
0684 panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
0685 } while (0)
0686
0687
0688
0689
0690
0691
0692
0693 #define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
0694 if (TAILQ_NEXT((elm), field) != NULL && \
0695 TAILQ_NEXT((elm), field)->field.tqe_prev != \
0696 &((elm)->field.tqe_next)) \
0697 panic("Bad link elm %p next->prev != elm", (elm)); \
0698 } while (0)
0699
0700
0701
0702
0703
0704
0705 #define QMD_TAILQ_CHECK_PREV(elm, field) do { \
0706 if (*(elm)->field.tqe_prev != (elm)) \
0707 panic("Bad link elm %p prev->next != elm", (elm)); \
0708 } while (0)
0709 #else
0710 #define QMD_TAILQ_CHECK_HEAD(head, field)
0711 #define QMD_TAILQ_CHECK_TAIL(head, headname)
0712 #define QMD_TAILQ_CHECK_NEXT(elm, field)
0713 #define QMD_TAILQ_CHECK_PREV(elm, field)
0714 #endif
0715
0716 #define TAILQ_CONCAT(head1, head2, field) do { \
0717 if (!TAILQ_EMPTY(head2)) { \
0718 *(head1)->tqh_last = (head2)->tqh_first; \
0719 (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
0720 (head1)->tqh_last = (head2)->tqh_last; \
0721 TAILQ_INIT((head2)); \
0722 QMD_TRACE_HEAD(head1); \
0723 QMD_TRACE_HEAD(head2); \
0724 } \
0725 } while (0)
0726
0727 #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
0728
0729 #define TAILQ_FIRST(head) ((head)->tqh_first)
0730
0731 #define TAILQ_FOREACH(var, head, field) \
0732 for ((var) = TAILQ_FIRST((head)); \
0733 (var); \
0734 (var) = TAILQ_NEXT((var), field))
0735
0736 #define TAILQ_FOREACH_FROM(var, head, field) \
0737 for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
0738 (var); \
0739 (var) = TAILQ_NEXT((var), field))
0740
0741 #define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
0742 for ((var) = TAILQ_FIRST((head)); \
0743 (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
0744 (var) = (tvar))
0745
0746 #define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \
0747 for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \
0748 (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
0749 (var) = (tvar))
0750
0751 #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
0752 for ((var) = TAILQ_LAST((head), headname); \
0753 (var); \
0754 (var) = TAILQ_PREV((var), headname, field))
0755
0756 #define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \
0757 for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
0758 (var); \
0759 (var) = TAILQ_PREV((var), headname, field))
0760
0761 #define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
0762 for ((var) = TAILQ_LAST((head), headname); \
0763 (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
0764 (var) = (tvar))
0765
0766 #define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
0767 for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \
0768 (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
0769 (var) = (tvar))
0770
0771 #define TAILQ_INIT(head) do { \
0772 TAILQ_FIRST((head)) = NULL; \
0773 (head)->tqh_last = &TAILQ_FIRST((head)); \
0774 QMD_TRACE_HEAD(head); \
0775 } while (0)
0776
0777 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
0778 QMD_TAILQ_CHECK_NEXT(listelm, field); \
0779 if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
0780 TAILQ_NEXT((elm), field)->field.tqe_prev = \
0781 &TAILQ_NEXT((elm), field); \
0782 else { \
0783 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
0784 QMD_TRACE_HEAD(head); \
0785 } \
0786 TAILQ_NEXT((listelm), field) = (elm); \
0787 (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
0788 QMD_TRACE_ELEM(&(elm)->field); \
0789 QMD_TRACE_ELEM(&(listelm)->field); \
0790 } while (0)
0791
0792 #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
0793 QMD_TAILQ_CHECK_PREV(listelm, field); \
0794 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
0795 TAILQ_NEXT((elm), field) = (listelm); \
0796 *(listelm)->field.tqe_prev = (elm); \
0797 (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
0798 QMD_TRACE_ELEM(&(elm)->field); \
0799 QMD_TRACE_ELEM(&(listelm)->field); \
0800 } while (0)
0801
0802 #define TAILQ_INSERT_HEAD(head, elm, field) do { \
0803 QMD_TAILQ_CHECK_HEAD(head, field); \
0804 if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
0805 TAILQ_FIRST((head))->field.tqe_prev = \
0806 &TAILQ_NEXT((elm), field); \
0807 else \
0808 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
0809 TAILQ_FIRST((head)) = (elm); \
0810 (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
0811 QMD_TRACE_HEAD(head); \
0812 QMD_TRACE_ELEM(&(elm)->field); \
0813 } while (0)
0814
0815 #define TAILQ_INSERT_TAIL(head, elm, field) do { \
0816 QMD_TAILQ_CHECK_TAIL(head, field); \
0817 TAILQ_NEXT((elm), field) = NULL; \
0818 (elm)->field.tqe_prev = (head)->tqh_last; \
0819 *(head)->tqh_last = (elm); \
0820 (head)->tqh_last = &TAILQ_NEXT((elm), field); \
0821 QMD_TRACE_HEAD(head); \
0822 QMD_TRACE_ELEM(&(elm)->field); \
0823 } while (0)
0824
0825 #define TAILQ_LAST(head, headname) \
0826 (*(((struct headname *)((head)->tqh_last))->tqh_last))
0827
0828
0829
0830
0831
0832
0833
0834
0835 #define TAILQ_LAST_FAST(head, type, field) \
0836 (TAILQ_EMPTY(head) ? NULL : __containerof((head)->tqh_last, QUEUE_TYPEOF(type), field.tqe_next))
0837
0838 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
0839
0840 #define TAILQ_PREV(elm, headname, field) \
0841 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
0842
0843 #define TAILQ_PREV_FAST(elm, head, type, field) \
0844 ((elm)->field.tqe_prev == &(head)->tqh_first ? NULL : \
0845 __containerof((elm)->field.tqe_prev, QUEUE_TYPEOF(type), field.tqe_next))
0846
0847 #define TAILQ_REMOVE(head, elm, field) do { \
0848 QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
0849 QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
0850 QMD_TAILQ_CHECK_NEXT(elm, field); \
0851 QMD_TAILQ_CHECK_PREV(elm, field); \
0852 if ((TAILQ_NEXT((elm), field)) != NULL) \
0853 TAILQ_NEXT((elm), field)->field.tqe_prev = \
0854 (elm)->field.tqe_prev; \
0855 else { \
0856 (head)->tqh_last = (elm)->field.tqe_prev; \
0857 QMD_TRACE_HEAD(head); \
0858 } \
0859 *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
0860 TRASHIT(*oldnext); \
0861 TRASHIT(*oldprev); \
0862 QMD_TRACE_ELEM(&(elm)->field); \
0863 } while (0)
0864
0865 #define TAILQ_SWAP(head1, head2, type, field) do { \
0866 QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
0867 QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
0868 (head1)->tqh_first = (head2)->tqh_first; \
0869 (head1)->tqh_last = (head2)->tqh_last; \
0870 (head2)->tqh_first = swap_first; \
0871 (head2)->tqh_last = swap_last; \
0872 if ((swap_first = (head1)->tqh_first) != NULL) \
0873 swap_first->field.tqe_prev = &(head1)->tqh_first; \
0874 else \
0875 (head1)->tqh_last = &(head1)->tqh_first; \
0876 if ((swap_first = (head2)->tqh_first) != NULL) \
0877 swap_first->field.tqe_prev = &(head2)->tqh_first; \
0878 else \
0879 (head2)->tqh_last = &(head2)->tqh_first; \
0880 } while (0)
0881
0882 #define TAILQ_END(head) NULL
0883
0884 #endif