Attempt to correct buggy win32 timer code (causing tinderbox failures).

This commit is contained in:
Graydon Hoare 2011-07-13 12:25:36 -07:00
parent ece2d27205
commit 01fc165517
7 changed files with 42 additions and 36 deletions

View File

@ -673,7 +673,7 @@ get_time(rust_task *task, uint32_t *sec, uint32_t *usec) {
extern "C" CDECL void
nano_time(rust_task *task, uint64_t *ns) {
timer t;
*ns = t.nano_time();
*ns = t.time_ns();
}
/**

View File

@ -148,10 +148,11 @@ rust_scheduler::log_state() {
if (!running_tasks.is_empty()) {
log(NULL, log_note, "running tasks:");
for (size_t i = 0; i < running_tasks.length(); i++) {
log(NULL, log_note, "\t task: %s @0x%" PRIxPTR " timeout: %d",
log(NULL, log_note, "\t task: %s @0x%" PRIxPTR
" remaining: %" PRId64 " us",
running_tasks[i]->name,
running_tasks[i],
running_tasks[i]->yield_timer.get_timeout());
running_tasks[i]->yield_timer.remaining_us());
}
}

View File

@ -162,7 +162,7 @@ rust_task::start(uintptr_t spawnee_fn,
ctx.call((void *)task_start_wrapper, a, sp);
yield_timer.reset(0);
yield_timer.reset_us(0);
transition(&sched->newborn_tasks, &sched->running_tasks);
}
@ -188,7 +188,7 @@ rust_task::yield(size_t nargs, size_t time_in_us) {
// FIXME: what is nargs for, and is it safe to ignore?
yield_timer.reset(time_in_us);
yield_timer.reset_us(time_in_us);
// Return to the scheduler.
ctx.next->swap(ctx);

View File

@ -170,8 +170,8 @@ upcall_yield(rust_task *task) {
extern "C" CDECL void
upcall_sleep(rust_task *task, size_t time_in_us) {
LOG_UPCALL_ENTRY(task);
LOG(task, task, "elapsed %d",
task->yield_timer.get_elapsed_time());
LOG(task, task, "elapsed %" PRIu64 " us",
task->yield_timer.elapsed_us());
LOG(task, task, "sleep %d us", time_in_us);
task->yield(2, time_in_us);
}

View File

@ -5,43 +5,48 @@
#include <mach/mach_time.h>
#endif
uint64_t ns_per_s = 1000000000LL;
timer::timer() {
#if __WIN32__
uint64_t ticks_per_second;
QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second);
_ticks_per_ns = ticks_per_second / 1000;
_ticks_per_s = 0LL;
// FIXME: assert this works or have a workaround.
QueryPerformanceFrequency((LARGE_INTEGER *)&_ticks_per_s);
if (_ticks_per_s == 0LL) {
_ticks_per_s = 1LL;
}
#endif
reset(0);
reset_us(0);
}
void
timer::reset(uint64_t timeout) {
_start = get_time();
_timeout = timeout;
timer::reset_us(uint64_t timeout_us) {
_start_us = time_us();
_timeout_us = timeout_us;
}
uint64_t
timer::get_elapsed_time() {
return get_time() - _start;
timer::elapsed_us() {
return time_us() - _start_us;
}
double
timer::get_elapsed_time_in_ms() {
return (double) get_elapsed_time() / 1000.0;
timer::elapsed_ms() {
return (double) elapsed_us() / 1000.0;
}
int64_t
timer::get_timeout() {
return _timeout - get_elapsed_time();
timer::remaining_us() {
return _timeout_us - elapsed_us();
}
bool
timer::has_timed_out() {
return get_timeout() <= 0;
return remaining_us() <= 0;
}
uint64_t
timer::nano_time() {
timer::time_ns() {
#ifdef __APPLE__
uint64_t time = mach_absolute_time();
mach_timebase_info_data_t info = {0, 0};
@ -53,17 +58,17 @@ timer::nano_time() {
#elif __WIN32__
uint64_t ticks;
QueryPerformanceCounter((LARGE_INTEGER *)&ticks);
return ticks / _ticks_per_ns;
return ((ticks * ns_per_s) / _ticks_per_s);
#else
timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (ts.tv_sec * 1000000000LL + ts.tv_nsec);
return (ts.tv_sec * ns_per_s + ts.tv_nsec);
#endif
}
uint64_t
timer::get_time() {
return nano_time() / 1000;
timer::time_us() {
return time_ns() / 1000;
}
timer::~timer() {

View File

@ -7,20 +7,20 @@
class timer {
private:
uint64_t _start;
uint64_t _timeout;
uint64_t get_time();
uint64_t _start_us;
uint64_t _timeout_us;
uint64_t time_us();
#if __WIN32__
uint64_t _ticks_per_ns;
uint64_t _ticks_per_s;
#endif
public:
timer();
void reset(uint64_t timeout);
uint64_t get_elapsed_time();
double get_elapsed_time_in_ms();
int64_t get_timeout();
void reset_us(uint64_t timeout);
uint64_t elapsed_us();
double elapsed_ms();
int64_t remaining_us();
bool has_timed_out();
uint64_t nano_time();
uint64_t time_ns();
virtual ~timer();
};

View File

@ -30,7 +30,7 @@ rust_test_suite::run() {
timer timer;
bool result = tests[i]->run();
printf("test: %s %s %.2f ms\n", test->name(),
result ? "PASSED" : "FAILE", timer.get_elapsed_time_in_ms());
result ? "PASS" : "FAIL", timer.elapsed_ms());
if (result == false) {
pass = false;
}