bool sched_removereadytorun(FAR _TCB *rtcb) { bool ret = false; /* Check if the TCB to be removed is at the head of the ready * to run list. In this case, we are removing the currently * active task. */ if (!rtcb->blink) { /* There must always be at least one task in the list (the idle task) */ ASSERT(rtcb->flink != NULL); /* Inform the instrumentation layer that we are switching tasks */ sched_note_switch(rtcb, rtcb->flink); rtcb->flink->task_state = TSTATE_TASK_RUNNING; ret = true; } /* Remove the TCB from the ready-to-run list */ dq_rem((FAR dq_entry_t*)rtcb, (dq_queue_t*)&g_readytorun); rtcb->task_state = TSTATE_TASK_INVALID; return ret; }
bool sched_removereadytorun(FAR struct tcb_s *rtcb) { FAR struct tcb_s *ntcb = NULL; bool ret = false; /* Check if the TCB to be removed is at the head of the ready to run list. * In this case, we are removing the currently active task. */ if (!rtcb->blink) { /* There must always be at least one task in the list (the idle task) */ ntcb = (FAR struct tcb_s *)rtcb->flink; DEBUGASSERT(ntcb != NULL); /* Inform the instrumentation layer that we are switching tasks */ sched_note_switch(rtcb, ntcb); ntcb->task_state = TSTATE_TASK_RUNNING; ret = true; } /* Remove the TCB from the ready-to-run list */ dq_rem((FAR dq_entry_t *)rtcb, (FAR dq_queue_t *)&g_readytorun); /* Since the TCB is not in any list, it is now invalid */ rtcb->task_state = TSTATE_TASK_INVALID; return ret; }
bool sched_addreadytorun(FAR _TCB *btcb) { FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head; bool ret; /* Check if pre-emption is disabled for the current running task and if * the new ready-to-run task would cause the current running task to be * preempted. */ if (rtcb->lockcount && rtcb->sched_priority < btcb->sched_priority) { /* Yes. Preemption would occur! Add the new ready-to-run task to the * g_pendingtasks task list for now. */ sched_addprioritized(btcb, (FAR dq_queue_t*)&g_pendingtasks); btcb->task_state = TSTATE_TASK_PENDING; ret = false; } /* Otherwise, add the new task to the g_readytorun task list */ else if (sched_addprioritized(btcb, (FAR dq_queue_t*)&g_readytorun)) { /* Information the instrumentation logic that we are switching tasks */ sched_note_switch(rtcb, btcb); /* The new btcb was added at the head of the g_readytorun list. It * is now to new active task! */ ASSERT(!rtcb->lockcount && btcb->flink != NULL); btcb->task_state = TSTATE_TASK_RUNNING; btcb->flink->task_state = TSTATE_TASK_READYTORUN; ret = true; } else { /* The new btcb was added in the middle of the g_readytorun list */ btcb->task_state = TSTATE_TASK_READYTORUN; ret = false; } return ret; }
bool sched_mergepending(void) { FAR struct tcb_s *pndtcb; FAR struct tcb_s *pndnext; FAR struct tcb_s *rtrtcb; FAR struct tcb_s *rtrprev; bool ret = false; /* Initialize the inner search loop */ rtrtcb = (FAR struct tcb_s*)g_readytorun.head; /* Process every TCB in the g_pendingtasks list */ for (pndtcb = (FAR struct tcb_s*)g_pendingtasks.head; pndtcb; pndtcb = pndnext) { pndnext = pndtcb->flink; /* Search the g_readytorun list to find the location to insert the * new pndtcb. Each is list is maintained in ascending sched_priority * order. */ for (; (rtrtcb && pndtcb->sched_priority <= rtrtcb->sched_priority); rtrtcb = rtrtcb->flink); /* Add the pndtcb to the spot found in the list. Check if the * pndtcb goes at the ends of the g_readytorun list. This would be * error condition since the idle test must always be at the end of * the g_readytorun list! */ if (!rtrtcb) { PANIC(OSERR_NOIDLETASK); } else { /* The pndtcb goes just before rtrtcb */ rtrprev = rtrtcb->blink; if (!rtrprev) { /* Special case: Inserting pndtcb at the head of the list */ /* Inform the instrumentation layer that we are switching tasks */ sched_note_switch(rtrtcb, pndtcb); /* Then insert at the head of the list */ pndtcb->flink = rtrtcb; pndtcb->blink = NULL; rtrtcb->blink = pndtcb; g_readytorun.head = (FAR dq_entry_t*)pndtcb; rtrtcb->task_state = TSTATE_TASK_READYTORUN; pndtcb->task_state = TSTATE_TASK_RUNNING; ret = true; } else { /* Insert in the middle of the list */ pndtcb->flink = rtrtcb; pndtcb->blink = rtrprev; rtrprev->flink = pndtcb; rtrtcb->blink = pndtcb; pndtcb->task_state = TSTATE_TASK_READYTORUN; } } /* Set up for the next time through */ rtrtcb = pndtcb; } /* Mark the input list empty */ g_pendingtasks.head = NULL; g_pendingtasks.tail = NULL; return ret; }