Files
OpenCellular/core/host/timer.c
Vic Yang 7bbf6d7bb3 Slow down time when running unit tests
When a timing sensitive test run on a heavily loaded system, sometimes a
task runs for longer than it usually does and causes the test to fail.
All the timing requirements in the unit tests are trying to verify the
various delays in our codebase, and mostly we don't care about the time
taken by active running code (as they are very quick.) To improve the
stability of tests, let's slow down the time. To a test, it's as if the
code runs faster. If a test uses udelay() and exceeds the 10-second time
limit, we can make that single test faster by setting the time scale.

BUG=None
TEST=Repeatedly run 'make runtests'
BRANCH=None

Change-Id: I9bc5c77e0d34d04c8630d495387a751ef29c7bd5
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/220717
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
2014-10-04 21:08:38 +00:00

108 lines
2.2 KiB
C

/* Copyright (c) 2013 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.
*/
/* Timer module */
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include "task.h"
#include "test_util.h"
#include "timer.h"
#include "util.h"
/*
* For test that need to test for longer than the default time limit,
* adjust its time scale in test/build.mk by specifying
* <test_name>-scale=<new scale>.
*/
#ifndef TEST_TIME_SCALE
#define TEST_TIME_SCALE 1
#endif
/*
* To increase the stability of timing sensitive unit tests, slow
* down the time by 10x. This only affects active run time (including
* udelay() calls). To an unit test, the only effect is increased code
* execution speed. However, this comes at the cost of prolonged test
* run time for tests that use udelay(). Fortunately, most of our tests
* use usleep/msleep, and for tests that use udelay(), we can scale
* the time as mentioned above.
*/
#define TEST_TIME_SLOW_DOWN 10
static timestamp_t boot_time;
static int time_set;
void usleep(unsigned us)
{
if (!task_start_called()) {
udelay(us);
return;
}
ASSERT(!in_interrupt_context() &&
task_get_current() != TASK_ID_INT_GEN);
task_wait_event(us);
}
timestamp_t _get_time(void)
{
struct timespec ts;
timestamp_t ret;
clock_gettime(CLOCK_MONOTONIC, &ts);
ret.val = (1000000000 * (uint64_t)ts.tv_sec + ts.tv_nsec) *
TEST_TIME_SCALE / 1000 / TEST_TIME_SLOW_DOWN;
return ret;
}
timestamp_t get_time(void)
{
timestamp_t ret = _get_time();
ret.val -= boot_time.val;
return ret;
}
void force_time(timestamp_t ts)
{
timestamp_t now = _get_time();
boot_time.val = now.val - ts.val;
time_set = 1;
}
void udelay(unsigned us)
{
timestamp_t deadline;
if (!in_interrupt_context() && task_get_current() == TASK_ID_INT_GEN) {
interrupt_generator_udelay(us);
return;
}
deadline.val = get_time().val + us;
while (get_time().val < deadline.val)
;
}
int timestamp_expired(timestamp_t deadline, const timestamp_t *now)
{
timestamp_t now_val;
if (!now) {
now_val = get_time();
now = &now_val;
}
return ((int64_t)(now->val - deadline.val) >= 0);
}
void timer_init(void)
{
if (!time_set)
boot_time = _get_time();
}