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.