Based on a patch by Andrew Eikum.
Linux's CLOCK_MONOTONIC(_RAW) and macOS's mach_absolute_time all stop counting when the computer goes to sleep/suspend/hibernate/etc. However, Windows's GetTickCount does not stop counting. Linux's CLOCK_BOOTTIME matches Windows's behavior, as does macOS's mach_continuous_time.
BSD's CLOCK_MONOTONIC already counts asleep time.
To avoid issues with skew and performance, this patch falls back to mach_absolute_time on macOS if mach_continuous_time is unavailable. Note that mach_continuous_time was introduced in macOS 10.12, meaning that if the minimum version required is less than that, it will be linked weakly. Therefore we must check that it is nonnull before attempting to call it.
Signed-off-by: Chip Davis cdavis@codeweavers.com --- configure.ac | 1 + dlls/ntdll/time.c | 8 ++++++++ 2 files changed, 9 insertions(+)
diff --git a/configure.ac b/configure.ac index 754dbe8b36e..2a049909a65 100644 --- a/configure.ac +++ b/configure.ac @@ -2206,6 +2206,7 @@ AC_CHECK_FUNCS(\ getopt_long_only \ kqueue \ lstat \ + mach_continuous_time \ pipe2 \ poll \ port_create \ diff --git a/dlls/ntdll/time.c b/dlls/ntdll/time.c index 91e5887b879..92415d50b04 100644 --- a/dlls/ntdll/time.c +++ b/dlls/ntdll/time.c @@ -111,9 +111,17 @@ static inline ULONGLONG monotonic_counter(void) static mach_timebase_info_data_t timebase;
if (!timebase.denom) mach_timebase_info( &timebase ); +#ifdef HAVE_MACH_CONTINUOUS_TIME + if (mach_continuous_time != NULL) + return mach_continuous_time() * timebase.numer / timebase.denom / 100; +#endif return mach_absolute_time() * timebase.numer / timebase.denom / 100; #elif defined(HAVE_CLOCK_GETTIME) struct timespec ts; +#ifdef CLOCK_BOOTTIME + if (!clock_gettime( CLOCK_BOOTTIME, &ts )) + return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100; +#endif #ifdef CLOCK_MONOTONIC_RAW if (!clock_gettime( CLOCK_MONOTONIC_RAW, &ts )) return ts.tv_sec * (ULONGLONG)TICKSPERSEC + ts.tv_nsec / 100;
On Sun, Nov 24, 2019 at 07:39:58PM -0600, Chip Davis wrote:
Based on a patch by Andrew Eikum.
Linux's CLOCK_MONOTONIC(_RAW) and macOS's mach_absolute_time all stop counting when the computer goes to sleep/suspend/hibernate/etc. However, Windows's GetTickCount does not stop counting. Linux's CLOCK_BOOTTIME matches Windows's behavior, as does macOS's mach_continuous_time.
However, CLOCK_BOOTTIME is changed by adjtime(3) which GetTickCount() shouldn't be. I guess what we really want is a CLOCK_BOOTTIME_RAW...
Huw.
November 25, 2019 2:54 AM, "Huw Davies" huw@codeweavers.com wrote:
On Sun, Nov 24, 2019 at 07:39:58PM -0600, Chip Davis wrote:
Based on a patch by Andrew Eikum.
Linux's CLOCK_MONOTONIC(_RAW) and macOS's mach_absolute_time all stop counting when the computer goes to sleep/suspend/hibernate/etc. However, Windows's GetTickCount does not stop counting. Linux's CLOCK_BOOTTIME matches Windows's behavior, as does macOS's mach_continuous_time.
However, CLOCK_BOOTTIME is changed by adjtime(3) which GetTickCount() shouldn't be. I guess what we really want is a CLOCK_BOOTTIME_RAW...
So there's currently no clock on Linux that does exactly what we want? That's just grand...
Chip