mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-30 10:20:06 +00:00
CoreTiming: Adopt integer overflow handling if clock rate gets changed
This commit is contained in:
parent
1f288e06bc
commit
3f9739b60f
@ -4,6 +4,7 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <cinttypes>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#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<s64>::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<s64>::max() / g_clock_rate_arm11;
|
||||
// TODO: Rescale times of scheduled events?
|
||||
|
||||
FireMhzChange();
|
||||
|
@ -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<s64>::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<s64>::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<s64>::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<s64>(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<s64>::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<s64>::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<s64>(ns / 1000000000));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user