From 18b8b495244411bb33254ea0d8b868259077be7d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 8 Feb 2012 17:53:52 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3946 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/include/chvt.h | 88 +++++++++++++++++++++++++++++++++++++----------- os/kernel/src/chschd.c | 3 ++ os/kernel/src/chvt.c | 3 +- 3 files changed, 72 insertions(+), 22 deletions(-) (limited to 'os/kernel') diff --git a/os/kernel/include/chvt.h b/os/kernel/include/chvt.h index 95fb16408..355f66064 100644 --- a/os/kernel/include/chvt.h +++ b/os/kernel/include/chvt.h @@ -55,7 +55,8 @@ * * @api */ -#define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / 1000L) + 1L)) +#define MS2ST(msec) ((systime_t)(((((msec) - 1L) * CH_FREQUENCY) / \ + 1000L) + 1L)) /** * @brief Microseconds to system ticks. @@ -67,7 +68,8 @@ * * @api */ -#define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / 1000000L) + 1L)) +#define US2ST(usec) ((systime_t)(((((usec) - 1L) * CH_FREQUENCY) / \ + 1000000L) + 1L)) /** @} */ /** @@ -112,40 +114,84 @@ typedef struct { volatile systime_t vt_systime; /**< @brief System Time counter. */ } VTList; -extern VTList vtlist; - /** * @name Macro Functions * @{ */ /** * @brief Virtual timers ticker. + * @note The system lock is released before entering the callback and + * re-acquired immediately after. It is callback's responsibility + * to acquire the lock if needed. This is done in order to reduce + * interrupts jitter when many timers are in use. * * @iclass */ -#define chVTDoTickI() { \ - vtlist.vt_systime++; \ - if (&vtlist != (VTList *)vtlist.vt_next) { \ - VirtualTimer *vtp; \ - \ - --vtlist.vt_next->vt_time; \ - while (!(vtp = vtlist.vt_next)->vt_time) { \ - vtfunc_t fn = vtp->vt_func; \ - vtp->vt_func = (vtfunc_t)NULL; \ - vtp->vt_next->vt_prev = (void *)&vtlist; \ - (&vtlist)->vt_next = vtp->vt_next; \ - fn(vtp->vt_par); \ - } \ - } \ +#define chVTDoTickI() { \ + vtlist.vt_systime++; \ + if (&vtlist != (VTList *)vtlist.vt_next) { \ + VirtualTimer *vtp; \ + \ + --vtlist.vt_next->vt_time; \ + while (!(vtp = vtlist.vt_next)->vt_time) { \ + vtfunc_t fn = vtp->vt_func; \ + vtp->vt_func = (vtfunc_t)NULL; \ + vtp->vt_next->vt_prev = (void *)&vtlist; \ + (&vtlist)->vt_next = vtp->vt_next; \ + chSysUnlockFromIsr(); \ + fn(vtp->vt_par); \ + chSysLockFromIsr(); \ + } \ + } \ } /** - * @brief Returns TRUE if the speciified timer is armed. + * @brief Returns @p TRUE if the specified timer is armed. * * @iclass */ #define chVTIsArmedI(vtp) ((vtp)->vt_func != NULL) +/** + * @brief Enables a virtual timer. + * @note The associated function is invoked from interrupt context. + * + * @param[out] vtp the @p VirtualTimer structure pointer + * @param[in] time the number of ticks before the operation timeouts, the + * special values are handled as follow: + * - @a TIME_INFINITE is allowed but interpreted as a + * normal time specification. + * - @a TIME_IMMEDIATE this value is not allowed. + * . + * @param[in] vtfunc the timer callback function. After invoking the + * callback the timer is disabled and the structure can + * be disposed or reused. + * @param[in] par a parameter that will be passed to the callback + * function + * + * @api + */ +#define chVTSet(vtp, time, vtfunc, par) { \ + chSysLock(); \ + chVTSetI(vtp, time, vtfunc, par); \ + chSysUnlock(); \ +} + +/** + * @brief Disables a Virtual Timer. + * @note The timer is first checked and disabled only if armed. + * + * @param[in] vtp the @p VirtualTimer structure pointer + * + * @api + */ +#define chVTReset(vtp) { \ + chSysLock(); \ + if (chVTIsArmedI(vtp)) \ + chVTResetI(vtp); \ + chSysUnlock(); \ +} + /** * @brief Current system time. * @details Returns the number of system ticks since the @p chSysInit() @@ -153,13 +199,15 @@ extern VTList vtlist; * @note The counter can reach its maximum and then restart from zero. * @note This function is designed to work with the @p chThdSleepUntil(). * - * @return The system time in ticks.r + * @return The system time in ticks. * * @api */ #define chTimeNow() (vtlist.vt_systime) /** @} */ +extern VTList vtlist; + /* * Virtual Timers APIs. */ diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 808e06300..9739a595b 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -127,10 +127,12 @@ void chSchGoSleepS(tstate_t newstate) { static void wakeup(void *p) { Thread *tp = (Thread *)p; + chSysLockFromIsr(); switch (tp->p_state) { case THD_STATE_READY: /* Handling the special case where the thread has been made ready by another thread with higher priority.*/ + chSysUnlockFromIsr(); return; #if CH_USE_SEMAPHORES || CH_USE_QUEUES || \ (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) @@ -151,6 +153,7 @@ static void wakeup(void *p) { } tp->p_u.rdymsg = RDY_TIMEOUT; chSchReadyI(tp); + chSysUnlockFromIsr(); } /** diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 4869cebef..6389aaf6d 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -49,8 +49,7 @@ void _vt_init(void) { /** * @brief Enables a virtual timer. - * @note The associated function is invoked by an interrupt handler within - * the I-Locked state, see @ref system_states. + * @note The associated function is invoked from interrupt context. * * @param[out] vtp the @p VirtualTimer structure pointer * @param[in] time the number of ticks before the operation timeouts, the -- cgit v1.2.3