From 8099c2b9fd5b80f35868936a6e96f732106c3286 Mon Sep 17 00:00:00 2001 From: Jeremy White Date: Tue, 2 Nov 2004 19:32:03 +0000 Subject: [PATCH] Tune the behavior of Sleep() and Waitxxx() to more closely resemble Windows behavior. The key is to yield in a Sleep and in any Wait that times out. --- dlls/ntdll/sync.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 1a7cc9591d5..6b4fe325ffe 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -586,6 +586,12 @@ NTSTATUS NTDLL_wait_for_multiple_objects( UINT count, const HANDLE *handles, UIN call_apcs( (flags & SELECT_ALERTABLE) != 0 ); if (flags & SELECT_ALERTABLE) break; } + + /* A test on Windows 2000 shows that Windows always yields during + a wait, but a wait that is hit by an event gets a priority + boost as well. This seems to model that behavior the closest. */ + if (ret == WAIT_TIMEOUT) NtYieldExecution(); + return ret; } @@ -649,15 +655,15 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou { for (;;) select( 0, NULL, NULL, NULL, NULL ); } - else if (!timeout->QuadPart) - { - NtYieldExecution(); - } else { abs_time_t when; NTDLL_get_server_timeout( &when, timeout ); + + /* Note that we yield after establishing the desired timeout */ + NtYieldExecution(); + for (;;) { struct timeval tv; @@ -668,7 +674,9 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou tv.tv_usec += 1000000; tv.tv_sec--; } - if (tv.tv_sec < 0) tv.tv_sec = tv.tv_usec = 0; + /* if our yield already passed enough time, we're done */ + if (tv.tv_sec < 0) break; + if (select( 0, NULL, NULL, NULL, &tv ) != -1) break; } }