From fee92f1202e3bb100db298c735dade5c464df9ce Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Wed, 8 Jan 2014 13:15:52 -0800 Subject: [PATCH] hook_call_deferred() works before tasks have started State machines implemented using deferred functions need to be able to kick off deferred function from a HOOK_INIT handler. But tasks aren't running in HOOK_INIT, so task_wake() fails. Instead, hook_call_deferred() should check to see if the hook task has had a chance to run yet. If it hasn't, then there's no need to wake it; it'll get run eventually anyway. BUG=chrome-os-partner:24892 BRANCH=rambi TEST=Add a call to hook_call_deferred() in a HOOK_INIT handler. It shouldn't crash, and the deferred function should be called. Change-Id: I5c8077b636ae030a668a211fd8238549b6bcfa54 Signed-off-by: Randall Spangler Reviewed-on: https://chromium-review.googlesource.com/181953 Reviewed-by: Yung-chieh Lo --- common/hooks.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/common/hooks.c b/common/hooks.c index 492ccd98b4..3d6ccb695f 100644 --- a/common/hooks.c +++ b/common/hooks.c @@ -52,6 +52,7 @@ static const struct hook_ptrs hook_list[] = { /* Times for deferrable functions */ static uint64_t defer_until[DEFERRABLE_MAX_COUNT]; static int defer_new_call; +static int hook_task_started; #ifdef CONFIG_HOOK_DEBUG /* Stats for hooks */ @@ -161,8 +162,10 @@ int hook_call_deferred(void (*routine)(void), int us) * loop one more time before sleeping. */ defer_new_call = 1; + /* Wake task so it can re-sleep for the proper time */ - task_wake(TASK_ID_HOOKS); + if (hook_task_started) + task_wake(TASK_ID_HOOKS); } return EC_SUCCESS; @@ -174,6 +177,8 @@ void hook_task(void) static uint64_t last_second = -SECOND; static uint64_t last_tick = -HOOK_TICK_INTERVAL; + hook_task_started = 1; + while (1) { uint64_t t = get_time().val; int next = 0;