/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. * 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(void) { wait_for_task_started(); task_wake(TASK_ID_TMRD); task_wake(TASK_ID_TMRC); task_wake(TASK_ID_TMRB); task_wake(TASK_ID_TMRA); usleep(TEST_TIME + SECOND); test_pass(); }