unscaledcycleclock.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. #ifndef ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_
  36. #define ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_
  37. #include <cstdint>
  38. #if defined(__APPLE__)
  39. #include <TargetConditionals.h>
  40. #endif
  41. #include "absl/base/config.h"
  42. #include "absl/base/internal/unscaledcycleclock_config.h"
  43. #if ABSL_USE_UNSCALED_CYCLECLOCK
  44. namespace absl {
  45. ABSL_NAMESPACE_BEGIN
  46. namespace time_internal {
  47. class UnscaledCycleClockWrapperForGetCurrentTime;
  48. } // namespace time_internal
  49. namespace base_internal {
  50. class CycleClock;
  51. class UnscaledCycleClockWrapperForInitializeFrequency;
  52. class UnscaledCycleClock {
  53. private:
  54. UnscaledCycleClock() = delete;
  55. // Return the value of a cycle counter that counts at a rate that is
  56. // approximately constant.
  57. static int64_t Now();
  58. // Return the how much UnscaledCycleClock::Now() increases per second.
  59. // This is not necessarily the core CPU clock frequency.
  60. // It may be the nominal value report by the kernel, rather than a measured
  61. // value.
  62. static double Frequency();
  63. // Allowed users
  64. friend class base_internal::CycleClock;
  65. friend class time_internal::UnscaledCycleClockWrapperForGetCurrentTime;
  66. friend class base_internal::UnscaledCycleClockWrapperForInitializeFrequency;
  67. };
  68. #if defined(__x86_64__)
  69. inline int64_t UnscaledCycleClock::Now() {
  70. uint64_t low, high;
  71. __asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
  72. return static_cast<int64_t>((high << 32) | low);
  73. }
  74. #endif
  75. } // namespace base_internal
  76. ABSL_NAMESPACE_END
  77. } // namespace absl
  78. #endif // ABSL_USE_UNSCALED_CYCLECLOCK
  79. #endif // ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_