• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()18 LIBC_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