From: Marc-Aurel Zent <mzent@codeweavers.com> --- server/fd.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/server/fd.c b/server/fd.c index f70bec354a3..0dbefc7cfc6 100644 --- a/server/fd.c +++ b/server/fd.c @@ -36,6 +36,9 @@ #ifdef HAVE_LINUX_MAJOR_H #include <linux/major.h> #endif +#ifdef __APPLE__ +#include <mach/mach_time.h> +#endif #ifdef HAVE_SYS_STATVFS_H #include <sys/statvfs.h> #endif @@ -377,11 +380,44 @@ static void atomic_store_long(volatile LONG *ptr, LONG value) #endif } +static void atomic_store_ulonglong(volatile ULONGLONG *ptr, ULONGLONG value) +{ +#if defined(__i386__) || defined(__x86_64__) + *ptr = value; +#else + __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST); +#endif +} + +static timeout_t calculate_suspend_bias( timeout_t last_bias ) +{ + timeout_t counter = 0; + timeout_t unbiased_counter = 0; +#ifdef __APPLE__ + static mach_timebase_info_data_t timebase; + + if (!timebase.denom) mach_timebase_info( &timebase ); + unbiased_counter = mach_absolute_time() * timebase.numer / timebase.denom / 100; + counter = mach_continuous_time() * timebase.numer / timebase.denom / 100; +#elif defined(HAVE_CLOCK_GETTIME) + struct timespec ts; + if (!clock_gettime( CLOCK_MONOTONIC, &ts )) + counter = unbiased_counter = (timeout_t)ts.tv_sec * TICKS_PER_SEC + ts.tv_nsec / 100; +#ifdef CLOCK_BOOTTIME + if (!clock_gettime( CLOCK_BOOTTIME, &ts )) + counter = (timeout_t)ts.tv_sec * TICKS_PER_SEC + ts.tv_nsec / 100; +#endif +#endif + if (unbiased_counter) + return max( counter - unbiased_counter, last_bias ); + return last_bias; +} + static void set_user_shared_data_time(void) { timeout_t tick_count = monotonic_time / 10000; static timeout_t last_timezone_update; - timeout_t timezone_bias; + timeout_t timezone_bias, suspend_bias; struct tm *tm; time_t now; @@ -393,10 +429,12 @@ static void set_user_shared_data_time(void) tm = localtime( &now ); if (tm->tm_isdst) timezone_bias -= 3600; timezone_bias *= TICKS_PER_SEC; + suspend_bias = calculate_suspend_bias( user_shared_data->InterruptTimeBias ); atomic_store_long(&user_shared_data->TimeZoneBias.High2Time, timezone_bias >> 32); atomic_store_ulong(&user_shared_data->TimeZoneBias.LowPart, timezone_bias); atomic_store_long(&user_shared_data->TimeZoneBias.High1Time, timezone_bias >> 32); + atomic_store_ulonglong(&user_shared_data->InterruptTimeBias, suspend_bias); last_timezone_update = monotonic_time; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9875