summaryrefslogtreecommitdiff
path: root/core/host
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-09-02 13:01:04 +0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-09-04 20:32:55 +0000
commit74b6f7687293b27b276d7bc2a5c0aea9b29a6649 (patch)
tree27bf836ff4b5737daa982881c34133a645da0544 /core/host
parent844f4127e8de9c061b980f458d0d0f80b8083e6a (diff)
downloadchrome-ec-74b6f7687293b27b276d7bc2a5c0aea9b29a6649.tar.gz
Implement emulator clock fast-forwarding
When running an unit test, the emulator is sitting in idle task for most of the time. Since we don't have interrupt support now, the emulator is just waiting for the next wake-up timer to fire. To save time, we can actually just figure out which task is the next to wake up, and then fast-forward the system clock to that time. With this, all tests run faster and we can remove time-scaling for all current tests. This improves not only run time but also stability. If one day we have interrupt support, then we will have to modify this to take into account the fact that an interrupt might wake a task before any wake-up timer fires. BUG=chrome-os-partner:19235 TEST=Run all tests in parallel for 1000 times. BRANCH=None Change-Id: I4cd33b041230267c110af015d425dd78d124f963 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/167801 Reviewed-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'core/host')
-rw-r--r--core/host/task.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/core/host/task.c b/core/host/task.c
index 7c9e0622fb..e945b603a8 100644
--- a/core/host/task.c
+++ b/core/host/task.c
@@ -148,6 +148,23 @@ task_id_t task_get_current(void)
return my_task_id;
}
+static task_id_t task_get_next_wake(void)
+{
+ int i;
+ timestamp_t min_time;
+ int which_task = TASK_ID_INVALID;
+
+ min_time.val = ~0ull;
+
+ for (i = TASK_ID_COUNT - 1; i >= 0; --i)
+ if (min_time.val >= tasks[i].wake_time.val) {
+ min_time.val = tasks[i].wake_time.val;
+ which_task = i;
+ }
+
+ return which_task;
+}
+
void task_scheduler(void)
{
int i;
@@ -161,8 +178,23 @@ void task_scheduler(void)
break;
--i;
}
- if (i < 0)
- i = TASK_ID_IDLE;
+ if (i < 0) {
+ /*
+ * No task has event pending, and thus we are only
+ * waiting for the next wake-up timer to fire. Let's
+ * just find out which timer is the next and fast
+ * forward the system time to its deadline.
+ *
+ * Note that once we have interrupt support, we need
+ * to take into account the fact that an interrupt
+ * might set an event before the next timer fires.
+ */
+ i = task_get_next_wake();
+ if (i == TASK_ID_INVALID)
+ i = TASK_ID_IDLE;
+ else
+ force_time(tasks[i].wake_time);
+ }
tasks[i].wake_time.val = ~0ull;
pthread_cond_signal(&tasks[i].resume);