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; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=51725
Your paranoid android.
=== debian9 (64 bit WoW report) ===
ntdll: pipe.c:1557: Test failed: pipe is not signaled pipe.c:1557: Test failed: pipe is not signaled
On May 2, 2019, at 3:45 AM, Huw Davies huw@codeweavers.com wrote:
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;
Having clock_gettime() doesn't necessarily imply having CLOCK_REALTIME_COARSE. It seems that baseline POSIX only requires CLOCK_REALTIME.
-Ken
On Thu, May 02, 2019 at 08:47:29AM -0500, Ken Thomases wrote:
On May 2, 2019, at 3:45 AM, Huw Davies huw@codeweavers.com wrote:
-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;
Having clock_gettime() doesn't necessarily imply having CLOCK_REALTIME_COARSE. It seems that baseline POSIX only requires CLOCK_REALTIME.
Good point, thanks!
Huw.