This will only affect users running with HZ=1000. On an i7-8700 CPU @ 3.20GHz it cuts the call cost from ~30ns to ~12ns.
Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/ntdll/time.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c index d0a7954377..37401ce2e1 100644 --- a/dlls/ntdll/time.c +++ b/dlls/ntdll/time.c @@ -458,19 +458,43 @@ void WINAPI RtlTimeToElapsedTimeFields( const LARGE_INTEGER *Time, PTIME_FIELDS * Get the current system time. * * PARAMS - * Time [O] Destination for the current system time. + * time [O] Destination for the current system time. * * RETURNS * Success: STATUS_SUCCESS. * Failure: An NTSTATUS error code indicating the problem. */ -NTSTATUS WINAPI NtQuerySystemTime( PLARGE_INTEGER Time ) +NTSTATUS WINAPI NtQuerySystemTime( LARGE_INTEGER *time ) { - struct timeval now; +#if defined(HAVE_CLOCK_GETTIME) + struct timespec ts; + static clockid_t clock_id = -1;
- gettimeofday( &now, 0 ); - Time->QuadPart = now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; - Time->QuadPart += now.tv_usec * 10; + if (clock_id == -1) + { + struct timespec res; + + /* Use CLOCK_REALTIME_COARSE if it has 1 ms or better resolution */ + if (!clock_getres( CLOCK_REALTIME_COARSE, &res ) && res.tv_sec == 0 && res.tv_nsec <= 1000000) + clock_id = CLOCK_REALTIME_COARSE; + else + clock_id = CLOCK_REALTIME; + } + + if (!clock_gettime( clock_id, &ts )) + { + time->QuadPart = ts.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; + time->QuadPart += (ts.tv_nsec + 50) / 100; + } + else +#endif + { + struct timeval now; + + gettimeofday( &now, 0 ); + time->QuadPart = now.tv_sec * (ULONGLONG)TICKSPERSEC + TICKS_1601_TO_1970; + time->QuadPart += now.tv_usec * 10; + } return STATUS_SUCCESS; }