| /* Copyright 2012 The ChromiumOS Authors |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| * |
| * Tasks for timer test. |
| */ |
| |
| #include "common.h" |
| #include "console.h" |
| #include "task.h" |
| #include "test_util.h" |
| #include "timer.h" |
| #include "util.h" |
| |
| /* period between 500us and 128ms */ |
| #define PERIOD_US(num) (((num % 256) + 1) * 500) |
| |
| #define TEST_TIME (3 * SECOND) |
| |
| #define ERROR_MARGIN 5 |
| |
| static int calculate_golden(uint32_t seed) |
| { |
| int golden = 0; |
| uint32_t elapsed = 0; |
| while (1) { |
| elapsed += PERIOD_US(seed); |
| ++golden; |
| if (elapsed >= TEST_TIME) |
| return golden; |
| seed = prng(seed); |
| } |
| } |
| |
| int task_timer(void *seed) |
| { |
| uint32_t num = (uint32_t)(uintptr_t)seed; |
| int golden_cnt = calculate_golden(num); |
| task_id_t id = task_get_current(); |
| timestamp_t start; |
| int cnt = 0; |
| |
| while (1) { |
| task_wait_event(-1); |
| |
| ccprintf("\n[Timer task %d]\n", id); |
| start = get_time(); |
| |
| while (get_time().val - start.val < TEST_TIME) { |
| /* Wait for a "random" period */ |
| task_wait_event(PERIOD_US(num)); |
| ccprintf("%01d\n", id); |
| cnt++; |
| /* next pseudo random delay */ |
| num = prng(num); |
| } |
| ccprintf("Task %d: Count=%d Golden=%d\n", id, cnt, golden_cnt); |
| cnt -= golden_cnt; |
| if (cnt < 0) |
| cnt = -cnt; |
| if (cnt > ERROR_MARGIN) { |
| ccprintf("Count differs from Golden by more than %d!\n", |
| ERROR_MARGIN); |
| test_fail(); |
| } |
| } |
| |
| return EC_SUCCESS; |
| } |
| |
| void run_test(int argc, const char **argv) |
| { |
| wait_for_task_started(); |
| task_wake(TASK_ID_TMRD); |
| task_wake(TASK_ID_TMRC); |
| task_wake(TASK_ID_TMRB); |
| task_wake(TASK_ID_TMRA); |
| crec_usleep(TEST_TIME + SECOND); |
| test_pass(); |
| } |