summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-08-12 11:12:00 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-08-12 11:12:00 -0600
commit57c33e5418a3bdf06ed144b4a0405506d9c1f89a (patch)
tree8486c5cfb74664ec49179dc9fdbebb9995f35159
parent753d1b43c61a609e099f3055060ce116c96056d9 (diff)
downloadnuttx-57c33e5418a3bdf06ed144b4a0405506d9c1f89a.tar.gz
nuttx-57c33e5418a3bdf06ed144b4a0405506d9c1f89a.tar.bz2
nuttx-57c33e5418a3bdf06ed144b4a0405506d9c1f89a.zip
Tickless Stuff: Back out the risky timer operations when the ready-to-run list is modified. That is unsafe. An ugly workaround is just to keep an interval timer going all of the time with a minimum duration equal to the timeslice interval.
-rw-r--r--nuttx/sched/sched/sched_addblocked.c1
-rw-r--r--nuttx/sched/sched/sched_addreadytorun.c23
-rw-r--r--nuttx/sched/sched/sched_removereadytorun.c36
-rw-r--r--nuttx/sched/sched/sched_timerexpiration.c29
4 files changed, 32 insertions, 57 deletions
diff --git a/nuttx/sched/sched/sched_addblocked.c b/nuttx/sched/sched/sched_addblocked.c
index 1a3fc9098..cb2eda190 100644
--- a/nuttx/sched/sched/sched_addblocked.c
+++ b/nuttx/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/nuttx/sched/sched/sched_addreadytorun.c b/nuttx/sched/sched/sched_addreadytorun.c
index f99bd3186..04cc2afcb 100644
--- a/nuttx/sched/sched/sched_addreadytorun.c
+++ b/nuttx/sched/sched/sched_addreadytorun.c
@@ -43,8 +43,6 @@
#include <queue.h>
#include <assert.h>
-#include <nuttx/clock.h>
-
#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/nuttx/sched/sched/sched_removereadytorun.c b/nuttx/sched/sched/sched_removereadytorun.c
index 5fe5096bb..0fdcc1a29 100644
--- a/nuttx/sched/sched/sched_removereadytorun.c
+++ b/nuttx/sched/sched/sched_removereadytorun.c
@@ -43,8 +43,6 @@
#include <queue.h>
#include <assert.h>
-#include <nuttx/clock.h>
-
#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/nuttx/sched/sched/sched_timerexpiration.c b/nuttx/sched/sched/sched_timerexpiration.c
index 267768586..c4eeaafbb 100644
--- a/nuttx/sched/sched/sched_timerexpiration.c
+++ b/nuttx/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
{