diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/core_timing.cpp | 52 | ||||
| -rw-r--r-- | src/core/core_timing.h | 51 |
2 files changed, 55 insertions, 48 deletions
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 91c93e01f..dc1d8668f 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <algorithm> | 7 | #include <algorithm> |
| 8 | #include <cinttypes> | 8 | #include <cinttypes> |
| 9 | #include <limits> | ||
| 9 | #include <mutex> | 10 | #include <mutex> |
| 10 | #include <string> | 11 | #include <string> |
| 11 | #include <tuple> | 12 | #include <tuple> |
| @@ -57,7 +58,8 @@ static u64 event_fifo_id; | |||
| 57 | // to the event_queue by the emu thread | 58 | // to the event_queue by the emu thread |
| 58 | static Common::MPSCQueue<Event, false> ts_queue; | 59 | static Common::MPSCQueue<Event, false> ts_queue; |
| 59 | 60 | ||
| 60 | static constexpr int MAX_SLICE_LENGTH = 20000; | 61 | constexpr int MAX_SLICE_LENGTH = 20000; |
| 62 | constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits<s64>::max() / BASE_CLOCK_RATE; | ||
| 61 | 63 | ||
| 62 | static s64 idled_cycles; | 64 | static s64 idled_cycles; |
| 63 | 65 | ||
| @@ -70,6 +72,54 @@ static EventType* ev_lost = nullptr; | |||
| 70 | 72 | ||
| 71 | static void EmptyTimedCallback(u64 userdata, s64 cyclesLate) {} | 73 | static void EmptyTimedCallback(u64 userdata, s64 cyclesLate) {} |
| 72 | 74 | ||
| 75 | s64 usToCycles(s64 us) { | ||
| 76 | if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) { | ||
| 77 | NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); | ||
| 78 | return std::numeric_limits<s64>::max(); | ||
| 79 | } | ||
| 80 | if (us > MAX_VALUE_TO_MULTIPLY) { | ||
| 81 | NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); | ||
| 82 | return BASE_CLOCK_RATE * (us / 1000000); | ||
| 83 | } | ||
| 84 | return (BASE_CLOCK_RATE * us) / 1000000; | ||
| 85 | } | ||
| 86 | |||
| 87 | s64 usToCycles(u64 us) { | ||
| 88 | if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) { | ||
| 89 | NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); | ||
| 90 | return std::numeric_limits<s64>::max(); | ||
| 91 | } | ||
| 92 | if (us > MAX_VALUE_TO_MULTIPLY) { | ||
| 93 | NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); | ||
| 94 | return BASE_CLOCK_RATE * static_cast<s64>(us / 1000000); | ||
| 95 | } | ||
| 96 | return (BASE_CLOCK_RATE * static_cast<s64>(us)) / 1000000; | ||
| 97 | } | ||
| 98 | |||
| 99 | s64 nsToCycles(s64 ns) { | ||
| 100 | if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) { | ||
| 101 | NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); | ||
| 102 | return std::numeric_limits<s64>::max(); | ||
| 103 | } | ||
| 104 | if (ns > MAX_VALUE_TO_MULTIPLY) { | ||
| 105 | NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); | ||
| 106 | return BASE_CLOCK_RATE * (ns / 1000000000); | ||
| 107 | } | ||
| 108 | return (BASE_CLOCK_RATE * ns) / 1000000000; | ||
| 109 | } | ||
| 110 | |||
| 111 | s64 nsToCycles(u64 ns) { | ||
| 112 | if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) { | ||
| 113 | NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); | ||
| 114 | return std::numeric_limits<s64>::max(); | ||
| 115 | } | ||
| 116 | if (ns > MAX_VALUE_TO_MULTIPLY) { | ||
| 117 | NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); | ||
| 118 | return BASE_CLOCK_RATE * (static_cast<s64>(ns) / 1000000000); | ||
| 119 | } | ||
| 120 | return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000; | ||
| 121 | } | ||
| 122 | |||
| 73 | EventType* RegisterEvent(const std::string& name, TimedCallback callback) { | 123 | EventType* RegisterEvent(const std::string& name, TimedCallback callback) { |
| 74 | // check for existing type with same name. | 124 | // check for existing type with same name. |
| 75 | // we want event type names to remain unique so that we can use them for serialization. | 125 | // we want event type names to remain unique so that we can use them for serialization. |
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 9d3c1d05c..dc31124a8 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -18,17 +18,14 @@ | |||
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <functional> | 20 | #include <functional> |
| 21 | #include <limits> | ||
| 22 | #include <string> | 21 | #include <string> |
| 23 | #include "common/common_types.h" | 22 | #include "common/common_types.h" |
| 24 | #include "common/logging/log.h" | ||
| 25 | 23 | ||
| 26 | namespace CoreTiming { | 24 | namespace CoreTiming { |
| 27 | 25 | ||
| 28 | // The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz | 26 | // The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz |
| 29 | // The exact value used is of course unverified. | 27 | // The exact value used is of course unverified. |
| 30 | constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch clock speed is 1020MHz un/docked | 28 | constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch clock speed is 1020MHz un/docked |
| 31 | constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits<s64>::max() / BASE_CLOCK_RATE; | ||
| 32 | 29 | ||
| 33 | inline s64 msToCycles(int ms) { | 30 | inline s64 msToCycles(int ms) { |
| 34 | // since ms is int there is no way to overflow | 31 | // since ms is int there is no way to overflow |
| @@ -51,29 +48,9 @@ inline s64 usToCycles(int us) { | |||
| 51 | return (BASE_CLOCK_RATE * static_cast<s64>(us) / 1000000); | 48 | return (BASE_CLOCK_RATE * static_cast<s64>(us) / 1000000); |
| 52 | } | 49 | } |
| 53 | 50 | ||
| 54 | inline s64 usToCycles(s64 us) { | 51 | s64 usToCycles(s64 us); |
| 55 | if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) { | ||
| 56 | NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); | ||
| 57 | return std::numeric_limits<s64>::max(); | ||
| 58 | } | ||
| 59 | if (us > MAX_VALUE_TO_MULTIPLY) { | ||
| 60 | NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); | ||
| 61 | return BASE_CLOCK_RATE * (us / 1000000); | ||
| 62 | } | ||
| 63 | return (BASE_CLOCK_RATE * us) / 1000000; | ||
| 64 | } | ||
| 65 | 52 | ||
| 66 | inline s64 usToCycles(u64 us) { | 53 | s64 usToCycles(u64 us); |
| 67 | if (us / 1000000 > MAX_VALUE_TO_MULTIPLY) { | ||
| 68 | NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); | ||
| 69 | return std::numeric_limits<s64>::max(); | ||
| 70 | } | ||
| 71 | if (us > MAX_VALUE_TO_MULTIPLY) { | ||
| 72 | NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); | ||
| 73 | return BASE_CLOCK_RATE * static_cast<s64>(us / 1000000); | ||
| 74 | } | ||
| 75 | return (BASE_CLOCK_RATE * static_cast<s64>(us)) / 1000000; | ||
| 76 | } | ||
| 77 | 54 | ||
| 78 | inline s64 nsToCycles(float ns) { | 55 | inline s64 nsToCycles(float ns) { |
| 79 | return static_cast<s64>(BASE_CLOCK_RATE * (0.000000001f) * ns); | 56 | return static_cast<s64>(BASE_CLOCK_RATE * (0.000000001f) * ns); |
| @@ -83,29 +60,9 @@ inline s64 nsToCycles(int ns) { | |||
| 83 | return BASE_CLOCK_RATE * static_cast<s64>(ns) / 1000000000; | 60 | return BASE_CLOCK_RATE * static_cast<s64>(ns) / 1000000000; |
| 84 | } | 61 | } |
| 85 | 62 | ||
| 86 | inline s64 nsToCycles(s64 ns) { | 63 | s64 nsToCycles(s64 ns); |
| 87 | if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) { | ||
| 88 | NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); | ||
| 89 | return std::numeric_limits<s64>::max(); | ||
| 90 | } | ||
| 91 | if (ns > MAX_VALUE_TO_MULTIPLY) { | ||
| 92 | NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); | ||
| 93 | return BASE_CLOCK_RATE * (ns / 1000000000); | ||
| 94 | } | ||
| 95 | return (BASE_CLOCK_RATE * ns) / 1000000000; | ||
| 96 | } | ||
| 97 | 64 | ||
| 98 | inline s64 nsToCycles(u64 ns) { | 65 | s64 nsToCycles(u64 ns); |
| 99 | if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) { | ||
| 100 | NGLOG_ERROR(Core_Timing, "Integer overflow, use max value"); | ||
| 101 | return std::numeric_limits<s64>::max(); | ||
| 102 | } | ||
| 103 | if (ns > MAX_VALUE_TO_MULTIPLY) { | ||
| 104 | NGLOG_DEBUG(Core_Timing, "Time very big, do rounding"); | ||
| 105 | return BASE_CLOCK_RATE * (static_cast<s64>(ns) / 1000000000); | ||
| 106 | } | ||
| 107 | return (BASE_CLOCK_RATE * static_cast<s64>(ns)) / 1000000000; | ||
| 108 | } | ||
| 109 | 66 | ||
| 110 | inline u64 cyclesToNs(s64 cycles) { | 67 | inline u64 cyclesToNs(s64 cycles) { |
| 111 | return cycles * 1000000000 / BASE_CLOCK_RATE; | 68 | return cycles * 1000000000 / BASE_CLOCK_RATE; |