wall_clock.h 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <chrono>
  5. #include <memory>
  6. #include <ratio>
  7. #include "common/common_types.h"
  8. namespace Common {
  9. class WallClock {
  10. public:
  11. static constexpr u64 CNTFRQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz
  12. static constexpr u64 GPUTickFreq = 614'400'000; // GM20B GPU Tick Frequency = 614.4 MHz
  13. static constexpr u64 CPUTickFreq = 1'020'000'000; // T210/4 A57 CPU Tick Frequency = 1020.0 MHz
  14. virtual ~WallClock() = default;
  15. /// @returns The time in nanoseconds since the construction of this clock.
  16. virtual std::chrono::nanoseconds GetTimeNS() const = 0;
  17. /// @returns The time in microseconds since the construction of this clock.
  18. virtual std::chrono::microseconds GetTimeUS() const = 0;
  19. /// @returns The time in milliseconds since the construction of this clock.
  20. virtual std::chrono::milliseconds GetTimeMS() const = 0;
  21. /// @returns The guest CNTPCT ticks since the construction of this clock.
  22. virtual s64 GetCNTPCT() const = 0;
  23. /// @returns The guest GPU ticks since the construction of this clock.
  24. virtual s64 GetGPUTick() const = 0;
  25. /// @returns The raw host timer ticks since an indeterminate epoch.
  26. virtual s64 GetUptime() const = 0;
  27. /// @returns Whether the clock directly uses the host's hardware clock.
  28. virtual bool IsNative() const = 0;
  29. static inline u64 NSToCNTPCT(u64 ns) {
  30. return ns * NsToCNTPCTRatio::num / NsToCNTPCTRatio::den;
  31. }
  32. static inline u64 NSToGPUTick(u64 ns) {
  33. return ns * NsToGPUTickRatio::num / NsToGPUTickRatio::den;
  34. }
  35. // Cycle Timing
  36. static inline u64 CPUTickToNS(u64 cpu_tick) {
  37. return cpu_tick * CPUTickToNsRatio::num / CPUTickToNsRatio::den;
  38. }
  39. static inline u64 CPUTickToUS(u64 cpu_tick) {
  40. return cpu_tick * CPUTickToUsRatio::num / CPUTickToUsRatio::den;
  41. }
  42. static inline u64 CPUTickToCNTPCT(u64 cpu_tick) {
  43. return cpu_tick * CPUTickToCNTPCTRatio::num / CPUTickToCNTPCTRatio::den;
  44. }
  45. static inline u64 CPUTickToGPUTick(u64 cpu_tick) {
  46. return cpu_tick * CPUTickToGPUTickRatio::num / CPUTickToGPUTickRatio::den;
  47. }
  48. protected:
  49. using NsRatio = std::nano;
  50. using UsRatio = std::micro;
  51. using MsRatio = std::milli;
  52. using NsToUsRatio = std::ratio_divide<std::nano, std::micro>;
  53. using NsToMsRatio = std::ratio_divide<std::nano, std::milli>;
  54. using NsToCNTPCTRatio = std::ratio<CNTFRQ, std::nano::den>;
  55. using NsToGPUTickRatio = std::ratio<GPUTickFreq, std::nano::den>;
  56. // Cycle Timing
  57. using CPUTickToNsRatio = std::ratio<std::nano::den, CPUTickFreq>;
  58. using CPUTickToUsRatio = std::ratio<std::micro::den, CPUTickFreq>;
  59. using CPUTickToCNTPCTRatio = std::ratio<CNTFRQ, CPUTickFreq>;
  60. using CPUTickToGPUTickRatio = std::ratio<GPUTickFreq, CPUTickFreq>;
  61. };
  62. std::unique_ptr<WallClock> CreateOptimalClock();
  63. std::unique_ptr<WallClock> CreateStandardWallClock();
  64. } // namespace Common