tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

unscaledcycleclock.h (3569B)


      1 // Copyright 2017 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 //
     15 // UnscaledCycleClock
     16 //    An UnscaledCycleClock yields the value and frequency of a cycle counter
     17 //    that increments at a rate that is approximately constant.
     18 //    This class is for internal use only, you should consider using CycleClock
     19 //    instead.
     20 //
     21 // Notes:
     22 // The cycle counter frequency is not necessarily the core clock frequency.
     23 // That is, CycleCounter cycles are not necessarily "CPU cycles".
     24 //
     25 // An arbitrary offset may have been added to the counter at power on.
     26 //
     27 // On some platforms, the rate and offset of the counter may differ
     28 // slightly when read from different CPUs of a multiprocessor.  Usually,
     29 // we try to ensure that the operating system adjusts values periodically
     30 // so that values agree approximately.   If you need stronger guarantees,
     31 // consider using alternate interfaces.
     32 //
     33 // The CPU is not required to maintain the ordering of a cycle counter read
     34 // with respect to surrounding instructions.
     35 
     36 #ifndef ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_
     37 #define ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_
     38 
     39 #include <cstdint>
     40 
     41 #if defined(__APPLE__)
     42 #include <TargetConditionals.h>
     43 #endif
     44 
     45 #include "absl/base/config.h"
     46 #include "absl/base/internal/unscaledcycleclock_config.h"
     47 
     48 #if ABSL_USE_UNSCALED_CYCLECLOCK
     49 
     50 namespace absl {
     51 ABSL_NAMESPACE_BEGIN
     52 namespace time_internal {
     53 class UnscaledCycleClockWrapperForGetCurrentTime;
     54 }  // namespace time_internal
     55 
     56 namespace base_internal {
     57 class CycleClock;
     58 class UnscaledCycleClockWrapperForInitializeFrequency;
     59 
     60 class UnscaledCycleClock {
     61 private:
     62  UnscaledCycleClock() = delete;
     63 
     64  // Return the value of a cycle counter that counts at a rate that is
     65  // approximately constant.
     66  static int64_t Now();
     67 
     68  // Return the how much UnscaledCycleClock::Now() increases per second.
     69  // This is not necessarily the core CPU clock frequency.
     70  // It may be the nominal value report by the kernel, rather than a measured
     71  // value.
     72  static double Frequency();
     73 
     74  // Allowed users
     75  friend class base_internal::CycleClock;
     76  friend class time_internal::UnscaledCycleClockWrapperForGetCurrentTime;
     77  friend class base_internal::UnscaledCycleClockWrapperForInitializeFrequency;
     78 };
     79 
     80 #if defined(__x86_64__)
     81 
     82 inline int64_t UnscaledCycleClock::Now() {
     83  uint64_t low, high;
     84  __asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
     85  return static_cast<int64_t>((high << 32) | low);
     86 }
     87 
     88 #elif defined(__aarch64__)
     89 
     90 // System timer of ARMv8 runs at a different frequency than the CPU's.
     91 // The frequency is fixed, typically in the range 1-50MHz.  It can be
     92 // read at CNTFRQ special register.  We assume the OS has set up
     93 // the virtual timer properly.
     94 inline int64_t UnscaledCycleClock::Now() {
     95  int64_t virtual_timer_value;
     96  asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
     97  return virtual_timer_value;
     98 }
     99 
    100 #endif
    101 
    102 }  // namespace base_internal
    103 ABSL_NAMESPACE_END
    104 }  // namespace absl
    105 
    106 #endif  // ABSL_USE_UNSCALED_CYCLECLOCK
    107 
    108 #endif  // ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_