1 //===--- Cached Performance Counter Frequency ----------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/__support/CPP/atomic.h" 10 #include "src/__support/common.h" 11 12 #define WIN32_LEAN_AND_MEAN 13 #define NOMINMAX 14 #include <Windows.h> 15 16 namespace LIBC_NAMESPACE_DECL { 17 namespace performance_counter { get_ticks_per_second()18LIBC_INLINE long long get_ticks_per_second() { 19 static cpp::Atomic<long long> frequency = 0; 20 // Relaxed ordering is enough. It is okay to record the frequency multiple 21 // times. The store operation itself is atomic and the value must propagate 22 // as required by cache coherence. 23 auto freq = frequency.load(cpp::MemoryOrder::RELAXED); 24 if (!freq) { 25 [[clang::uninitialized]] LARGE_INTEGER buffer; 26 // On systems that run Windows XP or later, the function will always 27 // succeed and will thus never return zero. 28 ::QueryPerformanceFrequency(&buffer); 29 frequency.store(buffer.QuadPart, cpp::MemoryOrder::RELAXED); 30 return buffer.QuadPart; 31 } 32 return freq; 33 } 34 } // namespace performance_counter 35 } // namespace LIBC_NAMESPACE_DECL 36