xref: /aosp_15_r20/external/abseil-cpp/absl/base/internal/sysinfo.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/sysinfo.h"
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #include "absl/base/attributes.h"
18*9356374aSAndroid Build Coastguard Worker 
19*9356374aSAndroid Build Coastguard Worker #ifdef _WIN32
20*9356374aSAndroid Build Coastguard Worker #include <windows.h>
21*9356374aSAndroid Build Coastguard Worker #else
22*9356374aSAndroid Build Coastguard Worker #include <fcntl.h>
23*9356374aSAndroid Build Coastguard Worker #include <pthread.h>
24*9356374aSAndroid Build Coastguard Worker #include <sys/stat.h>
25*9356374aSAndroid Build Coastguard Worker #include <sys/types.h>
26*9356374aSAndroid Build Coastguard Worker #include <unistd.h>
27*9356374aSAndroid Build Coastguard Worker #endif
28*9356374aSAndroid Build Coastguard Worker 
29*9356374aSAndroid Build Coastguard Worker #ifdef __linux__
30*9356374aSAndroid Build Coastguard Worker #include <sys/syscall.h>
31*9356374aSAndroid Build Coastguard Worker #endif
32*9356374aSAndroid Build Coastguard Worker 
33*9356374aSAndroid Build Coastguard Worker #if defined(__APPLE__) || defined(__FreeBSD__)
34*9356374aSAndroid Build Coastguard Worker #include <sys/sysctl.h>
35*9356374aSAndroid Build Coastguard Worker #endif
36*9356374aSAndroid Build Coastguard Worker 
37*9356374aSAndroid Build Coastguard Worker #ifdef __FreeBSD__
38*9356374aSAndroid Build Coastguard Worker #include <pthread_np.h>
39*9356374aSAndroid Build Coastguard Worker #endif
40*9356374aSAndroid Build Coastguard Worker 
41*9356374aSAndroid Build Coastguard Worker #ifdef __NetBSD__
42*9356374aSAndroid Build Coastguard Worker #include <lwp.h>
43*9356374aSAndroid Build Coastguard Worker #endif
44*9356374aSAndroid Build Coastguard Worker 
45*9356374aSAndroid Build Coastguard Worker #if defined(__myriad2__)
46*9356374aSAndroid Build Coastguard Worker #include <rtems.h>
47*9356374aSAndroid Build Coastguard Worker #endif
48*9356374aSAndroid Build Coastguard Worker 
49*9356374aSAndroid Build Coastguard Worker #include <string.h>
50*9356374aSAndroid Build Coastguard Worker 
51*9356374aSAndroid Build Coastguard Worker #include <cassert>
52*9356374aSAndroid Build Coastguard Worker #include <cerrno>
53*9356374aSAndroid Build Coastguard Worker #include <cstdint>
54*9356374aSAndroid Build Coastguard Worker #include <cstdio>
55*9356374aSAndroid Build Coastguard Worker #include <cstdlib>
56*9356374aSAndroid Build Coastguard Worker #include <ctime>
57*9356374aSAndroid Build Coastguard Worker #include <limits>
58*9356374aSAndroid Build Coastguard Worker #include <thread>  // NOLINT(build/c++11)
59*9356374aSAndroid Build Coastguard Worker #include <utility>
60*9356374aSAndroid Build Coastguard Worker #include <vector>
61*9356374aSAndroid Build Coastguard Worker 
62*9356374aSAndroid Build Coastguard Worker #include "absl/base/call_once.h"
63*9356374aSAndroid Build Coastguard Worker #include "absl/base/config.h"
64*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/raw_logging.h"
65*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/spinlock.h"
66*9356374aSAndroid Build Coastguard Worker #include "absl/base/internal/unscaledcycleclock.h"
67*9356374aSAndroid Build Coastguard Worker #include "absl/base/thread_annotations.h"
68*9356374aSAndroid Build Coastguard Worker 
69*9356374aSAndroid Build Coastguard Worker namespace absl {
70*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
71*9356374aSAndroid Build Coastguard Worker namespace base_internal {
72*9356374aSAndroid Build Coastguard Worker 
73*9356374aSAndroid Build Coastguard Worker namespace {
74*9356374aSAndroid Build Coastguard Worker 
75*9356374aSAndroid Build Coastguard Worker #if defined(_WIN32)
76*9356374aSAndroid Build Coastguard Worker 
77*9356374aSAndroid Build Coastguard Worker // Returns number of bits set in `bitMask`
Win32CountSetBits(ULONG_PTR bitMask)78*9356374aSAndroid Build Coastguard Worker DWORD Win32CountSetBits(ULONG_PTR bitMask) {
79*9356374aSAndroid Build Coastguard Worker   for (DWORD bitSetCount = 0; ; ++bitSetCount) {
80*9356374aSAndroid Build Coastguard Worker     if (bitMask == 0) return bitSetCount;
81*9356374aSAndroid Build Coastguard Worker     bitMask &= bitMask - 1;
82*9356374aSAndroid Build Coastguard Worker   }
83*9356374aSAndroid Build Coastguard Worker }
84*9356374aSAndroid Build Coastguard Worker 
85*9356374aSAndroid Build Coastguard Worker // Returns the number of logical CPUs using GetLogicalProcessorInformation(), or
86*9356374aSAndroid Build Coastguard Worker // 0 if the number of processors is not available or can not be computed.
87*9356374aSAndroid Build Coastguard Worker // https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation
Win32NumCPUs()88*9356374aSAndroid Build Coastguard Worker int Win32NumCPUs() {
89*9356374aSAndroid Build Coastguard Worker #pragma comment(lib, "kernel32.lib")
90*9356374aSAndroid Build Coastguard Worker   using Info = SYSTEM_LOGICAL_PROCESSOR_INFORMATION;
91*9356374aSAndroid Build Coastguard Worker 
92*9356374aSAndroid Build Coastguard Worker   DWORD info_size = sizeof(Info);
93*9356374aSAndroid Build Coastguard Worker   Info* info(static_cast<Info*>(malloc(info_size)));
94*9356374aSAndroid Build Coastguard Worker   if (info == nullptr) return 0;
95*9356374aSAndroid Build Coastguard Worker 
96*9356374aSAndroid Build Coastguard Worker   bool success = GetLogicalProcessorInformation(info, &info_size);
97*9356374aSAndroid Build Coastguard Worker   if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
98*9356374aSAndroid Build Coastguard Worker     free(info);
99*9356374aSAndroid Build Coastguard Worker     info = static_cast<Info*>(malloc(info_size));
100*9356374aSAndroid Build Coastguard Worker     if (info == nullptr) return 0;
101*9356374aSAndroid Build Coastguard Worker     success = GetLogicalProcessorInformation(info, &info_size);
102*9356374aSAndroid Build Coastguard Worker   }
103*9356374aSAndroid Build Coastguard Worker 
104*9356374aSAndroid Build Coastguard Worker   DWORD logicalProcessorCount = 0;
105*9356374aSAndroid Build Coastguard Worker   if (success) {
106*9356374aSAndroid Build Coastguard Worker     Info* ptr = info;
107*9356374aSAndroid Build Coastguard Worker     DWORD byteOffset = 0;
108*9356374aSAndroid Build Coastguard Worker     while (byteOffset + sizeof(Info) <= info_size) {
109*9356374aSAndroid Build Coastguard Worker       switch (ptr->Relationship) {
110*9356374aSAndroid Build Coastguard Worker         case RelationProcessorCore:
111*9356374aSAndroid Build Coastguard Worker           logicalProcessorCount += Win32CountSetBits(ptr->ProcessorMask);
112*9356374aSAndroid Build Coastguard Worker           break;
113*9356374aSAndroid Build Coastguard Worker 
114*9356374aSAndroid Build Coastguard Worker         case RelationNumaNode:
115*9356374aSAndroid Build Coastguard Worker         case RelationCache:
116*9356374aSAndroid Build Coastguard Worker         case RelationProcessorPackage:
117*9356374aSAndroid Build Coastguard Worker           // Ignore other entries
118*9356374aSAndroid Build Coastguard Worker           break;
119*9356374aSAndroid Build Coastguard Worker 
120*9356374aSAndroid Build Coastguard Worker         default:
121*9356374aSAndroid Build Coastguard Worker           // Ignore unknown entries
122*9356374aSAndroid Build Coastguard Worker           break;
123*9356374aSAndroid Build Coastguard Worker       }
124*9356374aSAndroid Build Coastguard Worker       byteOffset += sizeof(Info);
125*9356374aSAndroid Build Coastguard Worker       ptr++;
126*9356374aSAndroid Build Coastguard Worker     }
127*9356374aSAndroid Build Coastguard Worker   }
128*9356374aSAndroid Build Coastguard Worker   free(info);
129*9356374aSAndroid Build Coastguard Worker   return static_cast<int>(logicalProcessorCount);
130*9356374aSAndroid Build Coastguard Worker }
131*9356374aSAndroid Build Coastguard Worker 
132*9356374aSAndroid Build Coastguard Worker #endif
133*9356374aSAndroid Build Coastguard Worker 
134*9356374aSAndroid Build Coastguard Worker }  // namespace
135*9356374aSAndroid Build Coastguard Worker 
GetNumCPUs()136*9356374aSAndroid Build Coastguard Worker static int GetNumCPUs() {
137*9356374aSAndroid Build Coastguard Worker #if defined(__myriad2__)
138*9356374aSAndroid Build Coastguard Worker   return 1;
139*9356374aSAndroid Build Coastguard Worker #elif defined(_WIN32)
140*9356374aSAndroid Build Coastguard Worker   const int hardware_concurrency = Win32NumCPUs();
141*9356374aSAndroid Build Coastguard Worker   return hardware_concurrency ? hardware_concurrency : 1;
142*9356374aSAndroid Build Coastguard Worker #elif defined(_AIX)
143*9356374aSAndroid Build Coastguard Worker   return sysconf(_SC_NPROCESSORS_ONLN);
144*9356374aSAndroid Build Coastguard Worker #else
145*9356374aSAndroid Build Coastguard Worker   // Other possibilities:
146*9356374aSAndroid Build Coastguard Worker   //  - Read /sys/devices/system/cpu/online and use cpumask_parse()
147*9356374aSAndroid Build Coastguard Worker   //  - sysconf(_SC_NPROCESSORS_ONLN)
148*9356374aSAndroid Build Coastguard Worker   return static_cast<int>(std::thread::hardware_concurrency());
149*9356374aSAndroid Build Coastguard Worker #endif
150*9356374aSAndroid Build Coastguard Worker }
151*9356374aSAndroid Build Coastguard Worker 
152*9356374aSAndroid Build Coastguard Worker #if defined(_WIN32)
153*9356374aSAndroid Build Coastguard Worker 
GetNominalCPUFrequency()154*9356374aSAndroid Build Coastguard Worker static double GetNominalCPUFrequency() {
155*9356374aSAndroid Build Coastguard Worker #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
156*9356374aSAndroid Build Coastguard Worker     !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
157*9356374aSAndroid Build Coastguard Worker   // UWP apps don't have access to the registry and currently don't provide an
158*9356374aSAndroid Build Coastguard Worker   // API informing about CPU nominal frequency.
159*9356374aSAndroid Build Coastguard Worker   return 1.0;
160*9356374aSAndroid Build Coastguard Worker #else
161*9356374aSAndroid Build Coastguard Worker #pragma comment(lib, "advapi32.lib")  // For Reg* functions.
162*9356374aSAndroid Build Coastguard Worker   HKEY key;
163*9356374aSAndroid Build Coastguard Worker   // Use the Reg* functions rather than the SH functions because shlwapi.dll
164*9356374aSAndroid Build Coastguard Worker   // pulls in gdi32.dll which makes process destruction much more costly.
165*9356374aSAndroid Build Coastguard Worker   if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
166*9356374aSAndroid Build Coastguard Worker                     "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,
167*9356374aSAndroid Build Coastguard Worker                     KEY_READ, &key) == ERROR_SUCCESS) {
168*9356374aSAndroid Build Coastguard Worker     DWORD type = 0;
169*9356374aSAndroid Build Coastguard Worker     DWORD data = 0;
170*9356374aSAndroid Build Coastguard Worker     DWORD data_size = sizeof(data);
171*9356374aSAndroid Build Coastguard Worker     auto result = RegQueryValueExA(key, "~MHz", nullptr, &type,
172*9356374aSAndroid Build Coastguard Worker                                    reinterpret_cast<LPBYTE>(&data), &data_size);
173*9356374aSAndroid Build Coastguard Worker     RegCloseKey(key);
174*9356374aSAndroid Build Coastguard Worker     if (result == ERROR_SUCCESS && type == REG_DWORD &&
175*9356374aSAndroid Build Coastguard Worker         data_size == sizeof(data)) {
176*9356374aSAndroid Build Coastguard Worker       return data * 1e6;  // Value is MHz.
177*9356374aSAndroid Build Coastguard Worker     }
178*9356374aSAndroid Build Coastguard Worker   }
179*9356374aSAndroid Build Coastguard Worker   return 1.0;
180*9356374aSAndroid Build Coastguard Worker #endif  // WINAPI_PARTITION_APP && !WINAPI_PARTITION_DESKTOP
181*9356374aSAndroid Build Coastguard Worker }
182*9356374aSAndroid Build Coastguard Worker 
183*9356374aSAndroid Build Coastguard Worker #elif defined(CTL_HW) && defined(HW_CPU_FREQ)
184*9356374aSAndroid Build Coastguard Worker 
GetNominalCPUFrequency()185*9356374aSAndroid Build Coastguard Worker static double GetNominalCPUFrequency() {
186*9356374aSAndroid Build Coastguard Worker   unsigned freq;
187*9356374aSAndroid Build Coastguard Worker   size_t size = sizeof(freq);
188*9356374aSAndroid Build Coastguard Worker   int mib[2] = {CTL_HW, HW_CPU_FREQ};
189*9356374aSAndroid Build Coastguard Worker   if (sysctl(mib, 2, &freq, &size, nullptr, 0) == 0) {
190*9356374aSAndroid Build Coastguard Worker     return static_cast<double>(freq);
191*9356374aSAndroid Build Coastguard Worker   }
192*9356374aSAndroid Build Coastguard Worker   return 1.0;
193*9356374aSAndroid Build Coastguard Worker }
194*9356374aSAndroid Build Coastguard Worker 
195*9356374aSAndroid Build Coastguard Worker #else
196*9356374aSAndroid Build Coastguard Worker 
197*9356374aSAndroid Build Coastguard Worker // Helper function for reading a long from a file. Returns true if successful
198*9356374aSAndroid Build Coastguard Worker // and the memory location pointed to by value is set to the value read.
ReadLongFromFile(const char * file,long * value)199*9356374aSAndroid Build Coastguard Worker static bool ReadLongFromFile(const char *file, long *value) {
200*9356374aSAndroid Build Coastguard Worker   bool ret = false;
201*9356374aSAndroid Build Coastguard Worker #if defined(_POSIX_C_SOURCE)
202*9356374aSAndroid Build Coastguard Worker   const int file_mode = (O_RDONLY | O_CLOEXEC);
203*9356374aSAndroid Build Coastguard Worker #else
204*9356374aSAndroid Build Coastguard Worker   const int file_mode = O_RDONLY;
205*9356374aSAndroid Build Coastguard Worker #endif
206*9356374aSAndroid Build Coastguard Worker 
207*9356374aSAndroid Build Coastguard Worker   int fd = open(file, file_mode);
208*9356374aSAndroid Build Coastguard Worker   if (fd != -1) {
209*9356374aSAndroid Build Coastguard Worker     char line[1024];
210*9356374aSAndroid Build Coastguard Worker     char *err;
211*9356374aSAndroid Build Coastguard Worker     memset(line, '\0', sizeof(line));
212*9356374aSAndroid Build Coastguard Worker     ssize_t len;
213*9356374aSAndroid Build Coastguard Worker     do {
214*9356374aSAndroid Build Coastguard Worker       len = read(fd, line, sizeof(line) - 1);
215*9356374aSAndroid Build Coastguard Worker     } while (len < 0 && errno == EINTR);
216*9356374aSAndroid Build Coastguard Worker     if (len <= 0) {
217*9356374aSAndroid Build Coastguard Worker       ret = false;
218*9356374aSAndroid Build Coastguard Worker     } else {
219*9356374aSAndroid Build Coastguard Worker       const long temp_value = strtol(line, &err, 10);
220*9356374aSAndroid Build Coastguard Worker       if (line[0] != '\0' && (*err == '\n' || *err == '\0')) {
221*9356374aSAndroid Build Coastguard Worker         *value = temp_value;
222*9356374aSAndroid Build Coastguard Worker         ret = true;
223*9356374aSAndroid Build Coastguard Worker       }
224*9356374aSAndroid Build Coastguard Worker     }
225*9356374aSAndroid Build Coastguard Worker     close(fd);
226*9356374aSAndroid Build Coastguard Worker   }
227*9356374aSAndroid Build Coastguard Worker   return ret;
228*9356374aSAndroid Build Coastguard Worker }
229*9356374aSAndroid Build Coastguard Worker 
230*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY)
231*9356374aSAndroid Build Coastguard Worker 
232*9356374aSAndroid Build Coastguard Worker // Reads a monotonic time source and returns a value in
233*9356374aSAndroid Build Coastguard Worker // nanoseconds. The returned value uses an arbitrary epoch, not the
234*9356374aSAndroid Build Coastguard Worker // Unix epoch.
ReadMonotonicClockNanos()235*9356374aSAndroid Build Coastguard Worker static int64_t ReadMonotonicClockNanos() {
236*9356374aSAndroid Build Coastguard Worker   struct timespec t;
237*9356374aSAndroid Build Coastguard Worker #ifdef CLOCK_MONOTONIC_RAW
238*9356374aSAndroid Build Coastguard Worker   int rc = clock_gettime(CLOCK_MONOTONIC_RAW, &t);
239*9356374aSAndroid Build Coastguard Worker #else
240*9356374aSAndroid Build Coastguard Worker   int rc = clock_gettime(CLOCK_MONOTONIC, &t);
241*9356374aSAndroid Build Coastguard Worker #endif
242*9356374aSAndroid Build Coastguard Worker   if (rc != 0) {
243*9356374aSAndroid Build Coastguard Worker     ABSL_INTERNAL_LOG(
244*9356374aSAndroid Build Coastguard Worker         FATAL, "clock_gettime() failed: (" + std::to_string(errno) + ")");
245*9356374aSAndroid Build Coastguard Worker   }
246*9356374aSAndroid Build Coastguard Worker   return int64_t{t.tv_sec} * 1000000000 + t.tv_nsec;
247*9356374aSAndroid Build Coastguard Worker }
248*9356374aSAndroid Build Coastguard Worker 
249*9356374aSAndroid Build Coastguard Worker class UnscaledCycleClockWrapperForInitializeFrequency {
250*9356374aSAndroid Build Coastguard Worker  public:
Now()251*9356374aSAndroid Build Coastguard Worker   static int64_t Now() { return base_internal::UnscaledCycleClock::Now(); }
252*9356374aSAndroid Build Coastguard Worker };
253*9356374aSAndroid Build Coastguard Worker 
254*9356374aSAndroid Build Coastguard Worker struct TimeTscPair {
255*9356374aSAndroid Build Coastguard Worker   int64_t time;  // From ReadMonotonicClockNanos().
256*9356374aSAndroid Build Coastguard Worker   int64_t tsc;   // From UnscaledCycleClock::Now().
257*9356374aSAndroid Build Coastguard Worker };
258*9356374aSAndroid Build Coastguard Worker 
259*9356374aSAndroid Build Coastguard Worker // Returns a pair of values (monotonic kernel time, TSC ticks) that
260*9356374aSAndroid Build Coastguard Worker // approximately correspond to each other.  This is accomplished by
261*9356374aSAndroid Build Coastguard Worker // doing several reads and picking the reading with the lowest
262*9356374aSAndroid Build Coastguard Worker // latency.  This approach is used to minimize the probability that
263*9356374aSAndroid Build Coastguard Worker // our thread was preempted between clock reads.
GetTimeTscPair()264*9356374aSAndroid Build Coastguard Worker static TimeTscPair GetTimeTscPair() {
265*9356374aSAndroid Build Coastguard Worker   int64_t best_latency = std::numeric_limits<int64_t>::max();
266*9356374aSAndroid Build Coastguard Worker   TimeTscPair best;
267*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 10; ++i) {
268*9356374aSAndroid Build Coastguard Worker     int64_t t0 = ReadMonotonicClockNanos();
269*9356374aSAndroid Build Coastguard Worker     int64_t tsc = UnscaledCycleClockWrapperForInitializeFrequency::Now();
270*9356374aSAndroid Build Coastguard Worker     int64_t t1 = ReadMonotonicClockNanos();
271*9356374aSAndroid Build Coastguard Worker     int64_t latency = t1 - t0;
272*9356374aSAndroid Build Coastguard Worker     if (latency < best_latency) {
273*9356374aSAndroid Build Coastguard Worker       best_latency = latency;
274*9356374aSAndroid Build Coastguard Worker       best.time = t0;
275*9356374aSAndroid Build Coastguard Worker       best.tsc = tsc;
276*9356374aSAndroid Build Coastguard Worker     }
277*9356374aSAndroid Build Coastguard Worker   }
278*9356374aSAndroid Build Coastguard Worker   return best;
279*9356374aSAndroid Build Coastguard Worker }
280*9356374aSAndroid Build Coastguard Worker 
281*9356374aSAndroid Build Coastguard Worker // Measures and returns the TSC frequency by taking a pair of
282*9356374aSAndroid Build Coastguard Worker // measurements approximately `sleep_nanoseconds` apart.
MeasureTscFrequencyWithSleep(int sleep_nanoseconds)283*9356374aSAndroid Build Coastguard Worker static double MeasureTscFrequencyWithSleep(int sleep_nanoseconds) {
284*9356374aSAndroid Build Coastguard Worker   auto t0 = GetTimeTscPair();
285*9356374aSAndroid Build Coastguard Worker   struct timespec ts;
286*9356374aSAndroid Build Coastguard Worker   ts.tv_sec = 0;
287*9356374aSAndroid Build Coastguard Worker   ts.tv_nsec = sleep_nanoseconds;
288*9356374aSAndroid Build Coastguard Worker   while (nanosleep(&ts, &ts) != 0 && errno == EINTR) {}
289*9356374aSAndroid Build Coastguard Worker   auto t1 = GetTimeTscPair();
290*9356374aSAndroid Build Coastguard Worker   double elapsed_ticks = t1.tsc - t0.tsc;
291*9356374aSAndroid Build Coastguard Worker   double elapsed_time = (t1.time - t0.time) * 1e-9;
292*9356374aSAndroid Build Coastguard Worker   return elapsed_ticks / elapsed_time;
293*9356374aSAndroid Build Coastguard Worker }
294*9356374aSAndroid Build Coastguard Worker 
295*9356374aSAndroid Build Coastguard Worker // Measures and returns the TSC frequency by calling
296*9356374aSAndroid Build Coastguard Worker // MeasureTscFrequencyWithSleep(), doubling the sleep interval until the
297*9356374aSAndroid Build Coastguard Worker // frequency measurement stabilizes.
MeasureTscFrequency()298*9356374aSAndroid Build Coastguard Worker static double MeasureTscFrequency() {
299*9356374aSAndroid Build Coastguard Worker   double last_measurement = -1.0;
300*9356374aSAndroid Build Coastguard Worker   int sleep_nanoseconds = 1000000;  // 1 millisecond.
301*9356374aSAndroid Build Coastguard Worker   for (int i = 0; i < 8; ++i) {
302*9356374aSAndroid Build Coastguard Worker     double measurement = MeasureTscFrequencyWithSleep(sleep_nanoseconds);
303*9356374aSAndroid Build Coastguard Worker     if (measurement * 0.99 < last_measurement &&
304*9356374aSAndroid Build Coastguard Worker         last_measurement < measurement * 1.01) {
305*9356374aSAndroid Build Coastguard Worker       // Use the current measurement if it is within 1% of the
306*9356374aSAndroid Build Coastguard Worker       // previous measurement.
307*9356374aSAndroid Build Coastguard Worker       return measurement;
308*9356374aSAndroid Build Coastguard Worker     }
309*9356374aSAndroid Build Coastguard Worker     last_measurement = measurement;
310*9356374aSAndroid Build Coastguard Worker     sleep_nanoseconds *= 2;
311*9356374aSAndroid Build Coastguard Worker   }
312*9356374aSAndroid Build Coastguard Worker   return last_measurement;
313*9356374aSAndroid Build Coastguard Worker }
314*9356374aSAndroid Build Coastguard Worker 
315*9356374aSAndroid Build Coastguard Worker #endif  // ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY
316*9356374aSAndroid Build Coastguard Worker 
GetNominalCPUFrequency()317*9356374aSAndroid Build Coastguard Worker static double GetNominalCPUFrequency() {
318*9356374aSAndroid Build Coastguard Worker   long freq = 0;
319*9356374aSAndroid Build Coastguard Worker 
320*9356374aSAndroid Build Coastguard Worker   // Google's production kernel has a patch to export the TSC
321*9356374aSAndroid Build Coastguard Worker   // frequency through sysfs. If the kernel is exporting the TSC
322*9356374aSAndroid Build Coastguard Worker   // frequency use that. There are issues where cpuinfo_max_freq
323*9356374aSAndroid Build Coastguard Worker   // cannot be relied on because the BIOS may be exporting an invalid
324*9356374aSAndroid Build Coastguard Worker   // p-state (on x86) or p-states may be used to put the processor in
325*9356374aSAndroid Build Coastguard Worker   // a new mode (turbo mode). Essentially, those frequencies cannot
326*9356374aSAndroid Build Coastguard Worker   // always be relied upon. The same reasons apply to /proc/cpuinfo as
327*9356374aSAndroid Build Coastguard Worker   // well.
328*9356374aSAndroid Build Coastguard Worker   if (ReadLongFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", &freq)) {
329*9356374aSAndroid Build Coastguard Worker     return freq * 1e3;  // Value is kHz.
330*9356374aSAndroid Build Coastguard Worker   }
331*9356374aSAndroid Build Coastguard Worker 
332*9356374aSAndroid Build Coastguard Worker #if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY)
333*9356374aSAndroid Build Coastguard Worker   // On these platforms, the TSC frequency is the nominal CPU
334*9356374aSAndroid Build Coastguard Worker   // frequency.  But without having the kernel export it directly
335*9356374aSAndroid Build Coastguard Worker   // though /sys/devices/system/cpu/cpu0/tsc_freq_khz, there is no
336*9356374aSAndroid Build Coastguard Worker   // other way to reliably get the TSC frequency, so we have to
337*9356374aSAndroid Build Coastguard Worker   // measure it ourselves.  Some CPUs abuse cpuinfo_max_freq by
338*9356374aSAndroid Build Coastguard Worker   // exporting "fake" frequencies for implementing new features. For
339*9356374aSAndroid Build Coastguard Worker   // example, Intel's turbo mode is enabled by exposing a p-state
340*9356374aSAndroid Build Coastguard Worker   // value with a higher frequency than that of the real TSC
341*9356374aSAndroid Build Coastguard Worker   // rate. Because of this, we prefer to measure the TSC rate
342*9356374aSAndroid Build Coastguard Worker   // ourselves on i386 and x86-64.
343*9356374aSAndroid Build Coastguard Worker   return MeasureTscFrequency();
344*9356374aSAndroid Build Coastguard Worker #else
345*9356374aSAndroid Build Coastguard Worker 
346*9356374aSAndroid Build Coastguard Worker   // If CPU scaling is in effect, we want to use the *maximum*
347*9356374aSAndroid Build Coastguard Worker   // frequency, not whatever CPU speed some random processor happens
348*9356374aSAndroid Build Coastguard Worker   // to be using now.
349*9356374aSAndroid Build Coastguard Worker   if (ReadLongFromFile("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq",
350*9356374aSAndroid Build Coastguard Worker                        &freq)) {
351*9356374aSAndroid Build Coastguard Worker     return freq * 1e3;  // Value is kHz.
352*9356374aSAndroid Build Coastguard Worker   }
353*9356374aSAndroid Build Coastguard Worker 
354*9356374aSAndroid Build Coastguard Worker   return 1.0;
355*9356374aSAndroid Build Coastguard Worker #endif  // !ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY
356*9356374aSAndroid Build Coastguard Worker }
357*9356374aSAndroid Build Coastguard Worker 
358*9356374aSAndroid Build Coastguard Worker #endif
359*9356374aSAndroid Build Coastguard Worker 
360*9356374aSAndroid Build Coastguard Worker ABSL_CONST_INIT static once_flag init_num_cpus_once;
361*9356374aSAndroid Build Coastguard Worker ABSL_CONST_INIT static int num_cpus = 0;
362*9356374aSAndroid Build Coastguard Worker 
363*9356374aSAndroid Build Coastguard Worker // NumCPUs() may be called before main() and before malloc is properly
364*9356374aSAndroid Build Coastguard Worker // initialized, therefore this must not allocate memory.
NumCPUs()365*9356374aSAndroid Build Coastguard Worker int NumCPUs() {
366*9356374aSAndroid Build Coastguard Worker   base_internal::LowLevelCallOnce(
367*9356374aSAndroid Build Coastguard Worker       &init_num_cpus_once, []() { num_cpus = GetNumCPUs(); });
368*9356374aSAndroid Build Coastguard Worker   return num_cpus;
369*9356374aSAndroid Build Coastguard Worker }
370*9356374aSAndroid Build Coastguard Worker 
371*9356374aSAndroid Build Coastguard Worker // A default frequency of 0.0 might be dangerous if it is used in division.
372*9356374aSAndroid Build Coastguard Worker ABSL_CONST_INIT static once_flag init_nominal_cpu_frequency_once;
373*9356374aSAndroid Build Coastguard Worker ABSL_CONST_INIT static double nominal_cpu_frequency = 1.0;
374*9356374aSAndroid Build Coastguard Worker 
375*9356374aSAndroid Build Coastguard Worker // NominalCPUFrequency() may be called before main() and before malloc is
376*9356374aSAndroid Build Coastguard Worker // properly initialized, therefore this must not allocate memory.
NominalCPUFrequency()377*9356374aSAndroid Build Coastguard Worker double NominalCPUFrequency() {
378*9356374aSAndroid Build Coastguard Worker   base_internal::LowLevelCallOnce(
379*9356374aSAndroid Build Coastguard Worker       &init_nominal_cpu_frequency_once,
380*9356374aSAndroid Build Coastguard Worker       []() { nominal_cpu_frequency = GetNominalCPUFrequency(); });
381*9356374aSAndroid Build Coastguard Worker   return nominal_cpu_frequency;
382*9356374aSAndroid Build Coastguard Worker }
383*9356374aSAndroid Build Coastguard Worker 
384*9356374aSAndroid Build Coastguard Worker #if defined(_WIN32)
385*9356374aSAndroid Build Coastguard Worker 
GetTID()386*9356374aSAndroid Build Coastguard Worker pid_t GetTID() {
387*9356374aSAndroid Build Coastguard Worker   return pid_t{GetCurrentThreadId()};
388*9356374aSAndroid Build Coastguard Worker }
389*9356374aSAndroid Build Coastguard Worker 
390*9356374aSAndroid Build Coastguard Worker #elif defined(__linux__)
391*9356374aSAndroid Build Coastguard Worker 
392*9356374aSAndroid Build Coastguard Worker #ifndef SYS_gettid
393*9356374aSAndroid Build Coastguard Worker #define SYS_gettid __NR_gettid
394*9356374aSAndroid Build Coastguard Worker #endif
395*9356374aSAndroid Build Coastguard Worker 
GetTID()396*9356374aSAndroid Build Coastguard Worker pid_t GetTID() {
397*9356374aSAndroid Build Coastguard Worker   return static_cast<pid_t>(syscall(SYS_gettid));
398*9356374aSAndroid Build Coastguard Worker }
399*9356374aSAndroid Build Coastguard Worker 
400*9356374aSAndroid Build Coastguard Worker #elif defined(__akaros__)
401*9356374aSAndroid Build Coastguard Worker 
GetTID()402*9356374aSAndroid Build Coastguard Worker pid_t GetTID() {
403*9356374aSAndroid Build Coastguard Worker   // Akaros has a concept of "vcore context", which is the state the program
404*9356374aSAndroid Build Coastguard Worker   // is forced into when we need to make a user-level scheduling decision, or
405*9356374aSAndroid Build Coastguard Worker   // run a signal handler.  This is analogous to the interrupt context that a
406*9356374aSAndroid Build Coastguard Worker   // CPU might enter if it encounters some kind of exception.
407*9356374aSAndroid Build Coastguard Worker   //
408*9356374aSAndroid Build Coastguard Worker   // There is no current thread context in vcore context, but we need to give
409*9356374aSAndroid Build Coastguard Worker   // a reasonable answer if asked for a thread ID (e.g., in a signal handler).
410*9356374aSAndroid Build Coastguard Worker   // Thread 0 always exists, so if we are in vcore context, we return that.
411*9356374aSAndroid Build Coastguard Worker   //
412*9356374aSAndroid Build Coastguard Worker   // Otherwise, we know (since we are using pthreads) that the uthread struct
413*9356374aSAndroid Build Coastguard Worker   // current_uthread is pointing to is the first element of a
414*9356374aSAndroid Build Coastguard Worker   // struct pthread_tcb, so we extract and return the thread ID from that.
415*9356374aSAndroid Build Coastguard Worker   //
416*9356374aSAndroid Build Coastguard Worker   // TODO(dcross): Akaros anticipates moving the thread ID to the uthread
417*9356374aSAndroid Build Coastguard Worker   // structure at some point. We should modify this code to remove the cast
418*9356374aSAndroid Build Coastguard Worker   // when that happens.
419*9356374aSAndroid Build Coastguard Worker   if (in_vcore_context())
420*9356374aSAndroid Build Coastguard Worker     return 0;
421*9356374aSAndroid Build Coastguard Worker   return reinterpret_cast<struct pthread_tcb *>(current_uthread)->id;
422*9356374aSAndroid Build Coastguard Worker }
423*9356374aSAndroid Build Coastguard Worker 
424*9356374aSAndroid Build Coastguard Worker #elif defined(__myriad2__)
425*9356374aSAndroid Build Coastguard Worker 
GetTID()426*9356374aSAndroid Build Coastguard Worker pid_t GetTID() {
427*9356374aSAndroid Build Coastguard Worker   uint32_t tid;
428*9356374aSAndroid Build Coastguard Worker   rtems_task_ident(RTEMS_SELF, 0, &tid);
429*9356374aSAndroid Build Coastguard Worker   return tid;
430*9356374aSAndroid Build Coastguard Worker }
431*9356374aSAndroid Build Coastguard Worker 
432*9356374aSAndroid Build Coastguard Worker #elif defined(__APPLE__)
433*9356374aSAndroid Build Coastguard Worker 
GetTID()434*9356374aSAndroid Build Coastguard Worker pid_t GetTID() {
435*9356374aSAndroid Build Coastguard Worker   uint64_t tid;
436*9356374aSAndroid Build Coastguard Worker   // `nullptr` here implies this thread.  This only fails if the specified
437*9356374aSAndroid Build Coastguard Worker   // thread is invalid or the pointer-to-tid is null, so we needn't worry about
438*9356374aSAndroid Build Coastguard Worker   // it.
439*9356374aSAndroid Build Coastguard Worker   pthread_threadid_np(nullptr, &tid);
440*9356374aSAndroid Build Coastguard Worker   return static_cast<pid_t>(tid);
441*9356374aSAndroid Build Coastguard Worker }
442*9356374aSAndroid Build Coastguard Worker 
443*9356374aSAndroid Build Coastguard Worker #elif defined(__FreeBSD__)
444*9356374aSAndroid Build Coastguard Worker 
GetTID()445*9356374aSAndroid Build Coastguard Worker pid_t GetTID() { return static_cast<pid_t>(pthread_getthreadid_np()); }
446*9356374aSAndroid Build Coastguard Worker 
447*9356374aSAndroid Build Coastguard Worker #elif defined(__OpenBSD__)
448*9356374aSAndroid Build Coastguard Worker 
GetTID()449*9356374aSAndroid Build Coastguard Worker pid_t GetTID() { return getthrid(); }
450*9356374aSAndroid Build Coastguard Worker 
451*9356374aSAndroid Build Coastguard Worker #elif defined(__NetBSD__)
452*9356374aSAndroid Build Coastguard Worker 
GetTID()453*9356374aSAndroid Build Coastguard Worker pid_t GetTID() { return static_cast<pid_t>(_lwp_self()); }
454*9356374aSAndroid Build Coastguard Worker 
455*9356374aSAndroid Build Coastguard Worker #elif defined(__native_client__)
456*9356374aSAndroid Build Coastguard Worker 
GetTID()457*9356374aSAndroid Build Coastguard Worker pid_t GetTID() {
458*9356374aSAndroid Build Coastguard Worker   auto* thread = pthread_self();
459*9356374aSAndroid Build Coastguard Worker   static_assert(sizeof(pid_t) == sizeof(thread),
460*9356374aSAndroid Build Coastguard Worker                 "In NaCL int expected to be the same size as a pointer");
461*9356374aSAndroid Build Coastguard Worker   return reinterpret_cast<pid_t>(thread);
462*9356374aSAndroid Build Coastguard Worker }
463*9356374aSAndroid Build Coastguard Worker 
464*9356374aSAndroid Build Coastguard Worker #else
465*9356374aSAndroid Build Coastguard Worker 
466*9356374aSAndroid Build Coastguard Worker // Fallback implementation of `GetTID` using `pthread_self`.
GetTID()467*9356374aSAndroid Build Coastguard Worker pid_t GetTID() {
468*9356374aSAndroid Build Coastguard Worker   // `pthread_t` need not be arithmetic per POSIX; platforms where it isn't
469*9356374aSAndroid Build Coastguard Worker   // should be handled above.
470*9356374aSAndroid Build Coastguard Worker   return static_cast<pid_t>(pthread_self());
471*9356374aSAndroid Build Coastguard Worker }
472*9356374aSAndroid Build Coastguard Worker 
473*9356374aSAndroid Build Coastguard Worker #endif
474*9356374aSAndroid Build Coastguard Worker 
475*9356374aSAndroid Build Coastguard Worker // GetCachedTID() caches the thread ID in thread-local storage (which is a
476*9356374aSAndroid Build Coastguard Worker // userspace construct) to avoid unnecessary system calls. Without this caching,
477*9356374aSAndroid Build Coastguard Worker // it can take roughly 98ns, while it takes roughly 1ns with this caching.
GetCachedTID()478*9356374aSAndroid Build Coastguard Worker pid_t GetCachedTID() {
479*9356374aSAndroid Build Coastguard Worker #ifdef ABSL_HAVE_THREAD_LOCAL
480*9356374aSAndroid Build Coastguard Worker   static thread_local pid_t thread_id = GetTID();
481*9356374aSAndroid Build Coastguard Worker   return thread_id;
482*9356374aSAndroid Build Coastguard Worker #else
483*9356374aSAndroid Build Coastguard Worker   return GetTID();
484*9356374aSAndroid Build Coastguard Worker #endif  // ABSL_HAVE_THREAD_LOCAL
485*9356374aSAndroid Build Coastguard Worker }
486*9356374aSAndroid Build Coastguard Worker 
487*9356374aSAndroid Build Coastguard Worker }  // namespace base_internal
488*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
489*9356374aSAndroid Build Coastguard Worker }  // namespace absl
490