diff options
author | Alexandru M Stan <amstan@chromium.org> | 2015-02-06 15:47:43 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-02-12 06:44:04 +0000 |
commit | 80778ad0eb0f2a7a156f02b68eb7103687c245fb (patch) | |
tree | 4d728471e57e23e5f7ce4b9898707088a5e6e18b /include/task.h | |
parent | 39b111437ce89d2e90f9c3891922834b723b0878 (diff) | |
download | chrome-ec-80778ad0eb0f2a7a156f02b68eb7103687c245fb.tar.gz |
cortex-m0: Add deferred scheduler
If 2 interrupts happen at the same time, there is a chance that the nested
interrupt will not call svc_handler when it needs to. In extreme cases this
could lead to tasks not getting woken up when they're supposed to and watchdog
resetting.
The reason stuff worked was because there were enough other interrupts
around to eventually call the scheduler and switch to the ready task.
This change modifies the interrupt calls to not call the scheduler directly
(because in nested interrupt situation this causes problems), but defer the
call to scheduling until after the irq finishes by triggering a low priority
interrupt which will for sure call svc_host at the end. The PendSV irq was
used for this purpose.
BUG=chrome-os-partner:36193
TEST=No more SPI errors caused by scheduler problems
TEST=usleeps now are more accurate, they're guaranteed to not take forever now
BRANCH=veyron
Change-Id: I42acde6b3eb7be2540a0de9a8562dee2ea2be7ab
Signed-off-by: Alexandru M Stan <amstan@chromium.org>
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/248902
Tested-by: Alec Berg <alecaberg@chromium.org>
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Alec Berg <alecaberg@chromium.org>
Diffstat (limited to 'include/task.h')
-rw-r--r-- | include/task.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/task.h b/include/task.h index 0c71e804ba..06cef86946 100644 --- a/include/task.h +++ b/include/task.h @@ -141,6 +141,7 @@ const char *task_get_name(task_id_t tskid); * is called. */ void task_start_irq_handler(void *excep_return); +void task_end_irq_handler(void *excep_return); #else #define task_start_irq_handler(excep_return) #endif |