You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/03/15 01:36:35 UTC

[28/42] incubator-mynewt-core git commit: Use the presence of SIGALRM in the signal mask to detect whether the task is inside a critical section. Previously this was done by comparing the entire 'omask' with 'allsigs'. This was dubious for a couple of re

Use the presence of SIGALRM in the signal mask to detect whether the task
is inside a critical section. Previously this was done by comparing the
entire 'omask' with 'allsigs'. This was dubious for a couple of reasons:
- the compiler is free to add pad bytes between structure members and
  not initialize them.
- the OS is required to initialize only those signals that are actually
  implemented.

Since we enable/disable all signals in 'allsigs' simultaneously, testing
the presence of any one signal is sufficient to test all of them.

Set the SA_RESTART flag when registering a signal handler otherwise a
'write()' to the uart can fail with errno set to EINTR causing the
'uart_poller' task to assert.

Initialize signals in 'os_arch_os_init()' so critical sections start
functioning before they are used during task initialization.


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/a92a45eb
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/a92a45eb
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/a92a45eb

Branch: refs/heads/master
Commit: a92a45eb5862a5b077e37c23a29a203a7c434cca
Parents: 66bad70
Author: Neel Natu <ne...@nahannisys.com>
Authored: Thu Mar 10 22:55:36 2016 -0800
Committer: Christopher Collins <cc...@gmail.com>
Committed: Fri Mar 11 12:16:13 2016 -0800

----------------------------------------------------------------------
 libs/os/src/arch/sim/os_arch_sim.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/a92a45eb/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 a0a06d9..1daa94a 100644
--- a/libs/os/src/arch/sim/os_arch_sim.c
+++ b/libs/os/src/arch/sim/os_arch_sim.c
@@ -138,7 +138,11 @@ os_arch_save_sr(void)
     error = sigprocmask(SIG_BLOCK, &allsigs, &omask);
     assert(error == 0);
 
-    return (omask == allsigs);
+    /*
+     * If any one of the signals in 'allsigs' is present in 'omask' then
+     * we are already inside a critical section.
+     */
+    return (sigismember(&omask, SIGALRM));
 }
 
 void
@@ -167,7 +171,11 @@ os_arch_in_critical(void)
     error = sigprocmask(SIG_SETMASK, NULL, &omask);
     assert(error == 0);
 
-    return (omask == allsigs);
+    /*
+     * If any one of the signals in 'allsigs' is present in 'omask' then
+     * we are already inside a critical section.
+     */
+    return (sigismember(&omask, SIGALRM));
 }
 
 void
@@ -205,9 +213,17 @@ signals_init(void)
         memset(&sa, 0, sizeof sa);
         sa.sa_handler = signals[i].handler;
         sa.sa_mask = allsigs;
+        sa.sa_flags = SA_RESTART;
         error = sigaction(signals[i].num, &sa, NULL);
         assert(error == 0);
     }
+
+    /*
+     * We use SIGALRM as a proxy for 'allsigs' to check if we are inside
+     * a critical section (for e.g. see os_arch_in_critical()). Make sure
+     * that SIGALRM is indeed present in 'allsigs'.
+     */
+    assert(sigismember(&allsigs, SIGALRM));
 }
 
 static void
@@ -297,6 +313,14 @@ os_arch_os_init(void)
     TAILQ_INIT(&g_os_run_list);
     TAILQ_INIT(&g_os_sleep_list);
 
+    /*
+     * Setup all interrupt handlers.
+     *
+     * This must be done early because task initialization uses critical
+     * sections which function correctly only when 'allsigs' is initialized.
+     */
+    signals_init();
+
     os_init_idle_task();
     os_sanity_task_init(1);
 
@@ -312,9 +336,6 @@ os_arch_os_start(void)
     struct os_task *t;
     os_sr_t sr;
 
-    /* Setup all interrupt handlers */
-    signals_init();
-
     /*
      * Disable interrupts before enabling any interrupt sources. Pending
      * interrupts will be recognized when the first task starts executing.