/** * @brief Time management handler. * @note This handler has to be invoked by a periodic ISR in order to * reschedule the waiting threads. * * @iclass */ void nilSysTimerHandlerI(void) { #if NIL_CFG_TIMEDELTA == 0 thread_ref_t tr = &nil.threads[0]; nil.systime++; do { /* Is the thread in a wait state with timeout?.*/ if (tr->timeout > 0) { nilDbgAssert(!NIL_THD_IS_READY(tr), "nilSysTimerHandlerI(), #1", "is ready"); /* Did the timer reach zero?*/ if (--tr->timeout == 0) { /* Timeout on semaphores requires a special handling because the semaphore counter must be incremented.*/ if (NIL_THD_IS_WTSEM(tr)) tr->u1.semp->cnt++; else if (NIL_THD_IS_SUSP(tr)) tr->u1.trp = NULL; nilSchReadyI(tr, NIL_MSG_TMO); } } /* Lock released in order to give a preemption chance on those architectures supporting IRQ preemption.*/ nilSysUnlockFromISR(); tr++; nilSysLockFromISR(); #if WHG_MOD } while (tr < nil.idlep); #else /* WHG_MOD */ } while (tr < &nil.threads[NIL_CFG_NUM_THREADS]);
/** * @brief Wakes up a thread waiting on a thread reference object. * @note This function must not reschedule because it can be called from * ISR context. * * @param[in] trp a pointer to a thread reference object * @param[in] msg the message code * * @iclass */ void chThdResumeI(thread_reference_t *trp, msg_t msg) { if (*trp != NULL) { thread_reference_t tr = *trp; chDbgAssert(NIL_THD_IS_SUSP(tr), "not suspended"); *trp = NULL; (void) chSchReadyI(tr, msg); } }
/** * @brief Time management handler. * @note This handler has to be invoked by a periodic ISR in order to * reschedule the waiting threads. * * @iclass */ void chSysTimerHandlerI(void) { #if NIL_CFG_ST_TIMEDELTA == 0 thread_t *tp = &nil.threads[0]; nil.systime++; do { /* Is the thread in a wait state with timeout?.*/ if (tp->timeout > (systime_t)0) { chDbgAssert(!NIL_THD_IS_READY(tp), "is ready"); /* Did the timer reach zero?*/ if (--tp->timeout == (systime_t)0) { /* Timeout on semaphores requires a special handling because the semaphore counter must be incremented.*/ /*lint -save -e9013 [15.7] There is no else because it is not needed.*/ if (NIL_THD_IS_WTSEM(tp)) { tp->u1.semp->cnt++; } else if (NIL_THD_IS_SUSP(tp)) { *tp->u1.trp = NULL; } /*lint -restore*/ (void) chSchReadyI(tp, MSG_TIMEOUT); } } /* Lock released in order to give a preemption chance on those architectures supporting IRQ preemption.*/ chSysUnlockFromISR(); tp++; chSysLockFromISR(); } while (tp < &nil.threads[NIL_CFG_NUM_THREADS]); #else thread_t *tp = &nil.threads[0]; systime_t next = (systime_t)0; chDbgAssert(nil.nexttime == port_timer_get_alarm(), "time mismatch"); do { /* Is the thread in a wait state with timeout?.*/ if (tp->timeout > (systime_t)0) { chDbgAssert(!NIL_THD_IS_READY(tp), "is ready"); chDbgAssert(tp->timeout >= (nil.nexttime - nil.lasttime), "skipped one"); tp->timeout -= nil.nexttime - nil.lasttime; if (tp->timeout == (systime_t)0) { /* Timeout on semaphores requires a special handling because the semaphore counter must be incremented.*/ /*lint -save -e9013 [15.7] There is no else because it is not needed.*/ if (NIL_THD_IS_WTSEM(tp)) { tp->u1.semp->cnt++; } else if (NIL_THD_IS_SUSP(tp)) { *tp->u1.trp = NULL; } /*lint -restore*/ (void) chSchReadyI(tp, MSG_TIMEOUT); } else { if (tp->timeout <= (systime_t)(next - (systime_t)1)) { next = tp->timeout; } } } /* Lock released in order to give a preemption chance on those architectures supporting IRQ preemption.*/ chSysUnlockFromISR(); tp++; chSysLockFromISR(); } while (tp < &nil.threads[NIL_CFG_NUM_THREADS]); nil.lasttime = nil.nexttime; if (next > (systime_t)0) { nil.nexttime += next; port_timer_set_alarm(nil.nexttime); } else { /* No tick event needed.*/ port_timer_stop_alarm(); } #endif }