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