diff options
Diffstat (limited to 'src/common/x64/native_clock.cpp')
| -rw-r--r-- | src/common/x64/native_clock.cpp | 47 |
1 files changed, 7 insertions, 40 deletions
diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index c799111fd..26d4d0ba6 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp | |||
| @@ -11,44 +11,11 @@ | |||
| 11 | #include <x86intrin.h> | 11 | #include <x86intrin.h> |
| 12 | #endif | 12 | #endif |
| 13 | 13 | ||
| 14 | #include "common/uint128.h" | ||
| 14 | #include "common/x64/native_clock.h" | 15 | #include "common/x64/native_clock.h" |
| 15 | 16 | ||
| 16 | namespace Common { | 17 | namespace Common { |
| 17 | 18 | ||
| 18 | #ifdef _MSC_VER | ||
| 19 | |||
| 20 | namespace { | ||
| 21 | |||
| 22 | struct uint128 { | ||
| 23 | u64 low; | ||
| 24 | u64 high; | ||
| 25 | }; | ||
| 26 | |||
| 27 | u64 umuldiv64(u64 a, u64 b, u64 d) { | ||
| 28 | uint128 r{}; | ||
| 29 | r.low = _umul128(a, b, &r.high); | ||
| 30 | u64 remainder; | ||
| 31 | return _udiv128(r.high, r.low, d, &remainder); | ||
| 32 | } | ||
| 33 | |||
| 34 | } // namespace | ||
| 35 | |||
| 36 | #else | ||
| 37 | |||
| 38 | namespace { | ||
| 39 | |||
| 40 | u64 umuldiv64(u64 a, u64 b, u64 d) { | ||
| 41 | const u64 diva = a / d; | ||
| 42 | const u64 moda = a % d; | ||
| 43 | const u64 divb = b / d; | ||
| 44 | const u64 modb = b % d; | ||
| 45 | return diva * b + moda * divb + moda * modb / d; | ||
| 46 | } | ||
| 47 | |||
| 48 | } // namespace | ||
| 49 | |||
| 50 | #endif | ||
| 51 | |||
| 52 | u64 EstimateRDTSCFrequency() { | 19 | u64 EstimateRDTSCFrequency() { |
| 53 | const auto milli_10 = std::chrono::milliseconds{10}; | 20 | const auto milli_10 = std::chrono::milliseconds{10}; |
| 54 | // get current time | 21 | // get current time |
| @@ -70,7 +37,7 @@ u64 EstimateRDTSCFrequency() { | |||
| 70 | const u64 timer_diff = | 37 | const u64 timer_diff = |
| 71 | std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count(); | 38 | std::chrono::duration_cast<std::chrono::nanoseconds>(endTime - startTime).count(); |
| 72 | const u64 tsc_diff = tscEnd - tscStart; | 39 | const u64 tsc_diff = tscEnd - tscStart; |
| 73 | const u64 tsc_freq = umuldiv64(tsc_diff, 1000000000ULL, timer_diff); | 40 | const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff); |
| 74 | return tsc_freq; | 41 | return tsc_freq; |
| 75 | } | 42 | } |
| 76 | 43 | ||
| @@ -100,27 +67,27 @@ u64 NativeClock::GetRTSC() { | |||
| 100 | 67 | ||
| 101 | std::chrono::nanoseconds NativeClock::GetTimeNS() { | 68 | std::chrono::nanoseconds NativeClock::GetTimeNS() { |
| 102 | const u64 rtsc_value = GetRTSC(); | 69 | const u64 rtsc_value = GetRTSC(); |
| 103 | return std::chrono::nanoseconds{umuldiv64(rtsc_value, 1000000000, rtsc_frequency)}; | 70 | return std::chrono::nanoseconds{MultiplyAndDivide64(rtsc_value, 1000000000, rtsc_frequency)}; |
| 104 | } | 71 | } |
| 105 | 72 | ||
| 106 | std::chrono::microseconds NativeClock::GetTimeUS() { | 73 | std::chrono::microseconds NativeClock::GetTimeUS() { |
| 107 | const u64 rtsc_value = GetRTSC(); | 74 | const u64 rtsc_value = GetRTSC(); |
| 108 | return std::chrono::microseconds{umuldiv64(rtsc_value, 1000000, rtsc_frequency)}; | 75 | return std::chrono::microseconds{MultiplyAndDivide64(rtsc_value, 1000000, rtsc_frequency)}; |
| 109 | } | 76 | } |
| 110 | 77 | ||
| 111 | std::chrono::milliseconds NativeClock::GetTimeMS() { | 78 | std::chrono::milliseconds NativeClock::GetTimeMS() { |
| 112 | const u64 rtsc_value = GetRTSC(); | 79 | const u64 rtsc_value = GetRTSC(); |
| 113 | return std::chrono::milliseconds{umuldiv64(rtsc_value, 1000, rtsc_frequency)}; | 80 | return std::chrono::milliseconds{MultiplyAndDivide64(rtsc_value, 1000, rtsc_frequency)}; |
| 114 | } | 81 | } |
| 115 | 82 | ||
| 116 | u64 NativeClock::GetClockCycles() { | 83 | u64 NativeClock::GetClockCycles() { |
| 117 | const u64 rtsc_value = GetRTSC(); | 84 | const u64 rtsc_value = GetRTSC(); |
| 118 | return umuldiv64(rtsc_value, emulated_clock_frequency, rtsc_frequency); | 85 | return MultiplyAndDivide64(rtsc_value, emulated_clock_frequency, rtsc_frequency); |
| 119 | } | 86 | } |
| 120 | 87 | ||
| 121 | u64 NativeClock::GetCPUCycles() { | 88 | u64 NativeClock::GetCPUCycles() { |
| 122 | const u64 rtsc_value = GetRTSC(); | 89 | const u64 rtsc_value = GetRTSC(); |
| 123 | return umuldiv64(rtsc_value, emulated_cpu_frequency, rtsc_frequency); | 90 | return MultiplyAndDivide64(rtsc_value, emulated_cpu_frequency, rtsc_frequency); |
| 124 | } | 91 | } |
| 125 | 92 | ||
| 126 | } // namespace X64 | 93 | } // namespace X64 |