[libcxx-commits] [PATCH] D69314: Bug fix for PR#43703

Marshall Clow via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Tue Oct 22 11:07:44 PDT 2019


mclow.lists created this revision.
mclow.lists added reviewers: EricWF, ldionne.
Herald added subscribers: dexonsmith, christof.

https://PR43703 - `std::steady_clock::now()` frequently overflows on Windows

I'm putting this up for review because I'm not seeing an easy way to test this - and because I don't have a windows box handy.


Repository:
  rCXX libc++

https://reviews.llvm.org/D69314

Files:
  libcxx/src/chrono.cpp


Index: libcxx/src/chrono.cpp
===================================================================
--- libcxx/src/chrono.cpp
+++ libcxx/src/chrono.cpp
@@ -185,23 +185,36 @@
 //    If the function fails, the return value is zero. <snip>
 //    On systems that run Windows XP or later, the function will always succeed 
 //      and will thus never return zero.
+//  The same comment is made for QueryPerformanceCounter at
+//    https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
 
 static LARGE_INTEGER
 __QueryPerformanceFrequency()
 {
-	LARGE_INTEGER val;
-	(void) QueryPerformanceFrequency(&val);
-	return val;
+    LARGE_INTEGER val;
+    (void) QueryPerformanceFrequency(&val);
+    return val;
+}
+
+static LARGE_INTEGER
+__QueryPerformanceCounter()
+{
+    LARGE_INTEGER val;
+    (void) QueryPerformanceCounter(&val);
+    return val;
 }
 
 steady_clock::time_point
 steady_clock::now() _NOEXCEPT
 {
-  static const LARGE_INTEGER freq = __QueryPerformanceFrequency();
+    static const LARGE_INTEGER freq    = __QueryPerformanceFrequency();
+           const LARGE_INTEGER counter = __QueryPerformanceCounter();
+
+//  Do the multiplication in two parts to prevent overflow (See PR#43703)
+    const LONGLONG part1 = (counter.QuadPart / freq.QuadPart) * nano::den;
+    const LONGLONG part2 = (counter.QuadPart % freq.QuadPart) * nano::den / freq.QuadPart;
 
-  LARGE_INTEGER counter;
-  (void) QueryPerformanceCounter(&counter);
-  return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart));
+    return time_point(duration(part1 + part2));
 }
 
 #elif defined(CLOCK_MONOTONIC)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D69314.226060.patch
Type: text/x-patch
Size: 1649 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20191022/d8f4a28c/attachment.bin>


More information about the libcxx-commits mailing list