Xenomai API
2.5.6.1
|
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 */