You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/04/11 23:25:53 UTC

[23/28] incubator-mynewt-core git commit: Make task context switches in sim behave similarly to real hardware.

Make task context switches in sim behave similarly to real hardware.

Prior to the change context switching in sim happened "inline" as opposed
to on hardware where it would trigger a special interrupt and the context
switching happened in context of the interrupt handler.

This causes subtle differences in how tasks are scheduled inside sim.
For e.g. 'os_callout_tick()' is called from the timer handler with
interrupts disabled. If a callout fires this function will post to an
eventq and if a task is sleeping on it then it will be made runnable.

On 'sim' the context switch happened immediately (i.e. from the timer
handler context to the task that became runnable) whereas on real hardware
all it would do is trigger the special interrupt. Note that the interrupt
will not be recognized until the timer handler re-enables interrupts.

The context switching behavior is now done similarly on sim by posting
a signal to ourselves. The signal used is SIGURG because gdb treats this
signal specially and forwards it to the process without any additional
configuration (as opposed to gdb's treatment of SIGUSR1 which stops the
process).


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/dcdcfb4a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/dcdcfb4a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/dcdcfb4a

Branch: refs/heads/develop
Commit: dcdcfb4a1cc4352f19d9852ab6462b6f6aed8cb2
Parents: b51a0ee
Author: Neel Natu <ne...@nahannisys.com>
Authored: Wed Apr 6 18:54:08 2016 -0700
Committer: Neel Natu <ne...@nahannisys.com>
Committed: Wed Apr 6 18:54:08 2016 -0700

----------------------------------------------------------------------
 libs/os/src/arch/sim/os_arch_sim.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/dcdcfb4a/libs/os/src/arch/sim/os_arch_sim.c
----------------------------------------------------------------------
diff --git a/libs/os/src/arch/sim/os_arch_sim.c b/libs/os/src/arch/sim/os_arch_sim.c
index 521d51a..7a3b27d 100644
--- a/libs/os/src/arch/sim/os_arch_sim.c
+++ b/libs/os/src/arch/sim/os_arch_sim.c
@@ -53,6 +53,7 @@ extern void os_arch_frame_init(struct stack_frame *sf);
 
 #define OS_USEC_PER_TICK    (1000000 / OS_TICKS_PER_SEC)
 
+static pid_t mypid;
 static sigset_t allsigs, nosigs;
 static void timer_handler(int sig);
 
@@ -96,14 +97,32 @@ os_arch_task_stack_init(struct os_task *t, os_stack_t *stack_top, int size)
 }
 
 void
-os_arch_ctx_sw(struct os_task *next_t)  
+os_arch_ctx_sw(struct os_task *next_t)
 {
-    struct os_task *t;
+    /*
+     * gdb will stop execution of the program on most signals (e.g. SIGUSR1)
+     * whereas it passes SIGURG to the process without any special settings.
+     */
+    kill(mypid, SIGURG);
+}
+
+static void
+ctxsw_handler(int sig)
+{
+    struct os_task *t, *next_t;
     struct stack_frame *sf; 
     int rc;
 
     OS_ASSERT_CRITICAL();
     t = os_sched_get_current_task();
+    next_t = os_sched_next_task();
+    if (t == next_t) {
+        /*
+         * Context switch not needed - just return.
+         */
+        return;
+    }
+
     if (t) {
         sf = (struct stack_frame *) t->t_stackptr;
 
@@ -223,6 +242,7 @@ static struct {
     void (*handler)(int sig);
 } signals[] = {
     { SIGALRM, timer_handler },
+    { SIGURG, ctxsw_handler },
 };
 
 #define NUMSIGS     (sizeof(signals)/sizeof(signals[0]))
@@ -332,6 +352,7 @@ stop_timer(void)
 os_error_t 
 os_arch_os_init(void)
 {
+    mypid = getpid();
     g_current_task = NULL;
 
     TAILQ_INIT(&g_os_task_list);