Xenomai API  2.5.6.1
include/nucleus/schedqueue.h
00001 /*
00002  * Copyright (C) 2008 Philippe Gerum <[email protected]>.
00003  *
00004  * Xenomai is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published
00006  * by the Free Software Foundation; either version 2 of the License,
00007  * or (at your option) any later version.
00008  *
00009  * Xenomai is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with Xenomai; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00017  * 02111-1307, USA.
00018  */
00019 
00020 #ifndef _XENO_NUCLEUS_SCHEDQUEUE_H
00021 #define _XENO_NUCLEUS_SCHEDQUEUE_H
00022 
00023 #include <nucleus/queue.h>
00024 
00025 #ifdef CONFIG_XENO_OPT_SCALABLE_SCHED
00026 /*
00027  * Multi-level priority queue, suitable for handling the runnable
00028  * thread queue of a scheduling class with O(1) property. We only
00029  * manage a descending queuing order, i.e. highest numbered priorities
00030  * come first.
00031  */
00032 #define XNSCHED_MLQ_LEVELS  264
00033 
00034 #if BITS_PER_LONG * BITS_PER_LONG < XNSCHED_MLQ_LEVELS
00035 #error "Internal bitmap cannot hold so many priority levels"
00036 #endif
00037 
00038 #define __MLQ_LONGS ((XNSCHED_MLQ_LEVELS+BITS_PER_LONG-1)/BITS_PER_LONG)
00039 
00040 struct xnsched_mlq {
00041 
00042         int loprio, hiprio, elems;
00043         unsigned long himap, lomap[__MLQ_LONGS];
00044         struct xnqueue queue[XNSCHED_MLQ_LEVELS];
00045 
00046 };
00047 
00048 #undef __MLQ_LONGS
00049 
00050 void initmlq(struct xnsched_mlq *q, int loprio, int hiprio);
00051 
00052 void addmlq(struct xnsched_mlq *q,
00053             struct xnpholder *holder, int idx, int lifo);
00054 
00055 void removemlq(struct xnsched_mlq *q, struct xnpholder *holder);
00056 
00057 struct xnpholder *findmlqh(struct xnsched_mlq *q, int prio);
00058 
00059 struct xnpholder *getheadmlq(struct xnsched_mlq *q);
00060 
00061 struct xnpholder *getmlq(struct xnsched_mlq *q);
00062 
00063 struct xnpholder *nextmlq(struct xnsched_mlq *q,
00064                           struct xnpholder *h);
00065 
00066 static inline int countmlq(struct xnsched_mlq *q)
00067 {
00068         return q->elems;
00069 }
00070 
00071 static inline int emptymlq_p(struct xnsched_mlq *q)
00072 {
00073         return q->himap == 0;
00074 }
00075 
00076 static inline int indexmlq(struct xnsched_mlq *q, int prio)
00077 {
00078         XENO_ASSERT(QUEUES,
00079                     prio >= q->loprio && prio <= q->hiprio,
00080                     xnpod_fatal("priority level %d is out of range ", prio));
00081         /*
00082          * BIG FAT WARNING: We need to rescale the priority level to a
00083          * 0-based range. We use ffnz() to scan the bitmap which MUST
00084          * be based on a bit scan forward op. Therefore, the lower the
00085          * index value, the higher the priority (since least
00086          * significant bits will be found first when scanning the
00087          * bitmaps).
00088          */
00089         return q->hiprio - prio;
00090 }
00091 
00092 static inline int ffsmlq(struct xnsched_mlq *q)
00093 {
00094         int hi = ffnz(q->himap);
00095         int lo = ffnz(q->lomap[hi]);
00096         return hi * BITS_PER_LONG + lo; /* Result is undefined if none set. */
00097 }
00098 
00099 static inline void insertmlql(struct xnsched_mlq *q,
00100                               struct xnpholder *holder, int prio)
00101 {
00102         addmlq(q, holder, indexmlq(q, prio), 1);
00103 }
00104 
00105 static inline void insertmlqf(struct xnsched_mlq *q,
00106                               struct xnpholder *holder, int prio)
00107 {
00108         addmlq(q, holder, indexmlq(q, prio), 0);
00109 }
00110 
00111 static inline void appendmlq(struct xnsched_mlq *q, struct xnpholder *holder)
00112 {
00113         addmlq(q, holder, indexmlq(q, q->hiprio), 0);
00114 }
00115 
00116 static inline void prependmlq(struct xnsched_mlq *q, struct xnpholder *holder)
00117 {
00118         addmlq(q, holder, indexmlq(q, q->loprio), 1);
00119 }
00120 
00121 typedef struct xnsched_mlq xnsched_queue_t;
00122 
00123 #define sched_initpq            initmlq
00124 #define sched_emptypq_p         emptymlq_p
00125 #define sched_insertpql         insertmlql
00126 #define sched_insertpqf         insertmlqf
00127 #define sched_appendpq          appendmlq
00128 #define sched_prependpq         prependmlq
00129 #define sched_removepq          removemlq
00130 #define sched_getheadpq         getheadmlq
00131 #define sched_nextpq            nextmlq
00132 #define sched_getpq             getmlq
00133 #define sched_findpqh           findmlqh
00134 
00135 #else /* ! CONFIG_XENO_OPT_SCALABLE_SCHED */
00136 
00137 typedef xnpqueue_t xnsched_queue_t;
00138 
00139 #define sched_initpq(q, minp, maxp)     initpq(q)
00140 #define sched_emptypq_p                 emptypq_p
00141 #define sched_insertpql                 insertpql
00142 #define sched_insertpqf                 insertpqf
00143 #define sched_appendpq                  appendpq
00144 #define sched_prependpq                 prependpq
00145 #define sched_removepq                  removepq
00146 #define sched_getheadpq                 getheadpq
00147 #define sched_nextpq                    nextpq
00148 #define sched_getpq                     getpq
00149 #define sched_findpqh                   findpqh
00150 
00151 #endif /* !CONFIG_XENO_OPT_SCALABLE_SCHED */
00152 
00153 #endif /* !_XENO_NUCLEUS_SCHEDQUEUE_H */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines