/** * @brief Switches to the first thread on the runnable queue. * @details The current thread is positioned in the ready list ahead of all * threads having the same priority. * @note Not a user function, it is meant to be invoked by the scheduler * itself or from within the port layer. * * @special */ void chSchDoRescheduleAhead(void) { thread_t *otp, *cp; otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(queue_fifo_remove(&ch.rlist.r_queue)); #if defined(CH_CFG_IDLE_LEAVE_HOOK) if (otp->p_prio == IDLEPRIO) { CH_CFG_IDLE_LEAVE_HOOK(); } #endif currp->p_state = CH_STATE_CURRENT; otp->p_state = CH_STATE_READY; cp = (thread_t *)&ch.rlist.r_queue; do { cp = cp->p_next; } while (cp->p_prio > otp->p_prio); /* Insertion on p_prev.*/ otp->p_next = cp; otp->p_prev = cp->p_prev; otp->p_prev->p_next = cp->p_prev = otp; chSysSwitch(currp, otp); }
/** * @brief Wakes up a thread. * @details The thread is inserted into the ready list or immediately made * running depending on its relative priority compared to the current * thread. * @pre The thread must not be already inserted in any list through its * @p p_next and @p p_prev or list corruption would occur. * @note It is equivalent to a @p chSchReadyI() followed by a * @p chSchRescheduleS() but much more efficient. * @note The function assumes that the current thread has the highest * priority. * * @param[in] ntp the thread to be made ready * @param[in] msg the wakeup message * * @sclass */ void chSchWakeupS(thread_t *ntp, msg_t msg) { chDbgCheckClassS(); /* Storing the message to be retrieved by the target thread when it will restart execution.*/ ntp->p_u.rdymsg = msg; /* If the waken thread has a not-greater priority than the current one then it is just inserted in the ready list else it made running immediately and the invoking thread goes in the ready list instead.*/ if (ntp->p_prio <= currp->p_prio) { chSchReadyI(ntp); } else { thread_t *otp = chSchReadyI(currp); setcurrp(ntp); #if defined(CH_CFG_IDLE_LEAVE_HOOK) if (otp->p_prio == IDLEPRIO) { CH_CFG_IDLE_LEAVE_HOOK(); } #endif ntp->p_state = CH_STATE_CURRENT; chSysSwitch(ntp, otp); } }
void chSchDoRescheduleBehind(void) { Thread *otp; otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; otp->p_preempt = CH_TIME_QUANTUM; chSchReadyI(otp); chSysSwitch(currp, otp); }
void chSchGoSleepS(tstate_t newstate) { Thread *otp; chDbgCheckClassS(); (otp = currp)->p_state = newstate; #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; chSysSwitch(currp, otp); }
void chSchGoSleepS(tstate_t newstate) { Thread *otp; chDbgCheckClassS(); (otp = currp)->p_state = newstate; #if CH_TIME_QUANTUM > 0 /* The thread is renouncing its remaining time slices so it will have a new time quantum when it will wakeup.*/ otp->p_preempt = CH_TIME_QUANTUM; #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; chSysSwitch(currp, otp); }
void chSchWakeupS(Thread *ntp, msg_t msg) { chDbgCheckClassS(); ntp->p_u.rdymsg = msg; /* If the waken thread has a not-greater priority than the current one then it is just inserted in the ready list else it made running immediately and the invoking thread goes in the ready list instead.*/ if (ntp->p_prio <= currp->p_prio) chSchReadyI(ntp); else { Thread *otp = chSchReadyI(currp); setcurrp(ntp); ntp->p_state = THD_STATE_CURRENT; chSysSwitch(ntp, otp); } }
/** * @brief Switches to the first thread on the runnable queue. * @details The current thread is positioned in the ready list behind all * threads having the same priority. The thread regains its time * quantum. * @note Not a user function, it is meant to be invoked by the scheduler * itself or from within the port layer. * * @special */ void chSchDoRescheduleBehind(void) { thread_t *otp; otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(queue_fifo_remove(&ch.rlist.r_queue)); #if defined(CH_CFG_IDLE_LEAVE_HOOK) if (otp->p_prio == IDLEPRIO) { CH_CFG_IDLE_LEAVE_HOOK(); } #endif currp->p_state = CH_STATE_CURRENT; #if CH_CFG_TIME_QUANTUM > 0 otp->p_preempt = CH_CFG_TIME_QUANTUM; #endif chSchReadyI(otp); chSysSwitch(currp, otp); }
void chSchDoRescheduleAhead(void) { Thread *otp, *cp; otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; otp->p_state = THD_STATE_READY; cp = (Thread *)&rlist.r_queue; do { cp = cp->p_next; } while (cp->p_prio > otp->p_prio); /* Insertion on p_prev.*/ otp->p_next = cp; otp->p_prev = cp->p_prev; otp->p_prev->p_next = cp->p_prev = otp; chSysSwitch(currp, otp); }
/** * @brief Puts the current thread to sleep into the specified state. * @details The thread goes into a sleeping state. The possible * @ref thread_states are defined into @p threads.h. * * @param[in] newstate the new thread state * * @sclass */ void chSchGoSleepS(tstate_t newstate) { thread_t *otp; chDbgCheckClassS(); (otp = currp)->p_state = newstate; #if CH_CFG_TIME_QUANTUM > 0 /* The thread is renouncing its remaining time slices so it will have a new time quantum when it will wakeup.*/ otp->p_preempt = CH_CFG_TIME_QUANTUM; #endif setcurrp(queue_fifo_remove(&ch.rlist.r_queue)); #if defined(CH_CFG_IDLE_ENTER_HOOK) if (currp->p_prio == IDLEPRIO) { CH_CFG_IDLE_ENTER_HOOK(); } #endif currp->p_state = CH_STATE_CURRENT; chSysSwitch(currp, otp); }