|
|
@ -14,6 +14,7 @@ namespace Common { |
|
|
class WallClock { |
|
|
class WallClock { |
|
|
public: |
|
|
public: |
|
|
static constexpr u64 CNTFRQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz |
|
|
static constexpr u64 CNTFRQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz |
|
|
|
|
|
static constexpr u64 GPUTickFreq = 614'400'000; // GM20B GPU Tick Frequency = 614.4 MHz |
|
|
|
|
|
|
|
|
virtual ~WallClock() = default; |
|
|
virtual ~WallClock() = default; |
|
|
|
|
|
|
|
|
@ -29,6 +30,9 @@ public: |
|
|
/// @returns The guest CNTPCT ticks since the construction of this clock. |
|
|
/// @returns The guest CNTPCT ticks since the construction of this clock. |
|
|
virtual u64 GetCNTPCT() const = 0; |
|
|
virtual u64 GetCNTPCT() const = 0; |
|
|
|
|
|
|
|
|
|
|
|
/// @returns The guest GPU ticks since the construction of this clock. |
|
|
|
|
|
virtual u64 GetGPUTick() const = 0; |
|
|
|
|
|
|
|
|
/// @returns The raw host timer ticks since an indeterminate epoch. |
|
|
/// @returns The raw host timer ticks since an indeterminate epoch. |
|
|
virtual u64 GetHostTicksNow() const = 0; |
|
|
virtual u64 GetHostTicksNow() const = 0; |
|
|
|
|
|
|
|
|
@ -46,6 +50,10 @@ public: |
|
|
return us * UsToCNTPCTRatio::num / UsToCNTPCTRatio::den; |
|
|
return us * UsToCNTPCTRatio::num / UsToCNTPCTRatio::den; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static inline u64 NSToGPUTick(u64 ns) { |
|
|
|
|
|
return ns * NsToGPUTickRatio::num / NsToGPUTickRatio::den; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static inline u64 CNTPCTToNS(u64 cntpct) { |
|
|
static inline u64 CNTPCTToNS(u64 cntpct) { |
|
|
return cntpct * NsToCNTPCTRatio::den / NsToCNTPCTRatio::num; |
|
|
return cntpct * NsToCNTPCTRatio::den / NsToCNTPCTRatio::num; |
|
|
} |
|
|
} |
|
|
@ -54,6 +62,14 @@ public: |
|
|
return cntpct * UsToCNTPCTRatio::den / UsToCNTPCTRatio::num; |
|
|
return cntpct * UsToCNTPCTRatio::den / UsToCNTPCTRatio::num; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static inline u64 GPUTickToNS(u64 gpu_tick) { |
|
|
|
|
|
return gpu_tick * NsToGPUTickRatio::den / NsToGPUTickRatio::num; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static inline u64 CNTPCTToGPUTick(u64 cntpct) { |
|
|
|
|
|
return cntpct * CNTPCTToGPUTickRatio::num / CNTPCTToGPUTickRatio::den; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
protected: |
|
|
protected: |
|
|
using NsRatio = std::nano; |
|
|
using NsRatio = std::nano; |
|
|
using UsRatio = std::micro; |
|
|
using UsRatio = std::micro; |
|
|
@ -63,6 +79,8 @@ protected: |
|
|
using NsToMsRatio = std::ratio_divide<std::nano, std::milli>; |
|
|
using NsToMsRatio = std::ratio_divide<std::nano, std::milli>; |
|
|
using NsToCNTPCTRatio = std::ratio<CNTFRQ, std::nano::den>; |
|
|
using NsToCNTPCTRatio = std::ratio<CNTFRQ, std::nano::den>; |
|
|
using UsToCNTPCTRatio = std::ratio<CNTFRQ, std::micro::den>; |
|
|
using UsToCNTPCTRatio = std::ratio<CNTFRQ, std::micro::den>; |
|
|
|
|
|
using NsToGPUTickRatio = std::ratio<GPUTickFreq, std::nano::den>; |
|
|
|
|
|
using CNTPCTToGPUTickRatio = std::ratio<GPUTickFreq, CNTFRQ>; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
std::unique_ptr<WallClock> CreateOptimalClock(); |
|
|
std::unique_ptr<WallClock> CreateOptimalClock(); |
|
|
|