summaryrefslogtreecommitdiff
path: root/core/host
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2015-07-01 09:31:26 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-07-13 18:43:56 +0000
commitfbc84dc56566f31d897b420232088ba341810ea2 (patch)
treee3e9bf5cf66e28ceb55d3ff27a845d2553a80735 /core/host
parent41b538d4c6df5311fbf76495c187a4781938ae49 (diff)
downloadchrome-ec-fbc84dc56566f31d897b420232088ba341810ea2.tar.gz
hooks: Move HOOK_INIT to after task switching.
This commit changes the way in which tasks are started. Instead of having all tasks marked as ready to run upon initialization, only the hooks task is marked as ready to run. HOOK_INITs are now run at the beginning of the hooks task. After the HOOK_INITs, the hooks task calls back to enable the rest of the tasks, reschedules, and proceeds as usual. This also allows the removal of checks for task_start_called(). BUG=chrome-os-partner:27226 BRANCH=None TEST=Built and flash EC image for samus and verified that EC boot was successful as well as AP boot. Additionally, verified that charging, keyboard, tap-for-battery were all still functional. TEST=make -j buildall tests Change-Id: Iea53670222c803c2985e9c86c96974386888a4fe Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/283657 Reviewed-by: Alec Berg <alecaberg@chromium.org> Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Commit-Queue: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'core/host')
-rw-r--r--core/host/main.c1
-rw-r--r--core/host/task.c81
2 files changed, 66 insertions, 16 deletions
diff --git a/core/host/main.c b/core/host/main.c
index 80c2f33bf5..fbb28d9127 100644
--- a/core/host/main.c
+++ b/core/host/main.c
@@ -45,7 +45,6 @@ int main(int argc, char **argv)
#ifdef HAS_TASK_KEYSCAN
keyboard_scan_init();
#endif
- hook_init();
uart_init();
if (system_jumped_to_this_image()) {
diff --git a/core/host/task.c b/core/host/task.c
index 53f722e8b7..28c0cb0297 100644
--- a/core/host/task.c
+++ b/core/host/task.c
@@ -56,6 +56,8 @@ static int has_interrupt_generator = 1;
static __thread task_id_t my_task_id; /* thread local task id */
+static void task_enable_all_tasks_callback(void);
+
#define TASK(n, r, d, s) void r(void *);
CONFIG_TASK_LIST
CONFIG_TEST_TASK_LIST
@@ -331,6 +333,7 @@ static int fast_forward(void)
return TASK_ID_IDLE;
if (task_id != TASK_ID_INVALID &&
+ tasks[task_id].thread != (pthread_t)NULL &&
tasks[task_id].wake_time.val < generator_sleep_deadline.val) {
force_time(tasks[task_id].wake_time);
return task_id;
@@ -356,8 +359,15 @@ void task_scheduler(void)
now = get_time();
i = TASK_ID_COUNT - 1;
while (i >= 0) {
- if (tasks[i].event || now.val >= tasks[i].wake_time.val)
- break;
+ /*
+ * Only tasks with spawned threads are valid to be
+ * resumed.
+ */
+ if (tasks[i].thread) {
+ if (tasks[i].event ||
+ now.val >= tasks[i].wake_time.val)
+ break;
+ }
--i;
}
if (i < 0)
@@ -404,7 +414,7 @@ void *_task_int_generator_start(void *d)
int task_start(void)
{
- int i;
+ int i = TASK_ID_HOOKS;
task_register_interrupt();
@@ -414,31 +424,72 @@ int task_start(void)
pthread_mutex_lock(&run_lock);
+ /*
+ * Initialize the hooks task first. After its init, it will callback to
+ * enable the remaining tasks.
+ */
+ tasks[i].event = TASK_EVENT_WAKE;
+ tasks[i].wake_time.val = ~0ull;
+ tasks[i].started = 0;
+ pthread_cond_init(&tasks[i].resume, NULL);
+ pthread_create(&tasks[i].thread, NULL, _task_start_impl,
+ (void *)(uintptr_t)i);
+ pthread_cond_wait(&scheduler_cond, &run_lock);
+ /*
+ * Interrupt lock is grabbed by the task which just started.
+ * Let's unlock it so the next task can be started.
+ */
+ pthread_mutex_unlock(&interrupt_lock);
+
+ /*
+ * The hooks task is waiting in task_wait_event(). Lock interrupt_lock
+ * here so the first task chosen sees it locked.
+ */
+ pthread_mutex_lock(&interrupt_lock);
+
+ pthread_create(&interrupt_thread, NULL,
+ _task_int_generator_start, NULL);
+
+ /*
+ * Tell the hooks task to continue so that it can call back to enable
+ * the other tasks.
+ */
+ pthread_cond_signal(&tasks[i].resume);
+ pthread_cond_wait(&scheduler_cond, &run_lock);
+ task_enable_all_tasks_callback();
+
+ task_scheduler();
+
+ return 0;
+}
+
+static void task_enable_all_tasks_callback(void)
+{
+ int i;
+
+ /* Initialize the remaning tasks. */
for (i = 0; i < TASK_ID_COUNT; ++i) {
+ if (tasks[i].thread != (pthread_t)NULL)
+ continue;
+
tasks[i].event = TASK_EVENT_WAKE;
tasks[i].wake_time.val = ~0ull;
tasks[i].started = 0;
pthread_cond_init(&tasks[i].resume, NULL);
pthread_create(&tasks[i].thread, NULL, _task_start_impl,
(void *)(uintptr_t)i);
- pthread_cond_wait(&scheduler_cond, &run_lock);
/*
* Interrupt lock is grabbed by the task which just started.
* Let's unlock it so the next task can be started.
*/
pthread_mutex_unlock(&interrupt_lock);
+ pthread_cond_wait(&scheduler_cond, &run_lock);
}
- /*
- * All tasks are now waiting in task_wait_event(). Lock interrupt_lock
- * here so the first task chosen sees it locked.
- */
- pthread_mutex_lock(&interrupt_lock);
-
- pthread_create(&interrupt_thread, NULL,
- _task_int_generator_start, NULL);
-
- task_scheduler();
+}
- return 0;
+void task_enable_all_tasks(void)
+{
+ /* Signal to the scheduler to enable the remaining tasks. */
+ pthread_cond_signal(&scheduler_cond);
}