summaryrefslogtreecommitdiffstats
path: root/libcxx/src/chrono.cpp
diff options
context:
space:
mode:
authorMarshall Clow <mclow.lists@gmail.com>2019-04-01 17:23:30 +0000
committerMarshall Clow <mclow.lists@gmail.com>2019-04-01 17:23:30 +0000
commitecad92b0680716857d135ef40bbf595354f35867 (patch)
tree756accdff5283d2da4563ae61b6124b548745efd /libcxx/src/chrono.cpp
parent84c8baeef71efa9ab8461cfa41d9a7094cdd1bea (diff)
downloadbcm5719-llvm-ecad92b0680716857d135ef40bbf595354f35867.tar.gz
bcm5719-llvm-ecad92b0680716857d135ef40bbf595354f35867.zip
Fix PR#41323 'Race condition in steady_clock::now for _LIBCPP_WIN32API'. thanks to Ivan Afanasyev for the report.
llvm-svn: 357413
Diffstat (limited to 'libcxx/src/chrono.cpp')
-rw-r--r--libcxx/src/chrono.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/libcxx/src/chrono.cpp b/libcxx/src/chrono.cpp
index ea0a638acc5..1758e6ca2f3 100644
--- a/libcxx/src/chrono.cpp
+++ b/libcxx/src/chrono.cpp
@@ -177,16 +177,25 @@ steady_clock::now() _NOEXCEPT
#elif defined(_LIBCPP_WIN32API)
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx says:
+// 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.
+
+static LARGE_INTEGER
+__QueryPerformanceFrequency()
+{
+ LARGE_INTEGER val;
+ (void) QueryPerformanceFrequency(&val);
+ return val;
+}
+
steady_clock::time_point
steady_clock::now() _NOEXCEPT
{
- static LARGE_INTEGER freq;
- static BOOL initialized = FALSE;
- if (!initialized)
- initialized = QueryPerformanceFrequency(&freq); // always succceeds
+ static const LARGE_INTEGER freq = __QueryPerformanceFrequency();
- LARGE_INTEGER counter;
- QueryPerformanceCounter(&counter);
+ LARGE_INTEGER counter = __QueryPerformanceFrequency();
return time_point(duration(counter.QuadPart * nano::den / freq.QuadPart));
}
OpenPOWER on IntegriCloud