Windows: use low-res event loop clock.

For much better performance. Closes #88.
This commit is contained in:
Bert Belder 2011-07-19 17:32:43 +02:00
parent 86f1ca90e5
commit ca3cfbae74
3 changed files with 20 additions and 24 deletions

View File

@ -70,9 +70,6 @@ void uv_init() {
/* Initialize winsock */
uv_winsock_startup();
/* Initialize timers */
uv_timer_startup();
/* Intialize event loop */
uv_loop_init();
}

View File

@ -30,11 +30,8 @@
/*
* Timers
*/
RB_HEAD(uv_timer_tree_s, uv_timer_s);
void uv_timer_startup();
void uv_timer_endgame(uv_timer_t* handle);
DWORD uv_get_poll_timeout();

View File

@ -37,12 +37,19 @@ static char uv_hrtime_initialized_ = 0;
void uv_update_time() {
LARGE_INTEGER counter;
DWORD ticks = GetTickCount();
if (!QueryPerformanceCounter(&counter))
uv_fatal_error(GetLastError(), "QueryPerformanceCounter");
/* The assumption is made that LARGE_INTEGER.QuadPart has the same type */
/* LOOP->time, which happens to be. Is there any way to assert this? */
LARGE_INTEGER* time = (LARGE_INTEGER*) &LOOP->time;
LOOP->time = counter.QuadPart / uv_ticks_per_msec_;
/* If the timer has wrapped, add 1 to it's high-order dword. */
/* uv_poll must make sure that the timer can never overflow more than */
/* once between two subsequent uv_update_time calls. */
if (ticks < time->LowPart) {
time->HighPart += 1;
}
time->LowPart = ticks;
}
@ -88,16 +95,6 @@ uint64_t uv_hrtime(void) {
}
void uv_timer_startup() {
LARGE_INTEGER timer_frequency;
/* Initialize the event loop time */
if (!QueryPerformanceFrequency(&timer_frequency))
uv_fatal_error(GetLastError(), "QueryPerformanceFrequency");
uv_ticks_per_msec_ = timer_frequency.QuadPart / 1000;
}
static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) {
if (a->due < b->due)
return -1;
@ -222,10 +219,15 @@ DWORD uv_get_poll_timeout() {
uv_update_time();
delta = timer->due - LOOP->time;
if (delta >= UINT_MAX) {
/* Can't have a timeout greater than UINT_MAX, and a timeout value of */
/* UINT_MAX means infinite, so that's no good either. */
return UINT_MAX - 1;
if (delta >= UINT_MAX >> 1) {
/* A timeout value of UINT_MAX means infinite, so that's no good. But */
/* more importantly, there's always the risk that GetTickCount wraps. */
/* uv_update_time can detect this, but we must make sure that the */
/* tick counter never overflows twice between two subsequent */
/* uv_update_time calls. We do this by never sleeping more than half */
/* the time it takes to wrap the counter - which is huge overkill, */
/* but hey, it's not so bad to wake up every 25 days. */
return UINT_MAX >> 1;
} else if (delta < 0) {
/* Negative timeout values are not allowed */
return 0;