00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _XENO_NUCLEUS_QUEUE_H
00022 #define _XENO_NUCLEUS_QUEUE_H
00023
00024 #include <nucleus/types.h>
00025 #include <nucleus/core.h>
00026
00027
00028 #include <nucleus/assert.h>
00029
00030 #ifndef CONFIG_XENO_OPT_DEBUG_QUEUES
00031 #define CONFIG_XENO_OPT_DEBUG_QUEUES 0
00032 #endif
00033
00034
00035
00036 typedef struct xnholder {
00037
00038 struct xnholder *next;
00039 struct xnholder *last;
00040
00041 } xnholder_t;
00042
00043 static inline void inith(xnholder_t *holder)
00044 {
00045
00046 holder->last = holder;
00047 holder->next = holder;
00048 }
00049
00050 static inline void ath(xnholder_t *head, xnholder_t *holder)
00051 {
00052
00053 holder->last = head;
00054 holder->next = head->next;
00055 holder->next->last = holder;
00056 head->next = holder;
00057 }
00058
00059 static inline void dth(xnholder_t *holder)
00060 {
00061 holder->last->next = holder->next;
00062 holder->next->last = holder->last;
00063 }
00064
00065
00066
00067 typedef struct xnqueue {
00068
00069 xnholder_t head;
00070 int elems;
00071 #if defined(__KERNEL__) && XENO_DEBUG(QUEUES) && defined(CONFIG_SMP)
00072 xnlock_t lock;
00073 #endif
00074
00075 } xnqueue_t;
00076
00077 #if XENO_DEBUG(QUEUES) && defined(CONFIG_SMP)
00078 #define XNQUEUE_INITIALIZER(q) { { &(q).head, &(q).head }, 0, XNARCH_LOCK_UNLOCKED }
00079 #else
00080 #define XNQUEUE_INITIALIZER(q) { { &(q).head, &(q).head }, 0 }
00081 #endif
00082
00083 #define DEFINE_XNQUEUE(q) xnqueue_t q = XNQUEUE_INITIALIZER(q)
00084
00085 static inline void initq(xnqueue_t *qslot)
00086 {
00087 inith(&qslot->head);
00088 qslot->elems = 0;
00089 #if defined(__KERNEL__) && XENO_DEBUG(QUEUES) && defined(CONFIG_SMP)
00090 xnlock_init(&qslot->lock);
00091 #endif
00092 }
00093
00094 #if XENO_DEBUG(QUEUES)
00095
00096 #if defined(__KERNEL__) || defined(__XENO_SIM__)
00097
00098 #define XENO_DEBUG_CHECK_QUEUE(__qslot) \
00099 do { \
00100 xnholder_t *curr; \
00101 spl_t s; \
00102 int nelems = 0; \
00103 xnlock_get_irqsave(&(__qslot)->lock,s); \
00104 curr = (__qslot)->head.last; \
00105 while (curr != &(__qslot)->head && nelems < (__qslot)->elems) \
00106 curr = curr->last, nelems++; \
00107 if (curr != &(__qslot)->head || nelems != (__qslot)->elems) \
00108 xnpod_fatal("corrupted queue, qslot->elems=%d/%d, qslot=%p at %s:%d", \
00109 nelems, \
00110 (__qslot)->elems, \
00111 __qslot, \
00112 __FILE__,__LINE__); \
00113 xnlock_put_irqrestore(&(__qslot)->lock,s); \
00114 } while(0)
00115
00116 #define XENO_DEBUG_INSERT_QUEUE(__qslot,__holder) \
00117 do { \
00118 xnholder_t *curr; \
00119 spl_t s; \
00120 xnlock_get_irqsave(&(__qslot)->lock,s); \
00121 curr = (__qslot)->head.last; \
00122 while (curr != &(__qslot)->head && (__holder) != curr) \
00123 curr = curr->last; \
00124 if (curr == (__holder)) \
00125 xnpod_fatal("inserting element twice, holder=%p, qslot=%p at %s:%d", \
00126 __holder, \
00127 __qslot, \
00128 __FILE__,__LINE__); \
00129 if ((__holder)->last == NULL) \
00130 xnpod_fatal("holder=%p not initialized, qslot=%p", \
00131 __holder, \
00132 __qslot); \
00133 xnlock_put_irqrestore(&(__qslot)->lock,s); \
00134 } while(0)
00135
00136 #define XENO_DEBUG_REMOVE_QUEUE(__qslot,__holder) \
00137 do { \
00138 xnholder_t *curr; \
00139 spl_t s; \
00140 xnlock_get_irqsave(&(__qslot)->lock,s); \
00141 curr = (__qslot)->head.last; \
00142 while (curr != &(__qslot)->head && (__holder) != curr) \
00143 curr = curr->last; \
00144 if (curr == &(__qslot)->head) \
00145 xnpod_fatal("removing non-linked element, holder=%p, qslot=%p at %s:%d", \
00146 __holder, \
00147 __qslot, \
00148 __FILE__,__LINE__); \
00149 xnlock_put_irqrestore(&(__qslot)->lock,s); \
00150 } while(0)
00151
00152 #else
00153
00154
00155
00156
00157 #define XENO_DEBUG_CHECK_QUEUE(__qslot)
00158 #define XENO_DEBUG_INSERT_QUEUE(__qslot,__holder)
00159 #define XENO_DEBUG_REMOVE_QUEUE(__qslot,__holder)
00160
00161 #endif
00162
00163
00164
00165
00166 #define insertq(__qslot,__head,__holder) \
00167 ({ XENO_DEBUG_CHECK_QUEUE(__qslot); \
00168 XENO_DEBUG_INSERT_QUEUE(__qslot,__holder); \
00169 ath((__head)->last,__holder); \
00170 ++(__qslot)->elems; })
00171
00172 #define prependq(__qslot,__holder) \
00173 ({ XENO_DEBUG_CHECK_QUEUE(__qslot); \
00174 XENO_DEBUG_INSERT_QUEUE(__qslot,__holder); \
00175 ath(&(__qslot)->head,__holder); \
00176 ++(__qslot)->elems; })
00177
00178 #define appendq(__qslot,__holder) \
00179 ({ XENO_DEBUG_CHECK_QUEUE(__qslot); \
00180 XENO_DEBUG_INSERT_QUEUE(__qslot,__holder); \
00181 ath((__qslot)->head.last,__holder); \
00182 ++(__qslot)->elems; })
00183
00184 #define removeq(__qslot,__holder) \
00185 ({ XENO_DEBUG_CHECK_QUEUE(__qslot); \
00186 XENO_DEBUG_REMOVE_QUEUE(__qslot,__holder); \
00187 dth(__holder); \
00188 --(__qslot)->elems; })
00189
00190 #else
00191
00192 static inline void insertq(xnqueue_t *qslot,
00193 xnholder_t *head, xnholder_t *holder)
00194 {
00195
00196 ath(head->last, holder);
00197 ++qslot->elems;
00198 }
00199
00200 static inline void prependq(xnqueue_t *qslot, xnholder_t *holder)
00201 {
00202
00203 ath(&qslot->head, holder);
00204 ++qslot->elems;
00205 }
00206
00207 static inline void appendq(xnqueue_t *qslot, xnholder_t *holder)
00208 {
00209
00210 ath(qslot->head.last, holder);
00211 ++qslot->elems;
00212 }
00213
00214 static inline void removeq(xnqueue_t *qslot, xnholder_t *holder)
00215 {
00216 dth(holder);
00217 --qslot->elems;
00218 }
00219
00220 #endif
00221
00222 static inline xnholder_t *getheadq(xnqueue_t *qslot)
00223 {
00224 xnholder_t *holder = qslot->head.next;
00225 return holder == &qslot->head ? NULL : holder;
00226 }
00227
00228 static inline xnholder_t *getq(xnqueue_t *qslot)
00229 {
00230 xnholder_t *holder = getheadq(qslot);
00231 if (holder)
00232 removeq(qslot, holder);
00233 return holder;
00234 }
00235
00236 static inline xnholder_t *nextq(xnqueue_t *qslot, xnholder_t *holder)
00237 {
00238 xnholder_t *nextholder = holder->next;
00239 return nextholder == &qslot->head ? NULL : nextholder;
00240 }
00241
00242 static inline xnholder_t *popq(xnqueue_t *qslot, xnholder_t *holder)
00243 {
00244 xnholder_t *nextholder = nextq(qslot, holder);
00245 removeq(qslot, holder);
00246 return nextholder;
00247 }
00248
00249 static inline int countq(xnqueue_t *qslot)
00250 {
00251 return qslot->elems;
00252 }
00253
00254 static inline int emptyq_p(xnqueue_t *qslot)
00255 {
00256 return qslot->head.next == &qslot->head;
00257 }
00258
00259 static inline void moveq(xnqueue_t *dstq, xnqueue_t *srcq)
00260 {
00261 xnholder_t *headsrc = srcq->head.next;
00262 xnholder_t *tailsrc = srcq->head.last;
00263 xnholder_t *headdst = &dstq->head;
00264
00265 if (emptyq_p(srcq))
00266 return;
00267
00268 headsrc->last->next = tailsrc->next;
00269 tailsrc->next->last = headsrc->last;
00270 headsrc->last = headdst;
00271 tailsrc->next = headdst->next;
00272 headdst->next->last = tailsrc;
00273 headdst->next = headsrc;
00274 dstq->elems += srcq->elems;
00275 srcq->elems = 0;
00276 }
00277
00278
00279
00280 typedef struct xnpholder {
00281
00282 xnholder_t plink;
00283 int prio;
00284
00285 } xnpholder_t;
00286
00287 static inline void initph(xnpholder_t *holder)
00288 {
00289 inith(&holder->plink);
00290
00291 }
00292
00293
00294
00295
00296 typedef struct xnpqueue { xnqueue_t pqueue; } xnpqueue_t;
00297
00298 static inline void initpq(xnpqueue_t *pqslot)
00299 {
00300 initq(&pqslot->pqueue);
00301 }
00302
00303 static inline void insertpq(xnpqueue_t *pqslot,
00304 xnpholder_t *head, xnpholder_t *holder)
00305 {
00306
00307 insertq(&pqslot->pqueue, &head->plink, &holder->plink);
00308 }
00309
00310 static inline void insertpqf(xnpqueue_t *pqslot, xnpholder_t *holder, int prio)
00311 {
00312
00313
00314 xnholder_t *curr;
00315
00316 for (curr = pqslot->pqueue.head.last;
00317 curr != &pqslot->pqueue.head; curr = curr->last) {
00318 if (prio <= ((xnpholder_t *)curr)->prio)
00319 break;
00320 }
00321
00322 holder->prio = prio;
00323
00324 insertq(&pqslot->pqueue, curr->next, &holder->plink);
00325 }
00326
00327 static inline void insertpql(xnpqueue_t *pqslot, xnpholder_t *holder, int prio)
00328 {
00329
00330
00331 xnholder_t *curr;
00332
00333 for (curr = pqslot->pqueue.head.next;
00334 curr != &pqslot->pqueue.head; curr = curr->next) {
00335 if (prio >= ((xnpholder_t *)curr)->prio)
00336 break;
00337 }
00338
00339 holder->prio = prio;
00340
00341 insertq(&pqslot->pqueue, curr, &holder->plink);
00342 }
00343
00344 static inline xnpholder_t *findpqh(xnpqueue_t *pqslot, int prio)
00345 {
00346
00347
00348 xnholder_t *curr;
00349
00350 for (curr = pqslot->pqueue.head.next;
00351 curr != &pqslot->pqueue.head; curr = curr->next) {
00352 if (prio >= ((xnpholder_t *)curr)->prio)
00353 break;
00354 }
00355
00356 if (curr && ((xnpholder_t *)curr)->prio == prio)
00357 return (xnpholder_t *)curr;
00358
00359 return NULL;
00360 }
00361
00362 static inline void insertpqfr(xnpqueue_t *pqslot, xnpholder_t *holder, int prio)
00363 {
00364
00365
00366
00367
00368
00369 xnholder_t *curr;
00370
00371 for (curr = pqslot->pqueue.head.last;
00372 curr != &pqslot->pqueue.head; curr = curr->last) {
00373 if (prio >= ((xnpholder_t *)curr)->prio)
00374 break;
00375 }
00376
00377 holder->prio = prio;
00378
00379 insertq(&pqslot->pqueue, curr->next, &holder->plink);
00380 }
00381
00382 static inline void insertpqlr(xnpqueue_t *pqslot, xnpholder_t *holder, int prio)
00383 {
00384
00385
00386
00387
00388
00389 xnholder_t *curr;
00390
00391 for (curr = pqslot->pqueue.head.next;
00392 curr != &pqslot->pqueue.head; curr = curr->next) {
00393 if (prio <= ((xnpholder_t *)curr)->prio)
00394 break;
00395 }
00396
00397 holder->prio = prio;
00398
00399 insertq(&pqslot->pqueue, curr, &holder->plink);
00400 }
00401
00402 static inline xnpholder_t *findpqhr(xnpqueue_t *pqslot, int prio)
00403 {
00404
00405
00406
00407
00408
00409 xnholder_t *curr;
00410
00411 for (curr = pqslot->pqueue.head.next;
00412 curr != &pqslot->pqueue.head; curr = curr->next) {
00413 if (prio <= ((xnpholder_t *)curr)->prio)
00414 break;
00415 }
00416
00417 if (curr && ((xnpholder_t *)curr)->prio == prio)
00418 return (xnpholder_t *)curr;
00419
00420 return NULL;
00421 }
00422
00423 static inline void appendpq(xnpqueue_t *pqslot, xnpholder_t *holder)
00424 {
00425 holder->prio = 0;
00426 appendq(&pqslot->pqueue, &holder->plink);
00427 }
00428
00429 static inline void prependpq(xnpqueue_t *pqslot, xnpholder_t *holder)
00430 {
00431 holder->prio = 0;
00432 prependq(&pqslot->pqueue, &holder->plink);
00433 }
00434
00435 static inline void removepq(xnpqueue_t *pqslot, xnpholder_t *holder)
00436 {
00437 removeq(&pqslot->pqueue, &holder->plink);
00438 }
00439
00440 static inline xnpholder_t *getheadpq(xnpqueue_t *pqslot)
00441 {
00442 return (xnpholder_t *)getheadq(&pqslot->pqueue);
00443 }
00444
00445 static inline xnpholder_t *nextpq(xnpqueue_t *pqslot, xnpholder_t *holder)
00446 {
00447 return (xnpholder_t *)nextq(&pqslot->pqueue, &holder->plink);
00448 }
00449
00450 static inline xnpholder_t *getpq(xnpqueue_t *pqslot)
00451 {
00452 return (xnpholder_t *)getq(&pqslot->pqueue);
00453 }
00454
00455 static inline xnpholder_t *poppq(xnpqueue_t *pqslot, xnpholder_t *holder)
00456 {
00457 return (xnpholder_t *)popq(&pqslot->pqueue, &holder->plink);
00458 }
00459
00460 static inline int countpq(xnpqueue_t *pqslot)
00461 {
00462 return countq(&pqslot->pqueue);
00463 }
00464
00465 static inline int emptypq_p(xnpqueue_t *pqslot)
00466 {
00467 return emptyq_p(&pqslot->pqueue);
00468 }
00469
00470
00471
00472 typedef struct xngholder {
00473
00474 xnpholder_t glink;
00475 void *data;
00476
00477 } xngholder_t;
00478
00479 static inline void initgh(xngholder_t *holder, void *data)
00480 {
00481 inith(&holder->glink.plink);
00482 holder->data = data;
00483 }
00484
00485
00486
00487 typedef struct xngqueue {
00488
00489 xnpqueue_t gqueue;
00490 xnqueue_t *freehq;
00491 void (*starvation) (xnqueue_t *);
00492 int threshold;
00493
00494 } xngqueue_t;
00495
00496 static inline void initgq(xngqueue_t *gqslot,
00497 xnqueue_t *freehq,
00498 void (*starvation) (xnqueue_t *),
00499 int threshold)
00500 {
00501 initpq(&gqslot->gqueue);
00502 gqslot->freehq = freehq;
00503 gqslot->starvation = starvation;
00504 gqslot->threshold = threshold;
00505 }
00506
00507 static inline xngholder_t *allocgh(xngqueue_t *gqslot)
00508 {
00509 if (countq(gqslot->freehq) < gqslot->threshold)
00510 gqslot->starvation(gqslot->freehq);
00511
00512 return (xngholder_t *)getq(gqslot->freehq);
00513 }
00514
00515 static inline void *removegh(xngqueue_t *gqslot, xngholder_t *holder)
00516 {
00517 removepq(&gqslot->gqueue, &holder->glink);
00518 appendq(gqslot->freehq, &holder->glink.plink);
00519 return holder->data;
00520 }
00521
00522 static inline void insertgqf(xngqueue_t *gqslot, void *data, int prio)
00523 {
00524 xngholder_t *holder = allocgh(gqslot);
00525 holder->data = data;
00526 return insertpqf(&gqslot->gqueue, &holder->glink, prio);
00527 }
00528
00529 static inline void insertgql(xngqueue_t *gqslot, void *data, int prio)
00530 {
00531 xngholder_t *holder = allocgh(gqslot);
00532 holder->data = data;
00533 insertpql(&gqslot->gqueue, &holder->glink, prio);
00534 }
00535
00536 static inline void appendgq(xngqueue_t *gqslot, void *data)
00537 {
00538 xngholder_t *holder = allocgh(gqslot);
00539 holder->data = data;
00540 appendpq(&gqslot->gqueue, &holder->glink);
00541 }
00542
00543 static inline void prependgq(xngqueue_t *gqslot, void *data)
00544 {
00545 xngholder_t *holder = allocgh(gqslot);
00546 holder->data = data;
00547 prependpq(&gqslot->gqueue, &holder->glink);
00548 }
00549
00550 static inline xngholder_t *getheadgq(xngqueue_t *gqslot)
00551 {
00552 return (xngholder_t *)getheadpq(&gqslot->gqueue);
00553 }
00554
00555 static inline xngholder_t *nextgq(xngqueue_t *gqslot, xngholder_t *holder)
00556 {
00557 return (xngholder_t *)nextpq(&gqslot->gqueue, &holder->glink);
00558 }
00559
00560 static inline void *getgq(xngqueue_t *gqslot)
00561 {
00562 xngholder_t *holder = getheadgq(gqslot);
00563
00564 if (!holder)
00565 return NULL;
00566
00567 appendq(gqslot->freehq, &getpq(&gqslot->gqueue)->plink);
00568
00569 return holder->data;
00570 }
00571
00572 static inline xngholder_t *popgq(xngqueue_t *gqslot, xngholder_t *holder)
00573 {
00574 xngholder_t *nextholder = nextgq(gqslot, holder);
00575 removegh(gqslot, holder);
00576 return nextholder;
00577 }
00578
00579 static inline xngholder_t *findgq(xngqueue_t *gqslot, void *data)
00580 {
00581 xnholder_t *holder;
00582
00583 for (holder = gqslot->gqueue.pqueue.head.next;
00584 holder != &gqslot->gqueue.pqueue.head; holder = holder->next) {
00585 if (((xngholder_t *)holder)->data == data)
00586 return (xngholder_t *)holder;
00587 }
00588
00589 return NULL;
00590 }
00591
00592 static inline void *removegq(xngqueue_t *gqslot, void *data)
00593 {
00594 xngholder_t *holder = findgq(gqslot, data);
00595 return holder ? removegh(gqslot, holder) : NULL;
00596 }
00597
00598 static inline int countgq(xngqueue_t *gqslot)
00599 {
00600 return countpq(&gqslot->gqueue);
00601 }
00602
00603 static inline int emptygq_p(xngqueue_t *gqslot)
00604 {
00605 return emptypq_p(&gqslot->gqueue);
00606 }
00607
00608 #ifdef CONFIG_XENO_OPT_SCALABLE_SCHED
00609
00610
00611
00612
00613
00614 #if BITS_PER_LONG * BITS_PER_LONG < XNCORE_NR_PRIO
00615 #error "Internal bitmap cannot hold so many priority levels"
00616 #endif
00617
00618 #define __MLQ_LONGS ((XNCORE_NR_PRIO+BITS_PER_LONG-1)/BITS_PER_LONG)
00619
00620 typedef struct xnmlqueue {
00621
00622 int loprio, hiprio, elems;
00623
00624 u_long himap, lomap[__MLQ_LONGS];
00625
00626 struct xnqueue queue[XNCORE_NR_PRIO];
00627
00628 } xnmlqueue_t;
00629
00630 #undef __MLQ_LONGS
00631
00632 static inline int countmlq(xnmlqueue_t *mlqslot)
00633 {
00634 return mlqslot->elems;
00635 }
00636
00637 static inline int emptymlq_p(xnmlqueue_t *mlqslot)
00638 {
00639 return mlqslot->himap == 0;
00640 }
00641
00642 static inline int indexmlq(xnmlqueue_t *mlqslot, int prio)
00643 {
00644
00645
00646
00647
00648
00649 return mlqslot->hiprio - prio;
00650 }
00651
00652 static inline int ffsmlq(xnmlqueue_t *mlqslot)
00653 {
00654 int hi = ffnz(mlqslot->himap);
00655 int lo = ffnz(mlqslot->lomap[hi]);
00656 return hi * BITS_PER_LONG + lo;
00657 }
00658
00659 static inline void initmlq(xnmlqueue_t *mlqslot, int loprio, int hiprio)
00660 {
00661 int prio;
00662
00663 mlqslot->elems = 0;
00664 mlqslot->loprio = loprio;
00665 mlqslot->hiprio = hiprio;
00666 mlqslot->himap = 0;
00667 memset(&mlqslot->lomap, 0, sizeof(mlqslot->lomap));
00668
00669 for (prio = 0; prio < XNCORE_NR_PRIO; prio++)
00670 initq(&mlqslot->queue[prio]);
00671
00672 XENO_ASSERT(NUCLEUS,
00673 hiprio - loprio < XNCORE_NR_PRIO,
00674 xnpod_fatal("priority range [%d..%d] is beyond multi-level "
00675 "queue indexing capabilities",
00676 loprio, hiprio));
00677 }
00678
00679 #define XNMLQUEUE_APPEND 0
00680 #define XNMLQUEUE_PREPEND 1
00681
00682 static inline void addmlq(xnmlqueue_t *mlqslot,
00683 xnpholder_t *holder, int idx, int mode)
00684 {
00685 xnqueue_t *queue = &mlqslot->queue[idx];
00686 int hi = idx / BITS_PER_LONG;
00687 int lo = idx % BITS_PER_LONG;
00688
00689 if (mode == XNMLQUEUE_PREPEND)
00690 prependq(queue, &holder->plink);
00691 else
00692 appendq(queue, &holder->plink);
00693
00694 holder->prio = idx;
00695 mlqslot->elems++;
00696 __setbits(mlqslot->himap, 1UL << hi);
00697 __setbits(mlqslot->lomap[hi], 1UL << lo);
00698 }
00699
00700 static inline void insertmlql(xnmlqueue_t *mlqslot,
00701 xnpholder_t *holder, int prio)
00702 {
00703 addmlq(mlqslot, holder, indexmlq(mlqslot, prio), XNMLQUEUE_PREPEND);
00704 }
00705
00706 static inline void insertmlqf(xnmlqueue_t *mlqslot,
00707 xnpholder_t *holder, int prio)
00708 {
00709 addmlq(mlqslot, holder, indexmlq(mlqslot, prio), XNMLQUEUE_APPEND);
00710 }
00711
00712 static inline void appendmlq(xnmlqueue_t *mlqslot, xnpholder_t *holder)
00713 {
00714 addmlq(mlqslot, holder, indexmlq(mlqslot, mlqslot->hiprio),
00715 XNMLQUEUE_APPEND);
00716 }
00717
00718 static inline void prependmlq(xnmlqueue_t *mlqslot, xnpholder_t *holder)
00719 {
00720 addmlq(mlqslot, holder, indexmlq(mlqslot, mlqslot->loprio),
00721 XNMLQUEUE_PREPEND);
00722 }
00723
00724 static inline void removemlq(xnmlqueue_t *mlqslot, xnpholder_t *holder)
00725 {
00726 int idx = holder->prio;
00727 xnqueue_t *queue = &mlqslot->queue[idx];
00728
00729 mlqslot->elems--;
00730
00731 removeq(queue, &holder->plink);
00732
00733 if (emptyq_p(queue)) {
00734 int hi = idx / BITS_PER_LONG;
00735 int lo = idx % BITS_PER_LONG;
00736 __clrbits(mlqslot->lomap[hi], 1UL << lo);
00737 if (mlqslot->lomap[hi] == 0)
00738 __clrbits(mlqslot->himap, 1UL << hi);
00739 }
00740 }
00741
00742 static inline xnpholder_t *findmlqh(xnmlqueue_t *mlqslot, int prio)
00743 {
00744 xnqueue_t *queue = &mlqslot->queue[indexmlq(mlqslot, prio)];
00745 return (xnpholder_t *)getheadq(queue);
00746 }
00747
00748 static inline xnpholder_t *getheadmlq(xnmlqueue_t *mlqslot)
00749 {
00750 xnpholder_t *holder;
00751 xnqueue_t *queue;
00752
00753 if (emptymlq_p(mlqslot))
00754 return NULL;
00755
00756 queue = &mlqslot->queue[ffsmlq(mlqslot)];
00757 holder = (xnpholder_t *)getheadq(queue);
00758
00759 XENO_ASSERT(QUEUES, holder,
00760 xnpod_fatal
00761 ("corrupted multi-level queue, qslot=%p at %s:%d", mlqslot,
00762 __FILE__, __LINE__);
00763 );
00764
00765 return holder;
00766 }
00767
00768 static inline xnpholder_t *getmlq(xnmlqueue_t *mlqslot)
00769 {
00770 xnholder_t *holder;
00771 xnqueue_t *queue;
00772 int idx, hi, lo;
00773
00774 if (emptymlq_p(mlqslot))
00775 return NULL;
00776
00777 idx = ffsmlq(mlqslot);
00778 queue = &mlqslot->queue[idx];
00779 holder = getq(queue);
00780
00781 XENO_ASSERT(QUEUES, holder,
00782 xnpod_fatal
00783 ("corrupted multi-level queue, qslot=%p at %s:%d", mlqslot,
00784 __FILE__, __LINE__);
00785 );
00786
00787 mlqslot->elems--;
00788
00789 if (emptyq_p(queue)) {
00790 hi = idx / BITS_PER_LONG;
00791 lo = idx % BITS_PER_LONG;
00792 __clrbits(mlqslot->lomap[hi], 1UL << lo);
00793 if (mlqslot->lomap[hi] == 0)
00794 __clrbits(mlqslot->himap, 1UL << hi);
00795 }
00796
00797 return (xnpholder_t *)holder;
00798 }
00799
00800 #endif
00801
00802 #endif