From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:10 +0000 (-0700) Subject: make System_GetTimeMonotonic() really monotonic X-Git-Tag: stable-10.2.0~468 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=adf3be560d65d0d910d4d4b2988aef152a797720;p=thirdparty%2Fopen-vm-tools.git make System_GetTimeMonotonic() really monotonic Solaris has an issue where times() can return a lower value than it returned earlier, making it non-monotonic. This change works around this by saving the last returned value and returning that if the times() function return a lower value. --- diff --git a/open-vm-tools/lib/system/systemLinux.c b/open-vm-tools/lib/system/systemLinux.c index 8e6f77269..293adb23e 100644 --- a/open-vm-tools/lib/system/systemLinux.c +++ b/open-vm-tools/lib/system/systemLinux.c @@ -162,9 +162,32 @@ System_GetTimeMonotonic(void) return base + (last = current); #else // VM_X86_64 - +#ifdef sun + /* Solaris has a bug where times() can return a lower value than in + * a previous call, see bug #1710952, so we make sure to never + * return a lower value, by saving the old value and compare. + * We also make that thread safe. */ + static Atomic_uint64 last = { 0 }; + + while (1) { + uint64 last1 = Atomic_Read64(&last); + uint64 now = times(&tp); + + if (now > last1) { + uint64 last2 = Atomic_ReadIfEqualWrite64(&last, last1, now); + /* check if another thread changed last, and try again if true */ + if (last2 != last1) { + continue; + } + return now; + } else { + return last1; + } + } +#else return times(&tp); #endif +#endif }