aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/abseil-cpp/absl/base/internal/unscaledcycleclock.h
blob: cb2c4485b6418e764a930b15ee8a66f74f928423 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2017 The Abseil Authors. 
// 
// Licensed under the Apache License, Version 2.0 (the "License"); 
// you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at 
// 
//      https://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
// See the License for the specific language governing permissions and 
// limitations under the License. 
// 
// UnscaledCycleClock 
//    An UnscaledCycleClock yields the value and frequency of a cycle counter 
//    that increments at a rate that is approximately constant. 
//    This class is for internal use only, you should consider using CycleClock
//    instead.
// 
// Notes: 
// The cycle counter frequency is not necessarily the core clock frequency. 
// That is, CycleCounter cycles are not necessarily "CPU cycles". 
// 
// An arbitrary offset may have been added to the counter at power on. 
// 
// On some platforms, the rate and offset of the counter may differ 
// slightly when read from different CPUs of a multiprocessor.  Usually, 
// we try to ensure that the operating system adjusts values periodically 
// so that values agree approximately.   If you need stronger guarantees, 
// consider using alternate interfaces. 
// 
// The CPU is not required to maintain the ordering of a cycle counter read 
// with respect to surrounding instructions. 
 
#ifndef ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ 
#define ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ 
 
#include <cstdint> 
 
#if defined(__APPLE__) 
#include <TargetConditionals.h> 
#endif 
 
#include "absl/base/port.h" 
 
// The following platforms have an implementation of a hardware counter. 
#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \ 
    defined(__powerpc__) || defined(__ppc__) || defined(__riscv) ||     \
    defined(_M_IX86) || defined(_M_X64)
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1 
#else 
#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0 
#endif 
 
// The following platforms often disable access to the hardware 
// counter (through a sandbox) even if the underlying hardware has a 
// usable counter. The CycleTimer interface also requires a *scaled* 
// CycleClock that runs at atleast 1 MHz. We've found some Android 
// ARM64 devices where this is not the case, so we disable it by 
// default on Android ARM64. 
#if defined(__native_client__) ||                      \ 
    (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \ 
    (defined(__ANDROID__) && defined(__aarch64__)) 
#define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 0 
#else 
#define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 1 
#endif 
 
// UnscaledCycleClock is an optional internal feature. 
// Use "#if ABSL_USE_UNSCALED_CYCLECLOCK" to test for its presence. 
// Can be overridden at compile-time via -DABSL_USE_UNSCALED_CYCLECLOCK=0|1 
#if !defined(ABSL_USE_UNSCALED_CYCLECLOCK) 
#define ABSL_USE_UNSCALED_CYCLECLOCK               \ 
  (ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION && \ 
   ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT) 
#endif 
 
#if ABSL_USE_UNSCALED_CYCLECLOCK 
 
// This macro can be used to test if UnscaledCycleClock::Frequency() 
// is NominalCPUFrequency() on a particular platform. 
#if (defined(__i386__) || defined(__x86_64__) || defined(__riscv) || \
     defined(_M_IX86) || defined(_M_X64))
#define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY 
#endif 
 
namespace absl { 
ABSL_NAMESPACE_BEGIN
namespace time_internal { 
class UnscaledCycleClockWrapperForGetCurrentTime; 
}  // namespace time_internal 
 
namespace base_internal { 
class CycleClock; 
class UnscaledCycleClockWrapperForInitializeFrequency; 
 
class UnscaledCycleClock { 
 private: 
  UnscaledCycleClock() = delete; 
 
  // Return the value of a cycle counter that counts at a rate that is 
  // approximately constant. 
  static int64_t Now(); 
 
  // Return the how much UnscaledCycleClock::Now() increases per second. 
  // This is not necessarily the core CPU clock frequency. 
  // It may be the nominal value report by the kernel, rather than a measured 
  // value. 
  static double Frequency(); 
 
  // Allowed users
  friend class base_internal::CycleClock; 
  friend class time_internal::UnscaledCycleClockWrapperForGetCurrentTime; 
  friend class base_internal::UnscaledCycleClockWrapperForInitializeFrequency; 
}; 
 
}  // namespace base_internal 
ABSL_NAMESPACE_END
}  // namespace absl 
 
#endif  // ABSL_USE_UNSCALED_CYCLECLOCK 
 
#endif  // ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_