ntdll: make NtDelayExecution a bit more efficient
Graham
graham.knap at gmail.com
Tue Mar 5 19:56:02 CST 2013
Hi folks,
This is my first attempt at submitting a patch to Wine. If I've done
anything incorrectly, please let me know.
This patch is vaguely related to bug 24558. It eliminates a few
syscalls in NtDelayExecution:
1. If the caller requests a zero-wait yield, then do just that, and
nothing more.
2. If you're about to block on select(), then I don't see any point in
preceding that with a call to sched_yield(). I've also shuffled the
calls to NtGetSystemTime() so that it is only called once prior to the
first invocation of select().
I tested this with StarCraft II, and it appears to work as intended. I
don't expect a measurable performance gain, but the difference is
visible via "strace -c". Please let me know what you think. Thanks.
-- graham
-------------- next part --------------
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index 58dde65..d99d91d 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -1213,30 +1213,31 @@ NTSTATUS WINAPI NtDelayExecution( BOOLEAN alertable, const LARGE_INTEGER *timeou
{
for (;;) select( 0, NULL, NULL, NULL, NULL );
}
+ else if (!timeout->QuadPart)
+ {
+ NtYieldExecution();
+ }
else
{
LARGE_INTEGER now;
timeout_t when, diff;
+ NtQuerySystemTime( &now );
+
if ((when = timeout->QuadPart) < 0)
{
- NtQuerySystemTime( &now );
when = now.QuadPart - when;
}
- /* Note that we yield after establishing the desired timeout */
- NtYieldExecution();
- if (!when) return STATUS_SUCCESS;
-
for (;;)
{
struct timeval tv;
- NtQuerySystemTime( &now );
diff = (when - now.QuadPart + 9) / 10;
if (diff <= 0) break;
tv.tv_sec = diff / 1000000;
tv.tv_usec = diff % 1000000;
if (select( 0, NULL, NULL, NULL, &tv ) != -1) break;
+ NtQuerySystemTime( &now );
}
}
return STATUS_SUCCESS;
More information about the wine-patches
mailing list