diff options
author | Vic Yang <victoryang@chromium.org> | 2013-09-02 13:01:04 +0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2013-09-04 20:32:55 +0000 |
commit | 74b6f7687293b27b276d7bc2a5c0aea9b29a6649 (patch) | |
tree | 27bf836ff4b5737daa982881c34133a645da0544 | |
parent | 844f4127e8de9c061b980f458d0d0f80b8083e6a (diff) | |
download | chrome-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>
-rw-r--r-- | core/host/task.c | 36 | ||||
-rw-r--r-- | test/build.mk | 3 |
2 files changed, 34 insertions, 5 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); diff --git a/test/build.mk b/test/build.mk index 72c2982505..470e74dc75 100644 --- a/test/build.mk +++ b/test/build.mk @@ -39,7 +39,6 @@ flash-y=flash.o hooks-y=hooks.o host_command-y=host_command.o kb_8042-y=kb_8042.o -kb_8042-scale=3 kb_mkbp-y=kb_mkbp.o kb_scan-y=kb_scan.o lid_sw-y=lid_sw.o @@ -48,12 +47,10 @@ pingpong-y=pingpong.o power_button-y=power_button.o powerdemo-y=powerdemo.o queue-y=queue.o -sbs_charging-scale=20 sbs_charging-y=sbs_charging.o stress-y=stress.o system-y=system.o thermal-y=thermal.o -thermal-scale=200 timer_calib-y=timer_calib.o timer_dos-y=timer_dos.o utils-y=utils.o |