From e86fc6ad21d12a2f87239fa953b2bb6ac3da28b5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 14 Nov 2013 10:22:19 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6472 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/rt/include/ch.h | 13 +- os/rt/include/chglobal.h | 321 --------------------------------------- os/rt/include/chlists.h | 217 -------------------------- os/rt/include/chschd.h | 376 ++++++++++++++++++++++++++++++++++++++++++++++ os/rt/include/chthreads.h | 48 +++++- 5 files changed, 420 insertions(+), 555 deletions(-) delete mode 100644 os/rt/include/chglobal.h delete mode 100644 os/rt/include/chlists.h (limited to 'os/rt/include') diff --git a/os/rt/include/ch.h b/os/rt/include/ch.h index e96bc797c..c1360d4c4 100644 --- a/os/rt/include/ch.h +++ b/os/rt/include/ch.h @@ -66,15 +66,6 @@ typedef struct thread thread_t; typedef struct virtual_timer virtual_timer_t; -/* This function is special, it must be accessible from all modules.*/ -#ifdef __cplusplus -extern "C" { -#endif - void chSysHalt(const char *reason); -#ifdef __cplusplus -} -#endif - /* Inclusion of all the kernel sub-headers.*/ #include "chtypes.h" #include "chconf.h" @@ -82,11 +73,9 @@ extern "C" { #include "chdebug.h" #include "chtm.h" #include "chstats.h" -#include "chglobal.h" +#include "chschd.h" #include "chsys.h" #include "chvt.h" -#include "chlists.h" -#include "chschd.h" #include "chthreads.h" #include "chregistry.h" #include "chsem.h" diff --git a/os/rt/include/chglobal.h b/os/rt/include/chglobal.h deleted file mode 100644 index 3d8458f02..000000000 --- a/os/rt/include/chglobal.h +++ /dev/null @@ -1,321 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012,2013 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file chglobal.h - * @brief Data structures with global scope header. - * - * @addtogroup global - */ - -#ifndef _CHGLOBAL_H_ -#define _CHGLOBAL_H_ - -/*===========================================================================*/ -/* Module constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Generic threads single link list, it works like a stack. - */ -typedef struct { - thread_t *p_next; /**< @brief Next in the list/queue. */ -} threads_list_t; - -/** - * @extends threads_list_t - * - * @brief Generic threads bidirectional linked list header and element. - */ -typedef struct { - thread_t *p_next; /**< @brief Next in the list/queue. */ - thread_t *p_prev; /**< @brief Previous in the queue. */ -} threads_queue_t; - -/** - * @extends threads_queue_t - * - * @brief Ready list header. - */ -typedef struct { - threads_queue_t r_queue; /**< @brief Threads queue. */ - tprio_t r_prio; /**< @brief This field must be - initialized to zero. */ - struct context r_ctx; /**< @brief Not used, present because - offsets. */ -#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__) - thread_t *r_newer; /**< @brief Newer registry element. */ - thread_t *r_older; /**< @brief Older registry element. */ -#endif - /* End of the fields shared with the thread_t structure.*/ - thread_t *r_current; /**< @brief The currently running - thread. */ -} ready_list_t; - -/** - * @extends threads_queue_t - * - * @brief Structure representing a thread. - * @note Not all the listed fields are always needed, by switching off some - * not needed ChibiOS/RT subsystems it is possible to save RAM space - * by shrinking the @p thread_t structure. - */ -typedef struct thread { - thread_t *p_next; /**< @brief Next in the list/queue. */ - /* End of the fields shared with the threads_list_t structure.*/ - thread_t *p_prev; /**< @brief Previous in the queue. */ - /* End of the fields shared with the threads_queue_t structure.*/ - tprio_t p_prio; /**< @brief Thread priority. */ - struct context p_ctx; /**< @brief Processor context. */ -#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__) - thread_t *p_newer; /**< @brief Newer registry element. */ - thread_t *p_older; /**< @brief Older registry element. */ -#endif - /* End of the fields shared with the ReadyList structure. */ -#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__) - /** - * @brief Thread name or @p NULL. - */ - const char *p_name; -#endif -#if CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) - /** - * @brief Thread stack boundary. - */ - stkalign_t *p_stklimit; -#endif - /** - * @brief Current thread state. - */ - tstate_t p_state; - /** - * @brief Various thread flags. - */ - tmode_t p_flags; -#if CH_CFG_USE_DYNAMIC || defined(__DOXYGEN__) - /** - * @brief References to this thread. - */ - trefs_t p_refs; -#endif - /** - * @brief Number of ticks remaining to this thread. - */ -#if (CH_CFG_TIME_QUANTUM > 0) || defined(__DOXYGEN__) - tslices_t p_preempt; -#endif -#if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__) - /** - * @brief Thread consumed time in ticks. - * @note This field can overflow. - */ - volatile systime_t p_time; -#endif - /** - * @brief State-specific fields. - * @note All the fields declared in this union are only valid in the - * specified state or condition and are thus volatile. - */ - union { - /** - * @brief Thread wakeup code. - * @note This field contains the low level message sent to the thread - * by the waking thread or interrupt handler. The value is valid - * after exiting the @p chSchWakeupS() function. - */ - msg_t rdymsg; - /** - * @brief Thread exit code. - * @note The thread termination code is stored in this field in order - * to be retrieved by the thread performing a @p chThdWait() on - * this thread. - */ - msg_t exitcode; - /** - * @brief Pointer to a generic "wait" object. - * @note This field is used to get a generic pointer to a synchronization - * object and is valid when the thread is in one of the wait - * states. - */ - void *wtobjp; -#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__) - /** - * @brief Enabled events mask. - * @note This field is only valid while the thread is in the - * @p CH_STATE_WTOREVT or @p CH_STATE_WTANDEVT states. - */ - eventmask_t ewmask; -#endif - } p_u; -#if CH_CFG_USE_WAITEXIT || defined(__DOXYGEN__) - /** - * @brief Termination waiting list. - */ - threads_list_t p_waiting; -#endif -#if CH_CFG_USE_MESSAGES || defined(__DOXYGEN__) - /** - * @brief Messages queue. - */ - threads_queue_t p_msgqueue; - /** - * @brief Thread message. - */ - msg_t p_msg; -#endif -#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__) - /** - * @brief Pending events mask. - */ - eventmask_t p_epending; -#endif -#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__) - /** - * @brief List of the mutexes owned by this thread. - * @note The list is terminated by a @p NULL in this field. - */ - struct mutex *p_mtxlist; - /** - * @brief Thread's own, non-inherited, priority. - */ - tprio_t p_realprio; -#endif -#if (CH_CFG_USE_DYNAMIC && CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__) - /** - * @brief Memory Pool where the thread workspace is returned. - */ - void *p_mpool; -#endif -#if CH_DBG_STATISTICS || defined(__DOXYGEN__) - time_measurement_t p_stats; -#endif -#if defined(CH_CFG_THREAD_EXTRA_FIELDS) - /* Extra fields defined in chconf.h.*/ - CH_CFG_THREAD_EXTRA_FIELDS -#endif -} thread_t; - -/** - * @brief Virtual timers list header. - * @note The timers list is implemented as a double link bidirectional list - * in order to make the unlink time constant, the reset of a virtual - * timer is often used in the code. - */ -typedef struct { - virtual_timer_t *vt_next; /**< @brief Next timer in the delta - list. */ - virtual_timer_t *vt_prev; /**< @brief Last timer in the delta - list. */ - systime_t vt_delta; /**< @brief Must be initialized to -1. */ -#if CH_CFG_ST_TIMEDELTA == 0 || defined(__DOXYGEN__) - volatile systime_t vt_systime; /**< @brief System Time counter. */ -#endif -#if CH_CFG_ST_TIMEDELTA > 0 || defined(__DOXYGEN__) - /** - * @brief System time of the last tick event. - */ - systime_t vt_lasttime;/**< @brief System time of the last - tick event. */ -#endif -} virtual_timers_list_t; - -/** - * @brief System data structure. - * @note This structure contain all the data areas used by the OS except - * stacks. - */ -typedef struct ch_system { - /** - * @brief Ready list header. - */ - ready_list_t rlist; - /** - * @brief Virtual timers delta list header. - */ - virtual_timers_list_t vtlist; -#if CH_CFG_USE_TM || defined(__DOXYGEN__) - /** - * @brief Measurement calibration value. - */ - rtcnt_t measurement_offset; -#endif -#if CH_DBG_STATISTICS || defined(__DOXYGEN__) - /** - * @brief Global kernel statistics. - */ - kernel_stats_t kernel_stats; -#endif -#if CH_DBG_ENABLED || defined(__DOXYGEN__) - /** - * @brief Pointer to the panic message. - * @details This pointer is meant to be accessed through the debugger, it is - * written once and then the system is halted. - */ - const char *dbg_panic_msg; -#endif -#if CH_DBG_SYSTEM_STATE_CHECK || defined(__DOXYGEN__) - /** - * @brief ISR nesting level. - */ - cnt_t dbg_isr_cnt; - /** - * @brief Lock nesting level. - */ - cnt_t dbg_lock_cnt; -#endif -#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__) - /** - * @brief Public trace buffer. - */ - ch_trace_buffer_t dbg_trace_buffer; -#endif -} ch_system_t; - -/*===========================================================================*/ -/* Module macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern ch_system_t ch; -#endif - -/*===========================================================================*/ -/* Module inline functions. */ -/*===========================================================================*/ - -#endif /* _CHGLOBAL_H_ */ - -/** @} */ diff --git a/os/rt/include/chlists.h b/os/rt/include/chlists.h deleted file mode 100644 index f49ce679f..000000000 --- a/os/rt/include/chlists.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012,2013 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file chlists.h - * @brief Thread queues and lists header. - * - * @addtogroup queues_list - * @{ - */ - -#ifndef _CHLISTS_H_ -#define _CHLISTS_H_ - -/*===========================================================================*/ -/* Module constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Module macros. */ -/*===========================================================================*/ - -/** - * @brief Data part of a static threads queue initializer. - * @details This macro should be used when statically initializing a threads - * queue that is part of a bigger structure. - * - * @param[in] name the name of the threads queue variable - */ -#define _threads_queue_t_DATA(name) {(thread_t *)&name, (thread_t *)&name} - -/** - * @brief Static threads queue initializer. - * @details Statically initialized threads queues require no explicit - * initialization using @p queue_init(). - * - * @param[in] name the name of the threads queue variable - */ -#define threads_queue_t_DECL(name) \ - threads_queue_t name = _threads_queue_t_DATA(name) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - msg_t chQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t timeout); - void chQueueWakeupOneI(threads_queue_t *tqp, msg_t msg); - void chQueueWakeupAllI(threads_queue_t *tqp, msg_t msg); -#ifdef __cplusplus -} -#endif - -/*===========================================================================*/ -/* Module inline functions. */ -/*===========================================================================*/ - -/** - * @brief Threads list initialization. - * - * @notapi - */ -static inline void list_init(threads_list_t *tlp) { - - tlp->p_next = (thread_t *)tlp; -} - -/** - * @brief Evaluates to @p true if the specified threads list is empty. - * - * @notapi - */ -static inline bool list_isempty(threads_list_t *tlp) { - - return (bool)(tlp->p_next == (thread_t *)tlp); -} - -/** - * @brief Evaluates to @p true if the specified threads list is not empty. - * - * @notapi - */ -static inline bool list_notempty(threads_list_t *tlp) { - - return (bool)(tlp->p_next != (thread_t *)tlp); -} - -/** - * @brief Threads queue initialization. - * - * @notapi - */ -static inline void queue_init(threads_queue_t *tqp) { - - tqp->p_next = tqp->p_prev = (thread_t *)tqp; -} - -/** - * @brief Evaluates to @p true if the specified threads queue is empty. - * - * @notapi - */ -static inline bool queue_isempty(threads_queue_t *tqp) { - - return (bool)(tqp->p_next == (thread_t *)tqp); -} - -/** - * @brief Evaluates to @p true if the specified threads queue is not empty. - * - * @notapi - */ -static inline bool queue_notempty(threads_queue_t *tqp) { - - return (bool)(tqp->p_next != (thread_t *)tqp); -} - -/* If the performance code path has been chosen then all the following - functions are inlined into the various kernel modules.*/ -#if CH_CFG_OPTIMIZE_SPEED -static inline void list_insert(thread_t *tp, threads_list_t *tlp) { - - tp->p_next = tlp->p_next; - tlp->p_next = tp; -} - -static inline thread_t *list_remove(threads_list_t *tlp) { - - thread_t *tp = tlp->p_next; - tlp->p_next = tp->p_next; - return tp; -} - -static inline void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) { - - thread_t *cp = (thread_t *)tqp; - do { - cp = cp->p_next; - } while ((cp != (thread_t *)tqp) && (cp->p_prio >= tp->p_prio)); - tp->p_next = cp; - tp->p_prev = cp->p_prev; - tp->p_prev->p_next = cp->p_prev = tp; -} - -static inline void queue_insert(thread_t *tp, threads_queue_t *tqp) { - - tp->p_next = (thread_t *)tqp; - tp->p_prev = tqp->p_prev; - tp->p_prev->p_next = tqp->p_prev = tp; -} - -static inline thread_t *queue_fifo_remove(threads_queue_t *tqp) { - thread_t *tp = tqp->p_next; - - (tqp->p_next = tp->p_next)->p_prev = (thread_t *)tqp; - return tp; -} - -static inline thread_t *queue_lifo_remove(threads_queue_t *tqp) { - thread_t *tp = tqp->p_prev; - - (tqp->p_prev = tp->p_prev)->p_next = (thread_t *)tqp; - return tp; -} - -static inline thread_t *queue_dequeue(thread_t *tp) { - - tp->p_prev->p_next = tp->p_next; - tp->p_next->p_prev = tp->p_prev; - return tp; -} -#endif /* CH_CFG_OPTIMIZE_SPEED */ - -/** - * @brief Initializes a threads queue object. - * - * @param[out] tqp pointer to the threads queue object - * - * @init - */ -static inline void chQueueObjectInit(threads_queue_t *tqp) { - - queue_init(tqp); -} - -#endif /* _CHLISTS_H_ */ diff --git a/os/rt/include/chschd.h b/os/rt/include/chschd.h index b4160acc6..718cedd58 100644 --- a/os/rt/include/chschd.h +++ b/os/rt/include/chschd.h @@ -87,6 +87,262 @@ /* Module data structures and types. */ /*===========================================================================*/ +/** + * @brief Generic threads single link list, it works like a stack. + */ +typedef struct { + thread_t *p_next; /**< @brief Next in the list/queue. */ +} threads_list_t; + +/** + * @extends threads_list_t + * + * @brief Generic threads bidirectional linked list header and element. + */ +typedef struct { + thread_t *p_next; /**< @brief Next in the list/queue. */ + thread_t *p_prev; /**< @brief Previous in the queue. */ +} threads_queue_t; + +/** + * @extends threads_queue_t + * + * @brief Ready list header. + */ +typedef struct { + threads_queue_t r_queue; /**< @brief Threads queue. */ + tprio_t r_prio; /**< @brief This field must be + initialized to zero. */ + struct context r_ctx; /**< @brief Not used, present because + offsets. */ +#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__) + thread_t *r_newer; /**< @brief Newer registry element. */ + thread_t *r_older; /**< @brief Older registry element. */ +#endif + /* End of the fields shared with the thread_t structure.*/ + thread_t *r_current; /**< @brief The currently running + thread. */ +} ready_list_t; + +/** + * @extends threads_queue_t + * + * @brief Structure representing a thread. + * @note Not all the listed fields are always needed, by switching off some + * not needed ChibiOS/RT subsystems it is possible to save RAM space + * by shrinking the @p thread_t structure. + */ +typedef struct thread { + thread_t *p_next; /**< @brief Next in the list/queue. */ + /* End of the fields shared with the threads_list_t structure.*/ + thread_t *p_prev; /**< @brief Previous in the queue. */ + /* End of the fields shared with the threads_queue_t structure.*/ + tprio_t p_prio; /**< @brief Thread priority. */ + struct context p_ctx; /**< @brief Processor context. */ +#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__) + thread_t *p_newer; /**< @brief Newer registry element. */ + thread_t *p_older; /**< @brief Older registry element. */ +#endif + /* End of the fields shared with the ReadyList structure. */ +#if CH_CFG_USE_REGISTRY || defined(__DOXYGEN__) + /** + * @brief Thread name or @p NULL. + */ + const char *p_name; +#endif +#if CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) + /** + * @brief Thread stack boundary. + */ + stkalign_t *p_stklimit; +#endif + /** + * @brief Current thread state. + */ + tstate_t p_state; + /** + * @brief Various thread flags. + */ + tmode_t p_flags; +#if CH_CFG_USE_DYNAMIC || defined(__DOXYGEN__) + /** + * @brief References to this thread. + */ + trefs_t p_refs; +#endif + /** + * @brief Number of ticks remaining to this thread. + */ +#if (CH_CFG_TIME_QUANTUM > 0) || defined(__DOXYGEN__) + tslices_t p_preempt; +#endif +#if CH_DBG_THREADS_PROFILING || defined(__DOXYGEN__) + /** + * @brief Thread consumed time in ticks. + * @note This field can overflow. + */ + volatile systime_t p_time; +#endif + /** + * @brief State-specific fields. + * @note All the fields declared in this union are only valid in the + * specified state or condition and are thus volatile. + */ + union { + /** + * @brief Thread wakeup code. + * @note This field contains the low level message sent to the thread + * by the waking thread or interrupt handler. The value is valid + * after exiting the @p chSchWakeupS() function. + */ + msg_t rdymsg; + /** + * @brief Thread exit code. + * @note The thread termination code is stored in this field in order + * to be retrieved by the thread performing a @p chThdWait() on + * this thread. + */ + msg_t exitcode; + /** + * @brief Pointer to a generic "wait" object. + * @note This field is used to get a generic pointer to a synchronization + * object and is valid when the thread is in one of the wait + * states. + */ + void *wtobjp; +#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__) + /** + * @brief Enabled events mask. + * @note This field is only valid while the thread is in the + * @p CH_STATE_WTOREVT or @p CH_STATE_WTANDEVT states. + */ + eventmask_t ewmask; +#endif + } p_u; +#if CH_CFG_USE_WAITEXIT || defined(__DOXYGEN__) + /** + * @brief Termination waiting list. + */ + threads_list_t p_waiting; +#endif +#if CH_CFG_USE_MESSAGES || defined(__DOXYGEN__) + /** + * @brief Messages queue. + */ + threads_queue_t p_msgqueue; + /** + * @brief Thread message. + */ + msg_t p_msg; +#endif +#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__) + /** + * @brief Pending events mask. + */ + eventmask_t p_epending; +#endif +#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__) + /** + * @brief List of the mutexes owned by this thread. + * @note The list is terminated by a @p NULL in this field. + */ + struct mutex *p_mtxlist; + /** + * @brief Thread's own, non-inherited, priority. + */ + tprio_t p_realprio; +#endif +#if (CH_CFG_USE_DYNAMIC && CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__) + /** + * @brief Memory Pool where the thread workspace is returned. + */ + void *p_mpool; +#endif +#if CH_DBG_STATISTICS || defined(__DOXYGEN__) + time_measurement_t p_stats; +#endif +#if defined(CH_CFG_THREAD_EXTRA_FIELDS) + /* Extra fields defined in chconf.h.*/ + CH_CFG_THREAD_EXTRA_FIELDS +#endif +} thread_t; + +/** + * @brief Virtual timers list header. + * @note The timers list is implemented as a double link bidirectional list + * in order to make the unlink time constant, the reset of a virtual + * timer is often used in the code. + */ +typedef struct { + virtual_timer_t *vt_next; /**< @brief Next timer in the delta + list. */ + virtual_timer_t *vt_prev; /**< @brief Last timer in the delta + list. */ + systime_t vt_delta; /**< @brief Must be initialized to -1. */ +#if CH_CFG_ST_TIMEDELTA == 0 || defined(__DOXYGEN__) + volatile systime_t vt_systime; /**< @brief System Time counter. */ +#endif +#if CH_CFG_ST_TIMEDELTA > 0 || defined(__DOXYGEN__) + /** + * @brief System time of the last tick event. + */ + systime_t vt_lasttime;/**< @brief System time of the last + tick event. */ +#endif +} virtual_timers_list_t; + +/** + * @brief System data structure. + * @note This structure contain all the data areas used by the OS except + * stacks. + */ +typedef struct ch_system { + /** + * @brief Ready list header. + */ + ready_list_t rlist; + /** + * @brief Virtual timers delta list header. + */ + virtual_timers_list_t vtlist; +#if CH_CFG_USE_TM || defined(__DOXYGEN__) + /** + * @brief Measurement calibration value. + */ + rtcnt_t measurement_offset; +#endif +#if CH_DBG_STATISTICS || defined(__DOXYGEN__) + /** + * @brief Global kernel statistics. + */ + kernel_stats_t kernel_stats; +#endif +#if CH_DBG_ENABLED || defined(__DOXYGEN__) + /** + * @brief Pointer to the panic message. + * @details This pointer is meant to be accessed through the debugger, it is + * written once and then the system is halted. + */ + const char *dbg_panic_msg; +#endif +#if CH_DBG_SYSTEM_STATE_CHECK || defined(__DOXYGEN__) + /** + * @brief ISR nesting level. + */ + cnt_t dbg_isr_cnt; + /** + * @brief Lock nesting level. + */ + cnt_t dbg_lock_cnt; +#endif +#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__) + /** + * @brief Public trace buffer. + */ + ch_trace_buffer_t dbg_trace_buffer; +#endif +} ch_system_t; + /*===========================================================================*/ /* Module macros. */ /*===========================================================================*/ @@ -120,6 +376,10 @@ /* External declarations. */ /*===========================================================================*/ +#if !defined(__DOXYGEN__) +extern ch_system_t ch; +#endif + /* * Scheduler APIs. */ @@ -144,6 +404,122 @@ extern "C" { /* Module inline functions. */ /*===========================================================================*/ + /** + * @brief Threads list initialization. + * + * @notapi + */ + static inline void list_init(threads_list_t *tlp) { + + tlp->p_next = (thread_t *)tlp; + } + + /** + * @brief Evaluates to @p true if the specified threads list is empty. + * + * @notapi + */ + static inline bool list_isempty(threads_list_t *tlp) { + + return (bool)(tlp->p_next == (thread_t *)tlp); + } + + /** + * @brief Evaluates to @p true if the specified threads list is not empty. + * + * @notapi + */ + static inline bool list_notempty(threads_list_t *tlp) { + + return (bool)(tlp->p_next != (thread_t *)tlp); + } + + /** + * @brief Threads queue initialization. + * + * @notapi + */ + static inline void queue_init(threads_queue_t *tqp) { + + tqp->p_next = tqp->p_prev = (thread_t *)tqp; + } + + /** + * @brief Evaluates to @p true if the specified threads queue is empty. + * + * @notapi + */ + static inline bool queue_isempty(threads_queue_t *tqp) { + + return (bool)(tqp->p_next == (thread_t *)tqp); + } + + /** + * @brief Evaluates to @p true if the specified threads queue is not empty. + * + * @notapi + */ + static inline bool queue_notempty(threads_queue_t *tqp) { + + return (bool)(tqp->p_next != (thread_t *)tqp); + } + + /* If the performance code path has been chosen then all the following + functions are inlined into the various kernel modules.*/ + #if CH_CFG_OPTIMIZE_SPEED + static inline void list_insert(thread_t *tp, threads_list_t *tlp) { + + tp->p_next = tlp->p_next; + tlp->p_next = tp; + } + + static inline thread_t *list_remove(threads_list_t *tlp) { + + thread_t *tp = tlp->p_next; + tlp->p_next = tp->p_next; + return tp; + } + + static inline void queue_prio_insert(thread_t *tp, threads_queue_t *tqp) { + + thread_t *cp = (thread_t *)tqp; + do { + cp = cp->p_next; + } while ((cp != (thread_t *)tqp) && (cp->p_prio >= tp->p_prio)); + tp->p_next = cp; + tp->p_prev = cp->p_prev; + tp->p_prev->p_next = cp->p_prev = tp; + } + + static inline void queue_insert(thread_t *tp, threads_queue_t *tqp) { + + tp->p_next = (thread_t *)tqp; + tp->p_prev = tqp->p_prev; + tp->p_prev->p_next = tqp->p_prev = tp; + } + + static inline thread_t *queue_fifo_remove(threads_queue_t *tqp) { + thread_t *tp = tqp->p_next; + + (tqp->p_next = tp->p_next)->p_prev = (thread_t *)tqp; + return tp; + } + + static inline thread_t *queue_lifo_remove(threads_queue_t *tqp) { + thread_t *tp = tqp->p_prev; + + (tqp->p_prev = tp->p_prev)->p_next = (thread_t *)tqp; + return tp; + } + + static inline thread_t *queue_dequeue(thread_t *tp) { + + tp->p_prev->p_next = tp->p_next; + tp->p_next->p_prev = tp->p_prev; + return tp; + } +#endif /* CH_CFG_OPTIMIZE_SPEED */ + /** * @brief Determines if the current thread must reschedule. * @details This function returns @p true if there is a ready thread with diff --git a/os/rt/include/chthreads.h b/os/rt/include/chthreads.h index 1dcad9b48..e1a8b496d 100644 --- a/os/rt/include/chthreads.h +++ b/os/rt/include/chthreads.h @@ -158,6 +158,29 @@ typedef msg_t (*tfunc_t)(void *); #define THD_FUNCTION(tname, arg) PORT_THD_FUNCTION(tname, arg) /** @} */ +/** + * @name Threads queues + */ +/** + * @brief Data part of a static threads queue object initializer. + * @details This macro should be used when statically initializing a threads + * queue that is part of a bigger structure. + * + * @param[in] name the name of the threads queue variable + */ +#define _threads_queue_t_DATA(name) {(thread_t *)&name, (thread_t *)&name} + +/** + * @brief Static threads queue object initializer. + * @details Statically initialized threads queues require no explicit + * initialization using @p queue_init(). + * + * @param[in] name the name of the threads queue variable + */ +#define threads_queue_t_DECL(name) \ + threads_queue_t name = _threads_queue_t_DATA(name) +/** @} */ + /** * @name Macro Functions * @{ @@ -218,11 +241,14 @@ extern "C" { tprio_t prio, tfunc_t pf, void *arg); thread_t *chThdStart(thread_t *tp); tprio_t chThdSetPriority(tprio_t newprio); - msg_t chThreadSuspendS(thread_reference_t *trp); - msg_t chThreadSuspendTimeoutS(thread_reference_t *trp, systime_t timeout); - void chThreadResumeI(thread_reference_t *trp, msg_t msg); - void chThreadResumeS(thread_reference_t *trp, msg_t msg); - void chThreadResume(thread_reference_t *trp, msg_t msg); + msg_t chThdSuspendS(thread_reference_t *trp); + msg_t chThdSuspendTimeoutS(thread_reference_t *trp, systime_t timeout); + void chThdResumeI(thread_reference_t *trp, msg_t msg); + void chThdResumeS(thread_reference_t *trp, msg_t msg); + void chThdResume(thread_reference_t *trp, msg_t msg); + msg_t chThdEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout); + void chThdDequeueNextI(threads_queue_t *tqp, msg_t msg); + void chThdDequeueAllI(threads_queue_t *tqp, msg_t msg); void chThdTerminate(thread_t *tp); void chThdSleep(systime_t time); void chThdSleepUntil(systime_t time); @@ -337,6 +363,18 @@ static inline void chThdSleepS(systime_t time) { chSchGoSleepTimeoutS(CH_STATE_SLEEPING, time); } +/** + * @brief Initializes a threads queue object. + * + * @param[out] tqp pointer to the threads queue object + * + * @init + */ +static inline void chThdQueueObjectInit(threads_queue_t *tqp) { + + queue_init(tqp); +} + #endif /* _CHTHREADS_H_ */ /** @} */ -- cgit v1.2.3