From cf60dfb77e5917bf5c7506597ad3275695a2a8fe Mon Sep 17 00:00:00 2001 From: Rahix Date: Sun, 19 Sep 2021 16:49:41 +0200 Subject: [PATCH] fix(lifecycle): Fix epic_sleep() calls delaying load of new app When core 1 repeatedly calls `epic_sleep()`, this could delay an epic_load() from core 0 because the reset interrupt can only be delivered after such a call completed. To work around this, add calls into `do_load()` to notify the dispatcher task that it should return early from calls like `epic_sleep()`. This gets a bit tricky because the dispatcher task also uses `ulTaskNotifyTake()` to wake up when new API calls arrive. To make sure we still break out of `epic_sleep()`, we need to call `xTaskNotifyGive()` twice in the wait loop. --- epicardium/user_core/lifecycle.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/epicardium/user_core/lifecycle.c b/epicardium/user_core/lifecycle.c index 89d4dce4..5f3caddf 100644 --- a/epicardium/user_core/lifecycle.c +++ b/epicardium/user_core/lifecycle.c @@ -109,6 +109,9 @@ static int do_load(struct load_info *info) return -EPERM; } + /* Signal the dispatcher to return early from applicable API calls. */ + xTaskNotifyGive(dispatcher_task_id); + mutex_lock(&api_mutex); if (info->do_reset) { @@ -126,9 +129,17 @@ static int do_load(struct load_info *info) * call. */ while (!core1_is_ready()) { + /* + * Wake up the dispatcher task prematurely. This is needed so + * the second xTaskNotifyGive() below can then break out the + * dispatcher from e.g. an epic_sleep() call. + */ + xTaskNotifyGive(dispatcher_task_id); mutex_unlock(&api_mutex); /* Sleep so the dispatcher task can take the lock. */ vTaskDelay(8); + /* Signal the dispatcher to return early from applicable API calls. */ + xTaskNotifyGive(dispatcher_task_id); mutex_lock(&api_mutex); } -- GitLab