|
ChibiOS/RT
2.5.1 |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 00003 2011,2012 Giovanni Di Sirio. 00004 00005 This file is part of ChibiOS/RT. 00006 00007 ChibiOS/RT is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 ChibiOS/RT is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 /** 00022 * @file chschd.h 00023 * @brief Scheduler macros and structures. 00024 * 00025 * @addtogroup scheduler 00026 * @{ 00027 */ 00028 00029 #ifndef _CHSCHD_H_ 00030 #define _CHSCHD_H_ 00031 00032 /** 00033 * @name Wakeup status codes 00034 * @{ 00035 */ 00036 #define RDY_OK 0 /**< @brief Normal wakeup message. */ 00037 #define RDY_TIMEOUT -1 /**< @brief Wakeup caused by a timeout 00038 condition. */ 00039 #define RDY_RESET -2 /**< @brief Wakeup caused by a reset 00040 condition. */ 00041 /** @} */ 00042 00043 /** 00044 * @name Priority constants 00045 * @{ 00046 */ 00047 #define NOPRIO 0 /**< @brief Ready list header priority. */ 00048 #define IDLEPRIO 1 /**< @brief Idle thread priority. */ 00049 #define LOWPRIO 2 /**< @brief Lowest user priority. */ 00050 #define NORMALPRIO 64 /**< @brief Normal user priority. */ 00051 #define HIGHPRIO 127 /**< @brief Highest user priority. */ 00052 #define ABSPRIO 255 /**< @brief Greatest possible priority. */ 00053 /** @} */ 00054 00055 /** 00056 * @name Special time constants 00057 * @{ 00058 */ 00059 /** 00060 * @brief Zero time specification for some functions with a timeout 00061 * specification. 00062 * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter, 00063 * see the specific function documentation. 00064 */ 00065 #define TIME_IMMEDIATE ((systime_t)0) 00066 00067 /** 00068 * @brief Infinite time specification for all functions with a timeout 00069 * specification. 00070 */ 00071 #define TIME_INFINITE ((systime_t)-1) 00072 /** @} */ 00073 00074 /** 00075 * @brief Returns the priority of the first thread on the given ready list. 00076 * 00077 * @notapi 00078 */ 00079 #define firstprio(rlp) ((rlp)->p_next->p_prio) 00080 00081 /** 00082 * @extends ThreadsQueue 00083 * 00084 * @brief Ready list header. 00085 */ 00086 #if !defined(PORT_OPTIMIZED_READYLIST_STRUCT) || defined(__DOXYGEN__) 00087 typedef struct { 00088 ThreadsQueue r_queue; /**< @brief Threads queue. */ 00089 tprio_t r_prio; /**< @brief This field must be 00090 initialized to zero. */ 00091 struct context r_ctx; /**< @brief Not used, present because 00092 offsets. */ 00093 #if CH_USE_REGISTRY || defined(__DOXYGEN__) 00094 Thread *r_newer; /**< @brief Newer registry element. */ 00095 Thread *r_older; /**< @brief Older registry element. */ 00096 #endif 00097 /* End of the fields shared with the Thread structure.*/ 00098 Thread *r_current; /**< @brief The currently running 00099 thread. */ 00100 } ReadyList; 00101 #endif /* !defined(PORT_OPTIMIZED_READYLIST_STRUCT) */ 00102 00103 #if !defined(PORT_OPTIMIZED_RLIST_EXT) && !defined(__DOXYGEN__) 00104 extern ReadyList rlist; 00105 #endif /* !defined(PORT_OPTIMIZED_RLIST_EXT) */ 00106 00107 /** 00108 * @brief Current thread pointer access macro. 00109 * @note This macro is not meant to be used in the application code but 00110 * only from within the kernel, use the @p chThdSelf() API instead. 00111 * @note It is forbidden to use this macro in order to change the pointer 00112 * (currp = something), use @p setcurrp() instead. 00113 */ 00114 #if !defined(PORT_OPTIMIZED_CURRP) || defined(__DOXYGEN__) 00115 #define currp rlist.r_current 00116 #endif /* !defined(PORT_OPTIMIZED_CURRP) */ 00117 00118 /** 00119 * @brief Current thread pointer change macro. 00120 * @note This macro is not meant to be used in the application code but 00121 * only from within the kernel. 00122 * 00123 * @notapi 00124 */ 00125 #if !defined(PORT_OPTIMIZED_SETCURRP) || defined(__DOXYGEN__) 00126 #define setcurrp(tp) (currp = (tp)) 00127 #endif /* !defined(PORT_OPTIMIZED_SETCURRP) */ 00128 00129 /* 00130 * Scheduler APIs. 00131 */ 00132 #ifdef __cplusplus 00133 extern "C" { 00134 #endif 00135 void _scheduler_init(void); 00136 #if !defined(PORT_OPTIMIZED_READYI) 00137 Thread *chSchReadyI(Thread *tp); 00138 #endif 00139 #if !defined(PORT_OPTIMIZED_GOSLEEPS) 00140 void chSchGoSleepS(tstate_t newstate); 00141 #endif 00142 #if !defined(PORT_OPTIMIZED_GOSLEEPTIMEOUTS) 00143 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time); 00144 #endif 00145 #if !defined(PORT_OPTIMIZED_WAKEUPS) 00146 void chSchWakeupS(Thread *tp, msg_t msg); 00147 #endif 00148 #if !defined(PORT_OPTIMIZED_RESCHEDULES) 00149 void chSchRescheduleS(void); 00150 #endif 00151 #if !defined(PORT_OPTIMIZED_ISPREEMPTIONREQUIRED) 00152 bool_t chSchIsPreemptionRequired(void); 00153 #endif 00154 #if !defined(PORT_OPTIMIZED_DORESCHEDULEBEHIND) || defined(__DOXYGEN__) 00155 void chSchDoRescheduleBehind(void); 00156 #endif 00157 #if !defined(PORT_OPTIMIZED_DORESCHEDULEAHEAD) || defined(__DOXYGEN__) 00158 void chSchDoRescheduleAhead(void); 00159 #endif 00160 #if !defined(PORT_OPTIMIZED_DORESCHEDULE) 00161 void chSchDoReschedule(void); 00162 #endif 00163 #ifdef __cplusplus 00164 } 00165 #endif 00166 00167 /** 00168 * @name Macro Functions 00169 * @{ 00170 */ 00171 /** 00172 * @brief Determines if the current thread must reschedule. 00173 * @details This function returns @p TRUE if there is a ready thread with 00174 * higher priority. 00175 * 00176 * @iclass 00177 */ 00178 #if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDI) || defined(__DOXYGEN__) 00179 #define chSchIsRescRequiredI() (firstprio(&rlist.r_queue) > currp->p_prio) 00180 #endif /* !defined(PORT_OPTIMIZED_ISRESCHREQUIREDI) */ 00181 00182 /** 00183 * @brief Determines if yielding is possible. 00184 * @details This function returns @p TRUE if there is a ready thread with 00185 * equal or higher priority. 00186 * 00187 * @sclass 00188 */ 00189 #if !defined(PORT_OPTIMIZED_CANYIELDS) || defined(__DOXYGEN__) 00190 #define chSchCanYieldS() (firstprio(&rlist.r_queue) >= currp->p_prio) 00191 #endif /* !defined(PORT_OPTIMIZED_CANYIELDS) */ 00192 00193 /** 00194 * @brief Yields the time slot. 00195 * @details Yields the CPU control to the next thread in the ready list with 00196 * equal or higher priority, if any. 00197 * 00198 * @sclass 00199 */ 00200 #if !defined(PORT_OPTIMIZED_DOYIELDS) || defined(__DOXYGEN__) 00201 #define chSchDoYieldS() { \ 00202 if (chSchCanYieldS()) \ 00203 chSchDoRescheduleBehind(); \ 00204 } 00205 #endif /* !defined(PORT_OPTIMIZED_DOYIELDS) */ 00206 00207 /** 00208 * @brief Inline-able preemption code. 00209 * @details This is the common preemption code, this function must be invoked 00210 * exclusively from the port layer. 00211 * 00212 * @special 00213 */ 00214 #if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__) 00215 #define chSchPreemption() { \ 00216 tprio_t p1 = firstprio(&rlist.r_queue); \ 00217 tprio_t p2 = currp->p_prio; \ 00218 if (currp->p_preempt) { \ 00219 if (p1 > p2) \ 00220 chSchDoRescheduleAhead(); \ 00221 } \ 00222 else { \ 00223 if (p1 >= p2) \ 00224 chSchDoRescheduleBehind(); \ 00225 } \ 00226 } 00227 #else /* CH_TIME_QUANTUM == 0 */ 00228 #define chSchPreemption() { \ 00229 if (p1 >= p2) \ 00230 chSchDoRescheduleAhead(); \ 00231 } 00232 #endif /* CH_TIME_QUANTUM == 0 */ 00233 /** @} */ 00234 00235 #endif /* _CHSCHD_H_ */ 00236 00237 /** @} */