ChibiOS/RT
2.5.1
chschd.h
Go to the documentation of this file.
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 /** @} */