From 78789700a2f4a7e6580b63e0ede824615f586456 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 11 Aug 2014 15:07:15 -0600 Subject: Minor update to handling of timeslick delay on tast switches --- nuttx/sched/sched/sched_addreadytorun.c | 15 ++++++++++++- nuttx/sched/sched/sched_removereadytorun.c | 35 +++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/nuttx/sched/sched/sched_addreadytorun.c b/nuttx/sched/sched/sched_addreadytorun.c index f905d2743..f99bd3186 100644 --- a/nuttx/sched/sched/sched_addreadytorun.c +++ b/nuttx/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/nuttx/sched/sched/sched_removereadytorun.c b/nuttx/sched/sched/sched_removereadytorun.c index 84a4726b7..5fe5096bb 100644 --- a/nuttx/sched/sched/sched_removereadytorun.c +++ b/nuttx/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; + + /* Remove the TCB from the head of the ready-to-run list */ - rtcb->flink->task_state = TSTATE_TASK_RUNNING; + (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; -- cgit v1.2.3