ChibiOS/RT Architecture - Reference Manual - Guides |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. 00003 00004 This file is part of ChibiOS/RT. 00005 00006 ChibiOS/RT is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 ChibiOS/RT is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 00019 --- 00020 00021 A special exception to the GPL can be applied should you wish to distribute 00022 a combined work that includes ChibiOS/RT, without being obliged to provide 00023 the source code for any proprietary components. See the file exception.txt 00024 for full details of how and when the exception can be applied. 00025 */ 00026 00027 /** 00028 * @file chschd.h 00029 * @brief Scheduler macros and structures. 00030 * 00031 * @addtogroup scheduler 00032 * @{ 00033 */ 00034 00035 #ifndef _CHSCHD_H_ 00036 #define _CHSCHD_H_ 00037 00038 /** @brief Default thread wakeup low level message.*/ 00039 #define RDY_OK 0 00040 /** @brief Low level message sent to a thread awakened by a timeout.*/ 00041 #define RDY_TIMEOUT -1 00042 /** @brief Low level message sent to a thread awakened by a reset operation.*/ 00043 #define RDY_RESET -2 00044 00045 #define NOPRIO 0 /**< @brief Ready list header priority. */ 00046 #define IDLEPRIO 1 /**< @brief Idle thread priority. */ 00047 #define LOWPRIO 2 /**< @brief Lowest user priority. */ 00048 #define NORMALPRIO 64 /**< @brief Normal user priority. */ 00049 #define HIGHPRIO 127 /**< @brief Highest user priority. */ 00050 #define ABSPRIO 255 /**< @brief Greatest possible priority. */ 00051 00052 /** 00053 * @brief Zero time specification for some syscalls with a timeout 00054 * specification. 00055 * @note Not all functions accept @p TIME_IMMEDIATE as timeout parameter, 00056 * see the specific function documentation. 00057 */ 00058 #define TIME_IMMEDIATE ((systime_t)-1) 00059 00060 /** 00061 * @brief Infinite time specification for all the syscalls with a timeout 00062 * specification. 00063 */ 00064 #define TIME_INFINITE ((systime_t)0) 00065 00066 /** 00067 * @brief Returns the priority of the first thread on the given ready list. 00068 */ 00069 #define firstprio(rlp) ((rlp)->p_next->p_prio) 00070 00071 /** 00072 * @extends ThreadsQueue 00073 * 00074 * @brief Ready list header. 00075 */ 00076 #if !defined(PORT_OPTIMIZED_READYLIST_STRUCT) || defined(__DOXYGEN__) 00077 typedef struct { 00078 ThreadsQueue r_queue; /**< @brief Threads queue. */ 00079 tprio_t r_prio; /**< @brief This field must be 00080 initialized to zero. */ 00081 struct context r_ctx; /**< @brief Not used, present because 00082 offsets. */ 00083 #if CH_USE_REGISTRY 00084 Thread *r_newer; /**< @brief Newer registry element. */ 00085 Thread *r_older; /**< @brief Older registry element. */ 00086 #endif 00087 /* End of the fields shared with the Thread structure.*/ 00088 #if CH_TIME_QUANTUM > 0 00089 cnt_t r_preempt; /**< @brief Round robin counter. */ 00090 #endif 00091 #ifndef CH_CURRP_REGISTER_CACHE 00092 Thread *r_current; /**< @brief The currently running 00093 thread. */ 00094 #endif 00095 } ReadyList; 00096 #endif /* !defined(PORT_OPTIMIZED_READYLIST_STRUCT) */ 00097 00098 #if !defined(PORT_OPTIMIZED_RLIST_EXT) && !defined(__DOXYGEN__) 00099 extern ReadyList rlist; 00100 #endif /* !defined(PORT_OPTIMIZED_RLIST_EXT) */ 00101 00102 /** 00103 * @brief Current thread pointer access macro. 00104 * @note This macro is not meant to be used in the application code but 00105 * only from within the kernel, use the @p chThdSelf() API instead. 00106 * @note It is forbidden to use this macro in order to change the pointer 00107 * (currp = something), use @p setcurrp() instead. 00108 */ 00109 #if !defined(PORT_OPTIMIZED_CURRP) || defined(__DOXYGEN__) 00110 #if !defined(CH_CURRP_REGISTER_CACHE) || defined(__DOXYGEN__) 00111 #define currp rlist.r_current 00112 #else /* defined(CH_CURRP_REGISTER_CACHE) */ 00113 register Thread *currp asm(CH_CURRP_REGISTER_CACHE); 00114 #endif /* defined(CH_CURRP_REGISTER_CACHE) */ 00115 #endif /* !defined(PORT_OPTIMIZED_CURRP) */ 00116 00117 /** 00118 * @brief Current thread pointer change macro. 00119 * @note This macro is not meant to be used in the application code but 00120 * only from within the kernel. 00121 */ 00122 #if !defined(PORT_OPTIMIZED_SETCURRP) || defined(__DOXYGEN__) 00123 #define setcurrp(tp) (currp = (tp)) 00124 #endif /* !defined(PORT_OPTIMIZED_SETCURRP) */ 00125 00126 /* 00127 * Scheduler APIs. 00128 */ 00129 #ifdef __cplusplus 00130 extern "C" { 00131 #endif 00132 void scheduler_init(void); 00133 #if !defined(PORT_OPTIMIZED_READYI) 00134 Thread *chSchReadyI(Thread *tp); 00135 #endif 00136 #if !defined(PORT_OPTIMIZED_GOSLEEPS) 00137 void chSchGoSleepS(tstate_t newstate); 00138 #endif 00139 #if !defined(PORT_OPTIMIZED_GOSLEEPTIMEOUTS) 00140 msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time); 00141 #endif 00142 #if !defined(PORT_OPTIMIZED_WAKEUPS) 00143 void chSchWakeupS(Thread *tp, msg_t msg); 00144 #endif 00145 #if !defined(PORT_OPTIMIZED_DORESCHEDULEI) 00146 void chSchDoRescheduleI(void); 00147 #endif 00148 #if !defined(PORT_OPTIMIZED_RESCHEDULES) 00149 void chSchRescheduleS(void); 00150 #endif 00151 #if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI) 00152 bool_t chSchIsRescRequiredExI(void); 00153 #endif 00154 #ifdef __cplusplus 00155 } 00156 #endif 00157 00158 /** 00159 * @brief Determines if the current thread must reschedule. 00160 * @details This function returns @p TRUE if there is a ready thread with 00161 * higher priority. 00162 */ 00163 #if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDI) || defined(__DOXYGEN__) 00164 #define chSchIsRescRequiredI() (firstprio(&rlist.r_queue) > currp->p_prio) 00165 #endif /* !defined(PORT_OPTIMIZED_ISRESCHREQUIREDI) */ 00166 00167 /** 00168 * @brief Determines if yielding is possible. 00169 * @details This function returns @p TRUE if there is a ready thread with 00170 * equal or higher priority. 00171 */ 00172 #if !defined(PORT_OPTIMIZED_CANYIELDS) || defined(__DOXYGEN__) 00173 #define chSchCanYieldS() (firstprio(&rlist.r_queue) >= currp->p_prio) 00174 #endif /* !defined(PORT_OPTIMIZED_CANYIELDS) */ 00175 00176 /** 00177 * @brief Yields the time slot. 00178 * @details Yields the CPU control to the next thread in the ready list with 00179 * equal or higher priority, if any. 00180 */ 00181 #if !defined(PORT_OPTIMIZED_DOYIELDS) || defined(__DOXYGEN__) 00182 #define chSchDoYieldS() { \ 00183 if (chSchCanYieldS()) \ 00184 chSchDoRescheduleI(); \ 00185 } 00186 #endif /* !defined(PORT_OPTIMIZED_DOYIELDS) */ 00187 00188 #endif /* _CHSCHD_H_ */ 00189 00190 /** @} */