From 3f9739b60f6d2992b5789481eb5ef6af8f6d7e1a Mon Sep 17 00:00:00 2001 From: B3n30 Date: Tue, 14 Nov 2017 10:26:58 +0100 Subject: [PATCH] CoreTiming: Adopt integer overflow handling if clock rate gets changed --- src/core/core_timing.cpp | 3 +++ src/core/core_timing.h | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 5e2a5d00f..f799e88f7 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include "common/chunk_file.h" @@ -14,6 +15,7 @@ #include "core/core_timing.h" int g_clock_rate_arm11 = BASE_CLOCK_RATE_ARM11; +u64 max_value_to_multiply = std::numeric_limits::max() / g_clock_rate_arm11; // is this really necessary? #define INITIAL_SLICE_LENGTH 20000 @@ -79,6 +81,7 @@ void SetClockFrequencyMHz(int cpu_mhz) { last_global_time_ticks = GetTicks(); g_clock_rate_arm11 = cpu_mhz * 1000000; + max_value_to_multiply = std::numeric_limits::max() / g_clock_rate_arm11; // TODO: Rescale times of scheduled events? FireMhzChange(); diff --git a/src/core/core_timing.h b/src/core/core_timing.h index e1c48c8e0..8b2907f3c 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -24,12 +24,12 @@ // ScheduleEvent(periodInCycles - cycles_late, callback, "whatever") // The timing we get from the assembly is 268,111,855.956 Hz -// It is possible that this number isn't jus a integer because the compiler could have +// It is possible that this number isn't just an integer because the compiler could have // optimized the multiplication by a multiply-by-constant division. // Rounding to the nearest integer should be fine constexpr s64 BASE_CLOCK_RATE_ARM11 = 268111856; -constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits::max() / 268111856; +extern u64 max_value_to_multiply; extern int g_clock_rate_arm11; inline s64 msToCycles(int ms) { @@ -54,10 +54,10 @@ inline s64 usToCycles(int us) { } inline s64 usToCycles(s64 us) { - if ((us / 1000000) > MAX_VALUE_TO_MULTIPLY) { + if ((us / 1000000) > max_value_to_multiply) { LOG_ERROR(Core_Timing, "Integer overflow, use max value"); return std::numeric_limits::max(); - } else if (us > MAX_VALUE_TO_MULTIPLY) { + } else if (us > max_value_to_multiply) { LOG_DEBUG(Core_Timing, "Time very big, do rounding"); return (g_clock_rate_arm11 * (us / 1000000)); } @@ -65,10 +65,10 @@ inline s64 usToCycles(s64 us) { } inline s64 usToCycles(u64 us) { - if ((us / 1000000) > MAX_VALUE_TO_MULTIPLY) { + if ((us / 1000000) > max_value_to_multiply) { LOG_ERROR(Core_Timing, "Integer overflow, use max value"); return std::numeric_limits::max(); - } else if (us > MAX_VALUE_TO_MULTIPLY) { + } else if (us > max_value_to_multiply) { LOG_DEBUG(Core_Timing, "Time very big, do rounding"); return (g_clock_rate_arm11 * static_cast(us / 1000000)); } @@ -84,10 +84,10 @@ inline s64 nsToCycles(int ns) { } inline s64 nsToCycles(s64 ns) { - if ((ns / 1000000000) > MAX_VALUE_TO_MULTIPLY) { + if ((ns / 1000000000) > max_value_to_multiply) { LOG_ERROR(Core_Timing, "Integer overflow, use max value"); return std::numeric_limits::max(); - } else if (ns > MAX_VALUE_TO_MULTIPLY) { + } else if (ns > max_value_to_multiply) { LOG_DEBUG(Core_Timing, "Time very big, do rounding"); return (g_clock_rate_arm11 * (ns / 1000000000)); } @@ -95,10 +95,10 @@ inline s64 nsToCycles(s64 ns) { } inline s64 nsToCycles(u64 ns) { - if ((ns / 1000000000) > MAX_VALUE_TO_MULTIPLY) { + if ((ns / 1000000000) > max_value_to_multiply) { LOG_ERROR(Core_Timing, "Integer overflow, use max value"); return std::numeric_limits::max(); - } else if (ns > MAX_VALUE_TO_MULTIPLY) { + } else if (ns > max_value_to_multiply) { LOG_DEBUG(Core_Timing, "Time very big, do rounding"); return (g_clock_rate_arm11 * static_cast(ns / 1000000000)); }