diff --git a/sched/sched/sched_addreadytorun.c b/sched/sched/sched_addreadytorun.c index f905d27430..f99bd31864 100644 --- a/sched/sched/sched_addreadytorun.c +++ b/sched/sched/sched_addreadytorun.c @@ -43,6 +43,8 @@ #include #include +#include + #include "sched/sched.h" /**************************************************************************** @@ -137,12 +139,23 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) btcb->flink->task_state = TSTATE_TASK_READYTORUN; #if CONFIG_RR_INTERVAL > 0 + /* Reset the round robin timeslice interval of both the old + * and the new head of the ready-to-run list. + */ + + rtcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); + btcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); + #if 0 /* REVISIT: This can cause crashes in certain cases */ /* Whenever the task at the head of the ready-to-run changes, we * must reassess the interval time that controls time-slicing. */ - sched_timer_reassess(); + if ((rtcb->flags & TCB_FLAG_ROUND_ROBIN) != 0 || + (btcb->flags & TCB_FLAG_ROUND_ROBIN) != 0) + { + sched_timer_reassess(); + } #endif #endif ret = true; diff --git a/sched/sched/sched_removereadytorun.c b/sched/sched/sched_removereadytorun.c index 84a4726b7d..5fe5096bbc 100644 --- a/sched/sched/sched_removereadytorun.c +++ b/sched/sched/sched_removereadytorun.c @@ -43,6 +43,8 @@ #include #include +#include + #include "sched/sched.h" /**************************************************************************** @@ -92,6 +94,7 @@ 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. @@ -102,29 +105,49 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb) { /* There must always be at least one task in the list (the idle task) */ - ASSERT(rtcb->flink != NULL); + ntcb = (FAR struct tcb_s *)rtcb->flink; + DEBUGASSERT(ntcb != NULL); /* Inform the instrumentation layer that we are switching tasks */ - sched_note_switch(rtcb, rtcb->flink); + sched_note_switch(rtcb, ntcb); + ntcb->task_state = TSTATE_TASK_RUNNING; - rtcb->flink->task_state = TSTATE_TASK_RUNNING; + /* Remove the TCB from the head of the ready-to-run list */ + + (void)dq_remfirst((FAR dq_queue_t *)&g_readytorun); #if CONFIG_RR_INTERVAL > 0 + /* Reset the round robin timeslice interval of the new head of the + * ready-to-run list. + */ + + ntcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); + #if 0 /* REVISIT: This can cause crashes in certain cases */ /* Whenever the task at the head of the ready-to-run changes, we * must reassess the interval time that controls time-slicing. */ - sched_timer_reassess(); + if ((rtcb->flags & TCB_FLAG_ROUND_ROBIN) != 0 || + (ntcb->flags & TCB_FLAG_ROUND_ROBIN) != 0) + { + sched_timer_reassess(); + } #endif #endif + /* Indicate that a context switch is occurring */ + ret = true; } + else + { + /* Remove the TCB from the ready-to-run list (not from the head) */ - /* Remove the TCB from the ready-to-run list */ + dq_rem((FAR dq_entry_t *)rtcb, (FAR dq_queue_t *)&g_readytorun); + } - dq_rem((FAR dq_entry_t*)rtcb, (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;