26 #include <sys/types.h> 31 #include <sys/syscall.h> 34 #if defined(__APPLE__) || defined(__FreeBSD__) 35 #include <sys/sysctl.h> 38 #if defined(__myriad2__) 59 namespace base_internal {
66 #if defined(__myriad2__) 72 return std::thread::hardware_concurrency();
80 DWORD data_size =
sizeof(
data);
81 #pragma comment(lib, "shlwapi.lib") // For SHGetValue(). 83 SHGetValueA(HKEY_LOCAL_MACHINE,
84 "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
85 "~MHz",
nullptr, &data, &data_size))) {
91 #elif defined(CTL_HW) && defined(HW_CPU_FREQ) 95 size_t size =
sizeof(freq);
96 int mib[2] = {CTL_HW, HW_CPU_FREQ};
97 if (sysctl(mib, 2, &freq, &size,
nullptr, 0) == 0) {
98 return static_cast<double>(freq);
109 int fd = open(file, O_RDONLY);
113 memset(line,
'\0',
sizeof(line));
114 int len = read(fd, line,
sizeof(line) - 1);
118 const long temp_value = strtol(line, &err, 10);
119 if (line[0] !=
'\0' && (*err ==
'\n' || *err ==
'\0')) {
129 #if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY) 134 static int64_t ReadMonotonicClockNanos() {
136 #ifdef CLOCK_MONOTONIC_RAW 137 int rc = clock_gettime(CLOCK_MONOTONIC_RAW, &t);
139 int rc = clock_gettime(CLOCK_MONOTONIC, &t);
142 perror(
"clock_gettime() failed");
145 return int64_t{t.tv_sec} * 1000000000 + t.tv_nsec;
148 class UnscaledCycleClockWrapperForInitializeFrequency {
163 static TimeTscPair GetTimeTscPair() {
164 int64_t best_latency = std::numeric_limits<int64_t>::max();
166 for (
int i = 0;
i < 10; ++
i) {
167 int64_t t0 = ReadMonotonicClockNanos();
169 int64_t
t1 = ReadMonotonicClockNanos();
170 int64_t latency = t1 - t0;
171 if (latency < best_latency) {
172 best_latency = latency;
182 static double MeasureTscFrequencyWithSleep(
int sleep_nanoseconds) {
183 auto t0 = GetTimeTscPair();
186 ts.tv_nsec = sleep_nanoseconds;
187 while (nanosleep(&ts, &ts) != 0 && errno == EINTR) {}
188 auto t1 = GetTimeTscPair();
189 double elapsed_ticks =
t1.tsc - t0.tsc;
190 double elapsed_time = (
t1.time - t0.time) * 1e-9;
191 return elapsed_ticks / elapsed_time;
197 static double MeasureTscFrequency() {
198 double last_measurement = -1.0;
199 int sleep_nanoseconds = 1000000;
200 for (
int i = 0;
i < 8; ++
i) {
201 double measurement = MeasureTscFrequencyWithSleep(sleep_nanoseconds);
202 if (measurement * 0.99 < last_measurement &&
203 last_measurement < measurement * 1.01) {
208 last_measurement = measurement;
209 sleep_nanoseconds *= 2;
211 return last_measurement;
214 #endif // ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY 231 #if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY) 242 return MeasureTscFrequency();
248 if (
ReadLongFromFile(
"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq",
254 #endif // !ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY 280 return GetCurrentThreadId();
283 #elif defined(__linux__) 286 #define SYS_gettid __NR_gettid 290 return syscall(SYS_gettid);
293 #elif defined(__akaros__) 312 if (in_vcore_context())
314 return reinterpret_cast<struct pthread_tcb *
>(current_uthread)->
id;
317 #elif defined(__myriad2__) 321 rtems_task_ident(RTEMS_SELF, 0, &tid);
341 intptr_t tid =
reinterpret_cast<intptr_t
>(
v);
345 assert(0 <= word && static_cast<size_t>(word) < tid_array->size());
346 (*tid_array)[word] &= mask;
350 if (pthread_key_create(&tid_key,
FreeTID) != 0) {
352 perror(
"pthread_key_create failed");
358 tid_array =
new std::vector<uint32_t>(1);
366 intptr_t tid =
reinterpret_cast<intptr_t
>(pthread_getspecific(tid_key));
378 while (word < tid_array->
size() && ~(*tid_array)[word] == 0) {
381 if (word == tid_array->size()) {
382 tid_array->push_back(0);
386 while (bit < kBitsPerWord && (((*tid_array)[word] >> bit) & 1) != 0) {
390 (*tid_array)[word] |= 1u << bit;
393 if (pthread_setspecific(tid_key, reinterpret_cast<void *>(tid)) != 0) {
394 perror(
"pthread_setspecific failed");
398 return static_cast<pid_t
>(tid);
static void FreeTID(void *v)
static constexpr int kBitsPerWord
static double GetNominalCPUFrequency()
double NominalCPUFrequency()
static double nominal_cpu_frequency
void call_once(absl::once_flag &flag, Callable &&fn, Args &&...args)
static char data[kDataSize]
void LowLevelCallOnce(absl::once_flag *flag, Callable &&fn, Args &&...args)
static void InitializeSystemInfo()
static pthread_key_t tid_key
static absl::base_internal::SpinLock tid_lock(absl::base_internal::kLinkerInitialized)
static std::vector< uint32_t > *tid_array GUARDED_BY(tid_lock)
static once_flag tid_once
static once_flag init_system_info_once
static bool ReadLongFromFile(const char *file, long *value)