diff --git a/os/kernel/include/chcond.h b/os/kernel/include/chcond.h index 7557243cd..202f4125c 100644 --- a/os/kernel/include/chcond.h +++ b/os/kernel/include/chcond.h @@ -45,7 +45,7 @@ * @brief CondVar structure. */ typedef struct CondVar { - ThreadsQueue c_queue; /**< @brief CondVar threads queue.*/ + threads_queue_t c_queue; /**< @brief CondVar threads queue.*/ } CondVar; #ifdef __cplusplus @@ -73,7 +73,7 @@ extern "C" { * * @param[in] name the name of the condition variable */ -#define _CONDVAR_DATA(name) {_THREADSQUEUE_DATA(name.c_queue)} +#define _CONDVAR_DATA(name) {_threads_queue_t_DATA(name.c_queue)} /** * @brief Static condition variable initializer. diff --git a/os/kernel/include/chlists.h b/os/kernel/include/chlists.h index e47f0b704..2698b2129 100644 --- a/os/kernel/include/chlists.h +++ b/os/kernel/include/chlists.h @@ -56,7 +56,7 @@ * * @param[in] name the name of the threads queue variable */ -#define _THREADSQUEUE_DATA(name) {(Thread *)&name, (Thread *)&name} +#define _threads_queue_t_DATA(name) {(Thread *)&name, (Thread *)&name} /** * @brief Static threads queue initializer. @@ -65,7 +65,7 @@ * * @param[in] name the name of the threads queue variable */ -#define THREADSQUEUE_DECL(name) ThreadsQueue name = _THREADSQUEUE_DATA(name) +#define threads_queue_t_DECL(name) threads_queue_t name = _threads_queue_t_DATA(name) /*===========================================================================*/ /* External declarations. */ @@ -80,7 +80,7 @@ * * @notapi */ -static inline void list_init(ThreadsList *tlp) { +static inline void list_init(threads_list_t *tlp) { tlp->p_next = (Thread *)tlp; } @@ -90,7 +90,7 @@ static inline void list_init(ThreadsList *tlp) { * * @notapi */ -static inline bool_t list_isempty(ThreadsList *tlp) { +static inline bool_t list_isempty(threads_list_t *tlp) { return (bool_t)(tlp->p_next == (Thread *)tlp); } @@ -100,7 +100,7 @@ static inline bool_t list_isempty(ThreadsList *tlp) { * * @notapi */ -static inline bool_t list_notempty(ThreadsList *tlp) { +static inline bool_t list_notempty(threads_list_t *tlp) { return (bool_t)(tlp->p_next != (Thread *)tlp); } @@ -110,7 +110,7 @@ static inline bool_t list_notempty(ThreadsList *tlp) { * * @notapi */ -static inline void queue_init(ThreadsQueue *tqp) { +static inline void queue_init(threads_queue_t *tqp) { tqp->p_next = tqp->p_prev = (Thread *)tqp; } @@ -120,7 +120,7 @@ static inline void queue_init(ThreadsQueue *tqp) { * * @notapi */ -static inline bool_t queue_isempty(ThreadsQueue *tqp) { +static inline bool_t queue_isempty(threads_queue_t *tqp) { return (bool_t)(tqp->p_next == (Thread *)tqp); } @@ -130,7 +130,7 @@ static inline bool_t queue_isempty(ThreadsQueue *tqp) { * * @notapi */ -static inline bool_t queue_notempty(ThreadsQueue *tqp) { +static inline bool_t queue_notempty(threads_queue_t *tqp) { return (bool_t)(tqp->p_next != (Thread *)tqp); } @@ -138,20 +138,20 @@ static inline bool_t queue_notempty(ThreadsQueue *tqp) { /* If the performance code path has been chosen then all the following functions are inlined into the various kernel modules.*/ #if CH_OPTIMIZE_SPEED -static inline void list_insert(Thread *tp, ThreadsList *tlp) { +static inline void list_insert(Thread *tp, threads_list_t *tlp) { tp->p_next = tlp->p_next; tlp->p_next = tp; } -static inline Thread *list_remove(ThreadsList *tlp) { +static inline Thread *list_remove(threads_list_t *tlp) { Thread *tp = tlp->p_next; tlp->p_next = tp->p_next; return tp; } -static inline void queue_prio_insert(Thread *tp, ThreadsQueue *tqp) { +static inline void queue_prio_insert(Thread *tp, threads_queue_t *tqp) { Thread *cp = (Thread *)tqp; do { @@ -162,21 +162,21 @@ static inline void queue_prio_insert(Thread *tp, ThreadsQueue *tqp) { tp->p_prev->p_next = cp->p_prev = tp; } -static inline void queue_insert(Thread *tp, ThreadsQueue *tqp) { +static inline void queue_insert(Thread *tp, threads_queue_t *tqp) { tp->p_next = (Thread *)tqp; tp->p_prev = tqp->p_prev; tp->p_prev->p_next = tqp->p_prev = tp; } -static inline Thread *queue_fifo_remove(ThreadsQueue *tqp) { +static inline Thread *queue_fifo_remove(threads_queue_t *tqp) { Thread *tp = tqp->p_next; (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp; return tp; } -static inline Thread *queue_lifo_remove(ThreadsQueue *tqp) { +static inline Thread *queue_lifo_remove(threads_queue_t *tqp) { Thread *tp = tqp->p_prev; (tqp->p_prev = tp->p_prev)->p_next = (Thread *)tqp; diff --git a/os/kernel/include/chmtx.h b/os/kernel/include/chmtx.h index 00ebb2a23..2d271153a 100644 --- a/os/kernel/include/chmtx.h +++ b/os/kernel/include/chmtx.h @@ -35,7 +35,7 @@ * @brief Mutex structure. */ typedef struct Mutex { - ThreadsQueue m_queue; /**< @brief Queue of the threads sleeping + threads_queue_t m_queue; /**< @brief Queue of the threads sleeping on this Mutex. */ Thread *m_owner; /**< @brief Owner @p Thread pointer or @p NULL. */ @@ -65,7 +65,7 @@ extern "C" { * * @param[in] name the name of the mutex variable */ -#define _MUTEX_DATA(name) {_THREADSQUEUE_DATA(name.m_queue), NULL, NULL} +#define _MUTEX_DATA(name) {_threads_queue_t_DATA(name.m_queue), NULL, NULL} /** * @brief Static mutex initializer. diff --git a/os/kernel/include/chqueues.h b/os/kernel/include/chqueues.h index 507f020d1..0ea68deb8 100644 --- a/os/kernel/include/chqueues.h +++ b/os/kernel/include/chqueues.h @@ -60,7 +60,7 @@ typedef void (*qnotify_t)(GenericQueue *qp); * @ref system_states) and is non-blocking. */ struct GenericQueue { - ThreadsQueue q_waiting; /**< @brief Queue of waiting threads. */ + threads_queue_t q_waiting; /**< @brief Queue of waiting threads. */ size_t q_counter; /**< @brief Resources counter. */ uint8_t *q_buffer; /**< @brief Pointer to the queue buffer.*/ uint8_t *q_top; /**< @brief Pointer to the first location @@ -200,7 +200,7 @@ typedef GenericQueue InputQueue; * @param[in] link application defined pointer */ #define _INPUTQUEUE_DATA(name, buffer, size, inotify, link) { \ - _THREADSQUEUE_DATA(name), \ + _threads_queue_t_DATA(name), \ 0, \ (uint8_t *)(buffer), \ (uint8_t *)(buffer) + (size), \ @@ -317,7 +317,7 @@ typedef GenericQueue OutputQueue; * @param[in] link application defined pointer */ #define _OUTPUTQUEUE_DATA(name, buffer, size, onotify, link) { \ - _THREADSQUEUE_DATA(name), \ + _threads_queue_t_DATA(name), \ (size), \ (uint8_t *)(buffer), \ (uint8_t *)(buffer) + (size), \ diff --git a/os/kernel/include/chschd.h b/os/kernel/include/chschd.h index 37e457c31..3fe3a00b2 100644 --- a/os/kernel/include/chschd.h +++ b/os/kernel/include/chschd.h @@ -79,13 +79,13 @@ #define firstprio(rlp) ((rlp)->p_next->p_prio) /** - * @extends ThreadsQueue + * @extends threads_queue_t * * @brief Ready list header. */ #if !defined(PORT_OPTIMIZED_READYLIST_STRUCT) || defined(__DOXYGEN__) typedef struct { - ThreadsQueue r_queue; /**< @brief Threads queue. */ + 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 diff --git a/os/kernel/include/chsem.h b/os/kernel/include/chsem.h index b5036af7c..649287e7d 100644 --- a/os/kernel/include/chsem.h +++ b/os/kernel/include/chsem.h @@ -35,7 +35,7 @@ * @brief Semaphore structure. */ typedef struct Semaphore { - ThreadsQueue s_queue; /**< @brief Queue of the threads sleeping + threads_queue_t s_queue; /**< @brief Queue of the threads sleeping on this semaphore. */ cnt_t s_cnt; /**< @brief The semaphore counter. */ } Semaphore; @@ -69,7 +69,7 @@ extern "C" { * @param[in] n the counter initial value, this value must be * non-negative */ -#define _SEMAPHORE_DATA(name, n) {_THREADSQUEUE_DATA(name.s_queue), n} +#define _SEMAPHORE_DATA(name, n) {_threads_queue_t_DATA(name.s_queue), n} /** * @brief Static semaphore initializer. diff --git a/os/kernel/include/chthreads.h b/os/kernel/include/chthreads.h index 800263092..b8ff5693e 100644 --- a/os/kernel/include/chthreads.h +++ b/os/kernel/include/chthreads.h @@ -104,20 +104,20 @@ typedef struct Mutex Mutex; typedef struct { Thread *p_next; /**< @brief Next in the list/queue. */ -} ThreadsList; +} threads_list_t; /** - * @extends ThreadsList + * @extends threads_list_t * * @brief Generic threads bidirectional linked list header and element. */ typedef struct { Thread *p_next; /**< @brief Next in the list/queue. */ Thread *p_prev; /**< @brief Previous in the queue. */ -} ThreadsQueue; +} threads_queue_t; /** - * @extends ThreadsQueue + * @extends threads_queue_t * * @brief Structure representing a thread. * @note Not all the listed fields are always needed, by switching off some @@ -126,9 +126,9 @@ typedef struct { */ struct Thread { Thread *p_next; /**< @brief Next in the list/queue. */ - /* End of the fields shared with the ThreadsList structure. */ + /* End of the fields shared with the threads_list_t structure.*/ Thread *p_prev; /**< @brief Previous in the queue. */ - /* End of the fields shared with the ThreadsQueue structure. */ + /* 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_USE_REGISTRY || defined(__DOXYGEN__) @@ -215,13 +215,13 @@ struct Thread { /** * @brief Termination waiting list. */ - ThreadsList p_waiting; + threads_list_t p_waiting; #endif #if CH_USE_MESSAGES || defined(__DOXYGEN__) /** * @brief Messages queue. */ - ThreadsQueue p_msgqueue; + threads_queue_t p_msgqueue; /** * @brief Thread message. */ diff --git a/os/kernel/include/chvt.h b/os/kernel/include/chvt.h index 0afc7f385..92e77abf2 100644 --- a/os/kernel/include/chvt.h +++ b/os/kernel/include/chvt.h @@ -62,9 +62,12 @@ typedef struct VirtualTimer VirtualTimer; * timer is often used in the code. */ typedef struct { - VirtualTimer *vt_next; /**< @brief Next timer in the list. */ - VirtualTimer *vt_prev; /**< @brief Last timer in the list. */ - volatile systime_t vt_time; /**< @brief Current system time. */ + VirtualTimer *vt_next; /**< @brief Next timer in the delta + list. */ + VirtualTimer *vt_prev; /**< @brief Last timer in the delta + list. */ + systime_t vt_time; /**< @brief Must be initialized to -1. */ + volatile systime_t vt_systime; /**< @brief System Time counter. */ } VTList; /** @@ -75,7 +78,7 @@ typedef struct { struct VirtualTimer { VirtualTimer *vt_next; /**< @brief Next timer in the list. */ VirtualTimer *vt_prev; /**< @brief Previous timer in the list. */ - systime_t vt_time; /**< @brief Absolute time. */ + systime_t vt_time; /**< @brief Time delta before timeout. */ vtfunc_t vt_func; /**< @brief Timer callback function pointer. */ void *vt_par; /**< @brief Timer callback function @@ -144,9 +147,9 @@ extern "C" { #endif void _vt_init(void); bool chVTIsTimeWithin(systime_t time, systime_t start, systime_t end); - void chVTSetAbsoluteI(VirtualTimer *vtp, systime_t time, - vtfunc_t vtfunc, void *par); - void chVTResetI(VirtualTimer *vtp); + void chVTDoSetI(VirtualTimer *vtp, systime_t delay, + vtfunc_t vtfunc, void *par); + void chVTDoResetI(VirtualTimer *vtp); #ifdef __cplusplus } #endif @@ -155,6 +158,22 @@ extern "C" { /* Module inline functions. */ /*===========================================================================*/ +/** + * @brief Initializes a @p VirtualTimer object. + * @note Initializing a timer object is not strictly required because + * the function @p chVTSetI() initializes the object too. This + * function is only useful if you need to perform a @p chVTIsArmed() + * check before calling @p chVTSetI(). + * + * @param[out] vtp the @p VirtualTimer structure pointer + * + * @init + */ +static inline void chVTObjectInit(VirtualTimer *vtp) { + + vtp->vt_func = NULL; +} + /** * @brief Current system time. * @details Returns the number of system ticks since the @p chSysInit() @@ -227,22 +246,6 @@ static inline bool chVTIsSystemTimeWithin(systime_t start, systime_t end) { return chVTIsTimeWithin(chVTGetSystemTime(), start, end); } -/** - * @brief Initializes a @p VirtualTimer object. - * @note Initializing a timer object is not strictly required because - * the function @p chVTSetI() initializes the object too. This - * function is only useful if you need to perform a @p chVTIsArmed() - * check before calling @p chVTSetI(). - * - * @param[out] vtp the @p VirtualTimer structure pointer - * - * @init - */ -static inline void chVTObjectInit(VirtualTimer *vtp) { - - vtp->vt_func = NULL; -} - /** * @brief Returns @p true if the specified timer is armed. * @pre The timer must have been initialized using @p chVTObjectInit() @@ -260,62 +263,18 @@ static inline bool chVTIsArmedI(VirtualTimer *vtp) { return (bool)(vtp->vt_func != NULL); } -/** - * @brief Enables a virtual timer. - * - * @param[out] vtp the @p VirtualTimer structure pointer - * @param[in] delay the number of ticks before the operation timeouts. - * @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 - * - * @iclass - */ -static inline void chVTSetI(VirtualTimer *vtp, systime_t delay, - vtfunc_t vtfunc, void *par) { - - chVTSetAbsoluteI(vtp, chVTGetSystemTimeI() + delay, vtfunc, par); -} - -/** - * @brief Enables a virtual timer. - * - * @param[out] vtp the @p VirtualTimer structure pointer - * @param[in] delay the number of ticks before the operation timeouts. - * @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 - */ -static inline void chVTSet(VirtualTimer *vtp, systime_t delay, - vtfunc_t vtfunc, void *par) { - - chSysLock(); - chVTSetI(vtp, delay, vtfunc, par); - chSysUnlock(); -} - /** * @brief Disables a Virtual Timer. - * @pre The timer must be in armed state before calling this function. + * @note The timer is first checked and disabled only if armed. * * @param[in] vtp the @p VirtualTimer structure pointer * * @iclass */ -static inline void chVTDoResetI(VirtualTimer *vtp) { +static inline void chVTResetI(VirtualTimer *vtp) { - chDbgCheckClassI(); - chDbgCheck(vtp != NULL, "chVTDoResetI"); - - vtp->vt_prev->vt_next = vtp->vt_next; - vtp->vt_next->vt_prev = vtp->vt_prev; - vtp->vt_func = (vtfunc_t)NULL; + if (chVTIsArmedI(vtp)) + chVTDoResetI(vtp); } /** @@ -333,6 +292,51 @@ static inline void chVTReset(VirtualTimer *vtp) { chSysUnlock(); } +/** + * @brief Enables a virtual timer. + * @details If the virtual timer was already enabled then it is re-enabled + * using the new parameters. + * + * @param[in] vtp the @p VirtualTimer structure pointer + * @param[in] delay the number of ticks before the operation timeouts. + * @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 + * + * @iclass + */ +static inline void chVTSetI(VirtualTimer *vtp, systime_t delay, + vtfunc_t vtfunc, void *par) { + + chVTResetI(vtp); + chVTDoSetI(vtp, delay, vtfunc, par); +} + +/** + * @brief Enables a virtual timer. + * @details If the virtual timer was already enabled then it is re-enabled + * using the new parameters. + * + * @param[in] vtp the @p VirtualTimer structure pointer + * @param[in] delay the number of ticks before the operation timeouts. + * @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 + */ +static inline void chVTSet(VirtualTimer *vtp, systime_t delay, + vtfunc_t vtfunc, void *par) { + + chSysLock(); + chVTSetI(vtp, delay, vtfunc, par); + chSysUnlock(); +} + /** * @brief Virtual timers ticker. * @note The system lock is released before entering the callback and @@ -343,17 +347,19 @@ static inline void chVTReset(VirtualTimer *vtp) { * @iclass */ static inline void chVTDoTickI(void) { - systime_t systime = ++vtlist.vt_time; chDbgCheckClassI(); + vtlist.vt_systime++; if (&vtlist != (VTList *)vtlist.vt_next) { VirtualTimer *vtp; - while (((VirtualTimer *)&vtlist != (vtp = vtlist.vt_next)) && - (vtp->vt_time == systime)) { + --vtlist.vt_next->vt_time; + while (!(vtp = vtlist.vt_next)->vt_time) { vtfunc_t fn = vtp->vt_func; - chVTDoResetI(vtp); + 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(); diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index c0961a5c9..9e9b276e6 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -65,7 +65,7 @@ * * @notapi */ -void queue_prio_insert(Thread *tp, ThreadsQueue *tqp) { +void queue_prio_insert(Thread *tp, threads_queue_t *tqp) { /* cp iterates over the queue.*/ Thread *cp = (Thread *)tqp; @@ -88,7 +88,7 @@ void queue_prio_insert(Thread *tp, ThreadsQueue *tqp) { * * @notapi */ -void queue_insert(Thread *tp, ThreadsQueue *tqp) { +void queue_insert(Thread *tp, threads_queue_t *tqp) { tp->p_next = (Thread *)tqp; tp->p_prev = tqp->p_prev; @@ -105,7 +105,7 @@ void queue_insert(Thread *tp, ThreadsQueue *tqp) { * * @notapi */ -Thread *queue_fifo_remove(ThreadsQueue *tqp) { +Thread *queue_fifo_remove(threads_queue_t *tqp) { Thread *tp = tqp->p_next; (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp; @@ -122,7 +122,7 @@ Thread *queue_fifo_remove(ThreadsQueue *tqp) { * * @notapi */ -Thread *queue_lifo_remove(ThreadsQueue *tqp) { +Thread *queue_lifo_remove(threads_queue_t *tqp) { Thread *tp = tqp->p_prev; (tqp->p_prev = tp->p_prev)->p_next = (Thread *)tqp; @@ -154,7 +154,7 @@ Thread *queue_dequeue(Thread *tp) { * * @notapi */ -void list_insert(Thread *tp, ThreadsList *tlp) { +void list_insert(Thread *tp, threads_list_t *tlp) { tp->p_next = tlp->p_next; tlp->p_next = tp; @@ -169,7 +169,7 @@ void list_insert(Thread *tp, ThreadsList *tlp) { * * @notapi */ -Thread *list_remove(ThreadsList *tlp) { +Thread *list_remove(threads_list_t *tlp) { Thread *tp = tlp->p_next; tlp->p_next = tp->p_next; diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index adeb0dd52..38ecbed74 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -132,7 +132,8 @@ void chMtxLockS(Mutex *mp) { switch (tp->p_state) { case THD_STATE_WTMTX: /* Re-enqueues the mutex owner with its new priority.*/ - queue_prio_insert(queue_dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); + queue_prio_insert(queue_dequeue(tp), + (threads_queue_t *)tp->p_u.wtobjp); tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; continue; #if CH_USE_CONDVARS | \ @@ -148,7 +149,8 @@ void chMtxLockS(Mutex *mp) { case THD_STATE_SNDMSGQ: #endif /* Re-enqueues tp with its new priority on the queue.*/ - queue_prio_insert(queue_dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); + queue_prio_insert(queue_dequeue(tp), + (threads_queue_t *)tp->p_u.wtobjp); break; #endif case THD_STATE_READY: diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index ab9b88040..4f0fa839d 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -186,7 +186,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { if (TIME_INFINITE != time) { VirtualTimer vt; - chVTSetI(&vt, time, wakeup, currp); + chVTDoSetI(&vt, time, wakeup, currp); chSchGoSleepS(newstate); if (chVTIsArmedI(&vt)) chVTDoResetI(&vt); diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 8864bce0c..e93b2244c 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -67,7 +67,8 @@ VTList vtlist; void _vt_init(void) { vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist; - vtlist.vt_time = 0; + vtlist.vt_time = (systime_t)-1; + vtlist.vt_systime = 0; } /** @@ -93,12 +94,18 @@ bool chVTIsTimeWithin(systime_t time, systime_t start, systime_t end) { /** * @brief Enables a virtual timer. - * @details The timer is enabled and programmed to trigger at the absolute - * system time specified as parameter. - * @note The associated function is invoked from interrupt context. + * @details The timer is enabled and programmed to trigger after the delay + * specified as parameter. + * @pre The timer must not be already armed before calling this function. + * @note The callback function is invoked from interrupt context. * * @param[out] vtp the @p VirtualTimer structure pointer - * @param[in] time absolute system time + * @param[in] delay 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. @@ -107,51 +114,50 @@ bool chVTIsTimeWithin(systime_t time, systime_t start, systime_t end) { * * @iclass */ -void chVTSetAbsoluteI(VirtualTimer *vtp, systime_t time, - vtfunc_t vtfunc, void *par) { +void chVTDoSetI(VirtualTimer *vtp, systime_t delay, + vtfunc_t vtfunc, void *par) { VirtualTimer *p; - systime_t systime = vtlist.vt_time; chDbgCheckClassI(); - chDbgCheck((vtp != NULL) && (vtfunc != NULL), "chVTSetI"); + chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE), + "chVTDoSetI"); vtp->vt_par = par; vtp->vt_func = vtfunc; - vtp->vt_time = time; - if (time <= systime) { - p = vtlist.vt_prev; - while ((p->vt_time <= systime) && (p->vt_time > time)) - p = p->vt_prev; - vtp->vt_next = (vtp->vt_prev = p)->vt_next; - vtp->vt_next->vt_prev = p->vt_next = vtp; - } - else { - p = vtlist.vt_next; - while ((p->vt_time > systime) && (p->vt_time < time)) - p = p->vt_next; - vtp->vt_prev = (vtp->vt_next = p)->vt_prev; - vtp->vt_prev->vt_next = p->vt_prev = vtp; + p = vtlist.vt_next; + while (p->vt_time < delay) { + delay -= p->vt_time; + p = p->vt_next; } + + vtp->vt_prev = (vtp->vt_next = p)->vt_prev; + vtp->vt_prev->vt_next = p->vt_prev = vtp; + vtp->vt_time = delay; + if (p != (void *)&vtlist) + p->vt_time -= delay; } /** * @brief Disables a Virtual Timer. - * @note The timer is first checked and disabled only if armed. + * @pre The timer must be in armed state before calling this function. * * @param[in] vtp the @p VirtualTimer structure pointer * * @iclass */ -void chVTResetI(VirtualTimer *vtp) { +void chVTDoResetI(VirtualTimer *vtp) { chDbgCheckClassI(); - chDbgCheck(vtp != NULL, "chVTResetI"); + chDbgCheck(vtp != NULL, "chVTDoResetI"); + chDbgAssert(vtp->vt_func != NULL, + "chVTDoResetI(), #1", + "timer not set or already triggered"); - if (chVTIsArmedI(vtp)) { - vtp->vt_prev->vt_next = vtp->vt_next; - vtp->vt_next->vt_prev = vtp->vt_prev; - vtp->vt_func = (vtfunc_t)NULL; - } + if (vtp->vt_next != (void *)&vtlist) + vtp->vt_next->vt_time += vtp->vt_time; + vtp->vt_prev->vt_next = vtp->vt_next; + vtp->vt_next->vt_prev = vtp->vt_prev; + vtp->vt_func = (vtfunc_t)NULL; } /** @} */ diff --git a/test/testbmk.c b/test/testbmk.c index 5b46023d8..7e801c743 100644 --- a/test/testbmk.c +++ b/test/testbmk.c @@ -507,8 +507,8 @@ static void bmk10_execute(void) { test_start_timer(1000); do { chSysLock(); - chVTSetI(&vt1, 1, tmo, NULL); - chVTSetI(&vt2, 10000, tmo, NULL); + chVTDoSetI(&vt1, 1, tmo, NULL); + chVTDoSetI(&vt2, 10000, tmo, NULL); chVTResetI(&vt1); chVTResetI(&vt2); chSysUnlock();