ChibiOS/RT
2.5.1
chthreads.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    chthreads.h
00023  * @brief   Threads macros and structures.
00024  *
00025  * @addtogroup threads
00026  * @{
00027  */
00028 
00029 #ifndef _CHTHREADS_H_
00030 #define _CHTHREADS_H_
00031 
00032 /**
00033  * @name    Thread states
00034  * @{
00035  */
00036 #define THD_STATE_READY         0   /**< @brief Waiting on the ready list.  */
00037 #define THD_STATE_CURRENT       1   /**< @brief Currently running.          */
00038 #define THD_STATE_SUSPENDED     2   /**< @brief Created in suspended state. */
00039 #define THD_STATE_WTSEM         3   /**< @brief Waiting on a semaphore.     */
00040 #define THD_STATE_WTMTX         4   /**< @brief Waiting on a mutex.         */
00041 #define THD_STATE_WTCOND        5   /**< @brief Waiting on a condition
00042                                          variable.                          */
00043 #define THD_STATE_SLEEPING      6   /**< @brief Waiting in @p chThdSleep()
00044                                          or @p chThdSleepUntil().           */
00045 #define THD_STATE_WTEXIT        7   /**< @brief Waiting in @p chThdWait().  */
00046 #define THD_STATE_WTOREVT       8   /**< @brief Waiting for an event.       */
00047 #define THD_STATE_WTANDEVT      9   /**< @brief Waiting for several events. */
00048 #define THD_STATE_SNDMSGQ       10  /**< @brief Sending a message, in queue.*/
00049 #define THD_STATE_SNDMSG        11  /**< @brief Sent a message, waiting
00050                                          answer.                            */
00051 #define THD_STATE_WTMSG         12  /**< @brief Waiting for a message.      */
00052 #define THD_STATE_WTQUEUE       13  /**< @brief Waiting on an I/O queue.    */
00053 #define THD_STATE_FINAL         14  /**< @brief Thread terminated.          */
00054 
00055 /**
00056  * @brief   Thread states as array of strings.
00057  * @details Each element in an array initialized with this macro can be
00058  *          indexed using the numeric thread state values.
00059  */
00060 #define THD_STATE_NAMES                                                     \
00061   "READY", "CURRENT", "SUSPENDED", "WTSEM", "WTMTX", "WTCOND", "SLEEPING",  \
00062   "WTEXIT", "WTOREVT", "WTANDEVT", "SNDMSGQ", "SNDMSG", "WTMSG", "WTQUEUE", \
00063   "FINAL"
00064 /** @} */
00065 
00066 /**
00067  * @name    Thread flags and attributes
00068  * @{
00069  */
00070 #define THD_MEM_MODE_MASK       3   /**< @brief Thread memory mode mask.    */
00071 #define THD_MEM_MODE_STATIC     0   /**< @brief Static thread.              */
00072 #define THD_MEM_MODE_HEAP       1   /**< @brief Thread allocated from a
00073                                          Memory Heap.                       */
00074 #define THD_MEM_MODE_MEMPOOL    2   /**< @brief Thread allocated from a
00075                                          Memory Pool.                       */
00076 #define THD_TERMINATE           4   /**< @brief Termination requested flag. */
00077 /** @} */
00078 
00079 /**
00080  * @extends ThreadsQueue
00081  *
00082  * @brief   Structure representing a thread.
00083  * @note    Not all the listed fields are always needed, by switching off some
00084  *          not needed ChibiOS/RT subsystems it is possible to save RAM space
00085  *          by shrinking the @p Thread structure.
00086  */
00087 struct Thread {
00088   Thread                *p_next;    /**< @brief Next in the list/queue.     */
00089   /* End of the fields shared with the ThreadsList structure. */
00090   Thread                *p_prev;    /**< @brief Previous in the queue.      */
00091   /* End of the fields shared with the ThreadsQueue structure. */
00092   tprio_t               p_prio;     /**< @brief Thread priority.            */
00093   struct context        p_ctx;      /**< @brief Processor context.          */
00094 #if CH_USE_REGISTRY || defined(__DOXYGEN__)
00095   Thread                *p_newer;   /**< @brief Newer registry element.     */
00096   Thread                *p_older;   /**< @brief Older registry element.     */
00097 #endif
00098   /* End of the fields shared with the ReadyList structure. */
00099 #if CH_USE_REGISTRY || defined(__DOXYGEN__)
00100   /**
00101    * @brief Thread name or @p NULL.
00102    */
00103   const char            *p_name;
00104 #endif
00105 #if CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
00106   /**
00107    * @brief Thread stack boundary.
00108    */
00109   stkalign_t            *p_stklimit;
00110 #endif
00111   /**
00112    * @brief Current thread state.
00113    */
00114   tstate_t              p_state;
00115   /**
00116    * @brief Various thread flags.
00117    */
00118   tmode_t               p_flags;
00119 #if CH_USE_DYNAMIC || defined(__DOXYGEN__)
00120   /**
00121    * @brief References to this thread.
00122    */
00123   trefs_t               p_refs;
00124 #endif
00125   /**
00126    * @brief Number of ticks remaining to this thread.
00127    */
00128 #if (CH_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
00129   tslices_t             p_preempt;
00130 #endif
00131 #if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__)
00132   /**
00133    * @brief Thread consumed time in ticks.
00134    * @note  This field can overflow.
00135    */
00136   volatile systime_t    p_time;
00137 #endif
00138   /**
00139    * @brief State-specific fields.
00140    * @note  All the fields declared in this union are only valid in the
00141    *        specified state or condition and are thus volatile.
00142    */
00143   union {
00144     /**
00145      * @brief Thread wakeup code.
00146      * @note  This field contains the low level message sent to the thread
00147      *        by the waking thread or interrupt handler. The value is valid
00148      *        after exiting the @p chSchWakeupS() function.
00149      */
00150     msg_t               rdymsg;
00151     /**
00152      * @brief Thread exit code.
00153      * @note  The thread termination code is stored in this field in order
00154      *        to be retrieved by the thread performing a @p chThdWait() on
00155      *        this thread.
00156      */
00157     msg_t               exitcode;
00158     /**
00159      * @brief Pointer to a generic "wait" object.
00160      * @note  This field is used to get a generic pointer to a synchronization
00161      *        object and is valid when the thread is in one of the wait
00162      *        states.
00163      */
00164     void                *wtobjp;
00165 #if CH_USE_EVENTS || defined(__DOXYGEN__)
00166     /**
00167      * @brief Enabled events mask.
00168      * @note  This field is only valid while the thread is in the
00169      *        @p THD_STATE_WTOREVT or @p THD_STATE_WTANDEVT states.
00170      */
00171     eventmask_t         ewmask;
00172 #endif
00173   }                     p_u;
00174 #if CH_USE_WAITEXIT || defined(__DOXYGEN__)
00175   /**
00176    * @brief Termination waiting list.
00177    */
00178   ThreadsList           p_waiting;
00179 #endif
00180 #if CH_USE_MESSAGES || defined(__DOXYGEN__)
00181   /**
00182    * @brief Messages queue.
00183    */
00184   ThreadsQueue          p_msgqueue;
00185   /**
00186    * @brief Thread message.
00187    */
00188   msg_t                 p_msg;
00189 #endif
00190 #if CH_USE_EVENTS || defined(__DOXYGEN__)
00191   /**
00192    * @brief Pending events mask.
00193    */
00194   eventmask_t           p_epending;
00195 #endif
00196 #if CH_USE_MUTEXES || defined(__DOXYGEN__)
00197   /**
00198    * @brief List of the mutexes owned by this thread.
00199    * @note  The list is terminated by a @p NULL in this field.
00200    */
00201   Mutex                 *p_mtxlist;
00202   /**
00203    * @brief Thread's own, non-inherited, priority.
00204    */
00205   tprio_t               p_realprio;
00206 #endif
00207 #if (CH_USE_DYNAMIC && CH_USE_MEMPOOLS) || defined(__DOXYGEN__)
00208   /**
00209    * @brief Memory Pool where the thread workspace is returned.
00210    */
00211   void                  *p_mpool;
00212 #endif
00213 #if defined(THREAD_EXT_FIELDS)
00214   /* Extra fields defined in chconf.h.*/
00215   THREAD_EXT_FIELDS
00216 #endif
00217 };
00218 
00219 /**
00220  * @brief Thread function.
00221  */
00222 typedef msg_t (*tfunc_t)(void *);
00223 
00224 /**
00225  * @name    Macro Functions
00226  * @{
00227  */
00228 /**
00229  * @brief   Returns a pointer to the current @p Thread.
00230  * @note    Can be invoked in any context.
00231  *
00232  * @special
00233  */
00234 #define chThdSelf() currp
00235 
00236 /**
00237  * @brief   Returns the current thread priority.
00238  * @note    Can be invoked in any context.
00239  *
00240  * @special
00241  */
00242 #define chThdGetPriority() (currp->p_prio)
00243 
00244 /**
00245  * @brief   Returns the number of ticks consumed by the specified thread.
00246  * @note    This function is only available when the
00247  *          @p CH_DBG_THREADS_PROFILING configuration option is enabled.
00248  * @note    Can be invoked in any context.
00249  *
00250  * @param[in] tp        pointer to the thread
00251  *
00252  * @special
00253  */
00254 #define chThdGetTicks(tp) ((tp)->p_time)
00255 
00256 /**
00257  * @brief   Returns the pointer to the @p Thread local storage area, if any.
00258  * @note    Can be invoked in any context.
00259  *
00260  * @special
00261  */
00262 #define chThdLS() (void *)(currp + 1)
00263 
00264 /**
00265  * @brief   Verifies if the specified thread is in the @p THD_STATE_FINAL state.
00266  * @note    Can be invoked in any context.
00267  *
00268  * @param[in] tp        pointer to the thread
00269  * @retval TRUE         thread terminated.
00270  * @retval FALSE        thread not terminated.
00271  *
00272  * @special
00273  */
00274 #define chThdTerminated(tp) ((tp)->p_state == THD_STATE_FINAL)
00275 
00276 /**
00277  * @brief   Verifies if the current thread has a termination request pending.
00278  * @note    Can be invoked in any context.
00279  *
00280  * @retval TRUE         termination request pending.
00281  * @retval FALSE        termination request not pending.
00282  *
00283  * @special
00284  */
00285 #define chThdShouldTerminate() (currp->p_flags & THD_TERMINATE)
00286 
00287 /**
00288  * @brief   Resumes a thread created with @p chThdCreateI().
00289  *
00290  * @param[in] tp        pointer to the thread
00291  *
00292  * @iclass
00293  */
00294 #define chThdResumeI(tp) chSchReadyI(tp)
00295 
00296 /**
00297  * @brief   Suspends the invoking thread for the specified time.
00298  *
00299  * @param[in] time      the delay in system ticks, the special values are
00300  *                      handled as follow:
00301  *                      - @a TIME_INFINITE the thread enters an infinite sleep
00302  *                        state.
00303  *                      - @a TIME_IMMEDIATE this value is not allowed.
00304  *                      .
00305  *
00306  * @sclass
00307  */
00308 #define chThdSleepS(time) chSchGoSleepTimeoutS(THD_STATE_SLEEPING, time)
00309 
00310 /**
00311  * @brief   Delays the invoking thread for the specified number of seconds.
00312  * @note    The specified time is rounded up to a value allowed by the real
00313  *          system clock.
00314  * @note    The maximum specified value is implementation dependent.
00315  *
00316  * @param[in] sec       time in seconds, must be different from zero
00317  *
00318  * @api
00319  */
00320 #define chThdSleepSeconds(sec) chThdSleep(S2ST(sec))
00321 
00322 /**
00323  * @brief   Delays the invoking thread for the specified number of
00324  *          milliseconds.
00325  * @note    The specified time is rounded up to a value allowed by the real
00326  *          system clock.
00327  * @note    The maximum specified value is implementation dependent.
00328  *
00329  * @param[in] msec      time in milliseconds, must be different from zero
00330  *
00331  * @api
00332  */
00333 #define chThdSleepMilliseconds(msec) chThdSleep(MS2ST(msec))
00334 
00335 /**
00336  * @brief   Delays the invoking thread for the specified number of
00337  *          microseconds.
00338  * @note    The specified time is rounded up to a value allowed by the real
00339  *          system clock.
00340  * @note    The maximum specified value is implementation dependent.
00341  *
00342  * @param[in] usec      time in microseconds, must be different from zero
00343  *
00344  * @api
00345  */
00346 #define chThdSleepMicroseconds(usec) chThdSleep(US2ST(usec))
00347 /** @} */
00348 
00349 /*
00350  * Threads APIs.
00351  */
00352 #ifdef __cplusplus
00353 extern "C" {
00354 #endif
00355   Thread *_thread_init(Thread *tp, tprio_t prio);
00356 #if CH_DBG_FILL_THREADS
00357   void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v);
00358 #endif
00359   Thread *chThdCreateI(void *wsp, size_t size,
00360                        tprio_t prio, tfunc_t pf, void *arg);
00361   Thread *chThdCreateStatic(void *wsp, size_t size,
00362                             tprio_t prio, tfunc_t pf, void *arg);
00363   tprio_t chThdSetPriority(tprio_t newprio);
00364   Thread *chThdResume(Thread *tp);
00365   void chThdTerminate(Thread *tp);
00366   void chThdSleep(systime_t time);
00367   void chThdSleepUntil(systime_t time);
00368   void chThdYield(void);
00369   void chThdExit(msg_t msg);
00370   void chThdExitS(msg_t msg);
00371 #if CH_USE_WAITEXIT
00372   msg_t chThdWait(Thread *tp);
00373 #endif
00374 #ifdef __cplusplus
00375 }
00376 #endif
00377 
00378 #endif /* _CHTHREADS_H_ */
00379 
00380 /** @} */