diff --git a/sched/sched/sched_addblocked.c b/sched/sched/sched_addblocked.c index 1a3fc90987..cb2eda1908 100644 --- a/sched/sched/sched_addblocked.c +++ b/sched/sched/sched_addblocked.c @@ -119,4 +119,3 @@ void sched_addblocked(FAR struct tcb_s *btcb, tstate_t task_state) btcb->task_state = task_state; } - diff --git a/sched/sched/sched_addreadytorun.c b/sched/sched/sched_addreadytorun.c index f99bd31864..04cc2afcb4 100644 --- a/sched/sched/sched_addreadytorun.c +++ b/sched/sched/sched_addreadytorun.c @@ -43,8 +43,6 @@ #include #include -#include - #include "sched/sched.h" /**************************************************************************** @@ -137,27 +135,6 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb) btcb->task_state = TSTATE_TASK_RUNNING; 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. - */ - - if ((rtcb->flags & TCB_FLAG_ROUND_ROBIN) != 0 || - (btcb->flags & TCB_FLAG_ROUND_ROBIN) != 0) - { - sched_timer_reassess(); - } -#endif -#endif ret = true; } else diff --git a/sched/sched/sched_removereadytorun.c b/sched/sched/sched_removereadytorun.c index 5fe5096bbc..0fdcc1a294 100644 --- a/sched/sched/sched_removereadytorun.c +++ b/sched/sched/sched_removereadytorun.c @@ -43,8 +43,6 @@ #include #include -#include - #include "sched/sched.h" /**************************************************************************** @@ -112,40 +110,12 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb) sched_note_switch(rtcb, ntcb); ntcb->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. - */ - - 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) */ - dq_rem((FAR dq_entry_t *)rtcb, (FAR dq_queue_t *)&g_readytorun); - } + /* 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 */ diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index 267768586c..c4eeaafbb7 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -58,6 +58,22 @@ /************************************************************************ * Pre-processor Definitions ************************************************************************/ +/* In the original design, it was planned that sched_timer_reasses() be + * called whenever there was a change at the head of the ready-to-run + * list. That call was intended to establish a new time-slice or to + * stop an old time-slice timer. However, it turns out that that + * solution is too fragile: The system is too vulnerable at the time + * that the read-to-run list is modified in order to muck with timers. + * + * The kludge/work-around is simple to keep the timer running all of the + * time with an interval of no more than the timeslice interface. If we + * this, then there is really no need to do anything when on context + * switches. + */ + +#if CONFIG_RR_INTERVAL > 0 +# define KEEP_ALIVE_HACK 1 +#endif #ifndef MIN # define MIN(a,b) (((a) < (b)) ? (a) : (b)) @@ -212,7 +228,11 @@ static unsigned int sched_process_timeslice(unsigned int ticks, bool noswitches) { FAR struct tcb_s *rtcb = (FAR struct tcb_s*)g_readytorun.head; +#ifdef KEEP_ALIVE_HACK + unsigned int ret = MSEC2TICK(CONFIG_RR_INTERVAL); +#else unsigned int ret = 0; +#endif int decr; /* Check if the currently executing task uses round robin @@ -293,13 +313,22 @@ sched_process_timeslice(unsigned int ticks, bool noswitches) */ rtcb = (FAR struct tcb_s*)g_readytorun.head; + + /* Check if the new task at the head of the ready-to-run + * supports round robin scheduling. + */ + if ((rtcb->flags & TCB_FLAG_ROUND_ROBIN) != 0) { /* The new task at the head of the ready to run * list does not support round robin scheduling. */ +#ifdef KEEP_ALIVE_HACK + ret = MSEC2TICK(CONFIG_RR_INTERVAL); +#else ret = 0; +#endif } else {