diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/arm_interface.h | 9 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.cpp | 9 | ||||
| -rw-r--r-- | src/core/arm/dynarmic/arm_dynarmic.h | 2 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.cpp | 8 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.h | 2 | ||||
| -rw-r--r-- | src/core/core_timing.cpp | 36 | ||||
| -rw-r--r-- | src/core/core_timing.h | 6 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 2 | ||||
| -rw-r--r-- | src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp | 2 |
9 files changed, 33 insertions, 43 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 2aa017a54..ba528403c 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h | |||
| @@ -125,12 +125,6 @@ public: | |||
| 125 | virtual void SetCP15Register(CP15Register reg, u32 value) = 0; | 125 | virtual void SetCP15Register(CP15Register reg, u32 value) = 0; |
| 126 | 126 | ||
| 127 | /** | 127 | /** |
| 128 | * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time) | ||
| 129 | * @param ticks Number of ticks to advance the CPU core | ||
| 130 | */ | ||
| 131 | virtual void AddTicks(u64 ticks) = 0; | ||
| 132 | |||
| 133 | /** | ||
| 134 | * Saves the current CPU context | 128 | * Saves the current CPU context |
| 135 | * @param ctx Thread context to save | 129 | * @param ctx Thread context to save |
| 136 | */ | 130 | */ |
| @@ -150,9 +144,6 @@ public: | |||
| 150 | return num_instructions; | 144 | return num_instructions; |
| 151 | } | 145 | } |
| 152 | 146 | ||
| 153 | s64 down_count = 0; ///< A decreasing counter of remaining cycles before the next event, | ||
| 154 | /// decreased by the cpu run loop | ||
| 155 | |||
| 156 | protected: | 147 | protected: |
| 157 | /** | 148 | /** |
| 158 | * Executes the given number of instructions | 149 | * Executes the given number of instructions |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 42ae93ae8..2cb56d12f 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp | |||
| @@ -124,13 +124,6 @@ void ARM_Dynarmic::SetCP15Register(CP15Register reg, u32 value) { | |||
| 124 | interpreter_state->CP15[reg] = value; | 124 | interpreter_state->CP15[reg] = value; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | void ARM_Dynarmic::AddTicks(u64 ticks) { | ||
| 128 | down_count -= ticks; | ||
| 129 | if (down_count < 0) { | ||
| 130 | CoreTiming::Advance(); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); | 127 | MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); |
| 135 | 128 | ||
| 136 | void ARM_Dynarmic::ExecuteInstructions(int num_instructions) { | 129 | void ARM_Dynarmic::ExecuteInstructions(int num_instructions) { |
| @@ -139,7 +132,7 @@ void ARM_Dynarmic::ExecuteInstructions(int num_instructions) { | |||
| 139 | 132 | ||
| 140 | std::size_t ticks_executed = jit->Run(static_cast<unsigned>(num_instructions)); | 133 | std::size_t ticks_executed = jit->Run(static_cast<unsigned>(num_instructions)); |
| 141 | 134 | ||
| 142 | AddTicks(ticks_executed); | 135 | CoreTiming::AddTicks(ticks_executed); |
| 143 | } | 136 | } |
| 144 | 137 | ||
| 145 | void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { | 138 | void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { |
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 96148a1a5..0b00158a5 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h | |||
| @@ -32,8 +32,6 @@ public: | |||
| 32 | u32 GetCP15Register(CP15Register reg) override; | 32 | u32 GetCP15Register(CP15Register reg) override; |
| 33 | void SetCP15Register(CP15Register reg, u32 value) override; | 33 | void SetCP15Register(CP15Register reg, u32 value) override; |
| 34 | 34 | ||
| 35 | void AddTicks(u64 ticks) override; | ||
| 36 | |||
| 37 | void SaveContext(ThreadContext& ctx) override; | 35 | void SaveContext(ThreadContext& ctx) override; |
| 38 | void LoadContext(const ThreadContext& ctx) override; | 36 | void LoadContext(const ThreadContext& ctx) override; |
| 39 | 37 | ||
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index da955c9b9..4d72aef77 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp | |||
| @@ -77,12 +77,6 @@ void ARM_DynCom::SetCP15Register(CP15Register reg, u32 value) { | |||
| 77 | state->CP15[reg] = value; | 77 | state->CP15[reg] = value; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | void ARM_DynCom::AddTicks(u64 ticks) { | ||
| 81 | down_count -= ticks; | ||
| 82 | if (down_count < 0) | ||
| 83 | CoreTiming::Advance(); | ||
| 84 | } | ||
| 85 | |||
| 86 | void ARM_DynCom::ExecuteInstructions(int num_instructions) { | 80 | void ARM_DynCom::ExecuteInstructions(int num_instructions) { |
| 87 | state->NumInstrsToExecute = num_instructions; | 81 | state->NumInstrsToExecute = num_instructions; |
| 88 | 82 | ||
| @@ -90,7 +84,7 @@ void ARM_DynCom::ExecuteInstructions(int num_instructions) { | |||
| 90 | // executing one instruction at a time. Otherwise, if a block is being executed, more | 84 | // executing one instruction at a time. Otherwise, if a block is being executed, more |
| 91 | // instructions may actually be executed than specified. | 85 | // instructions may actually be executed than specified. |
| 92 | unsigned ticks_executed = InterpreterMainLoop(state.get()); | 86 | unsigned ticks_executed = InterpreterMainLoop(state.get()); |
| 93 | AddTicks(ticks_executed); | 87 | CoreTiming::AddTicks(ticks_executed); |
| 94 | } | 88 | } |
| 95 | 89 | ||
| 96 | void ARM_DynCom::SaveContext(ThreadContext& ctx) { | 90 | void ARM_DynCom::SaveContext(ThreadContext& ctx) { |
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 0ae535671..fc1ffed6a 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h | |||
| @@ -31,8 +31,6 @@ public: | |||
| 31 | u32 GetCP15Register(CP15Register reg) override; | 31 | u32 GetCP15Register(CP15Register reg) override; |
| 32 | void SetCP15Register(CP15Register reg, u32 value) override; | 32 | void SetCP15Register(CP15Register reg, u32 value) override; |
| 33 | 33 | ||
| 34 | void AddTicks(u64 ticks) override; | ||
| 35 | |||
| 36 | void SaveContext(ThreadContext& ctx) override; | 34 | void SaveContext(ThreadContext& ctx) override; |
| 37 | void LoadContext(const ThreadContext& ctx) override; | 35 | void LoadContext(const ThreadContext& ctx) override; |
| 38 | 36 | ||
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 276ecfdf6..5e2a5d00f 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -57,6 +57,9 @@ static s64 idled_cycles; | |||
| 57 | static s64 last_global_time_ticks; | 57 | static s64 last_global_time_ticks; |
| 58 | static s64 last_global_time_us; | 58 | static s64 last_global_time_us; |
| 59 | 59 | ||
| 60 | static s64 down_count = 0; ///< A decreasing counter of remaining cycles before the next event, | ||
| 61 | /// decreased by the cpu run loop | ||
| 62 | |||
| 60 | static std::recursive_mutex external_event_section; | 63 | static std::recursive_mutex external_event_section; |
| 61 | 64 | ||
| 62 | // Warning: not included in save state. | 65 | // Warning: not included in save state. |
| @@ -146,7 +149,7 @@ void UnregisterAllEvents() { | |||
| 146 | } | 149 | } |
| 147 | 150 | ||
| 148 | void Init() { | 151 | void Init() { |
| 149 | Core::CPU().down_count = INITIAL_SLICE_LENGTH; | 152 | down_count = INITIAL_SLICE_LENGTH; |
| 150 | g_slice_length = INITIAL_SLICE_LENGTH; | 153 | g_slice_length = INITIAL_SLICE_LENGTH; |
| 151 | global_timer = 0; | 154 | global_timer = 0; |
| 152 | idled_cycles = 0; | 155 | idled_cycles = 0; |
| @@ -185,8 +188,15 @@ void Shutdown() { | |||
| 185 | } | 188 | } |
| 186 | } | 189 | } |
| 187 | 190 | ||
| 191 | void AddTicks(u64 ticks) { | ||
| 192 | down_count -= ticks; | ||
| 193 | if (down_count < 0) { | ||
| 194 | Advance(); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 188 | u64 GetTicks() { | 198 | u64 GetTicks() { |
| 189 | return (u64)global_timer + g_slice_length - Core::CPU().down_count; | 199 | return (u64)global_timer + g_slice_length - down_count; |
| 190 | } | 200 | } |
| 191 | 201 | ||
| 192 | u64 GetIdleTicks() { | 202 | u64 GetIdleTicks() { |
| @@ -460,18 +470,18 @@ void MoveEvents() { | |||
| 460 | } | 470 | } |
| 461 | 471 | ||
| 462 | void ForceCheck() { | 472 | void ForceCheck() { |
| 463 | s64 cycles_executed = g_slice_length - Core::CPU().down_count; | 473 | s64 cycles_executed = g_slice_length - down_count; |
| 464 | global_timer += cycles_executed; | 474 | global_timer += cycles_executed; |
| 465 | // This will cause us to check for new events immediately. | 475 | // This will cause us to check for new events immediately. |
| 466 | Core::CPU().down_count = 0; | 476 | down_count = 0; |
| 467 | // But let's not eat a bunch more time in Advance() because of this. | 477 | // But let's not eat a bunch more time in Advance() because of this. |
| 468 | g_slice_length = 0; | 478 | g_slice_length = 0; |
| 469 | } | 479 | } |
| 470 | 480 | ||
| 471 | void Advance() { | 481 | void Advance() { |
| 472 | s64 cycles_executed = g_slice_length - Core::CPU().down_count; | 482 | s64 cycles_executed = g_slice_length - down_count; |
| 473 | global_timer += cycles_executed; | 483 | global_timer += cycles_executed; |
| 474 | Core::CPU().down_count = g_slice_length; | 484 | down_count = g_slice_length; |
| 475 | 485 | ||
| 476 | if (has_ts_events) | 486 | if (has_ts_events) |
| 477 | MoveEvents(); | 487 | MoveEvents(); |
| @@ -480,7 +490,7 @@ void Advance() { | |||
| 480 | if (!first) { | 490 | if (!first) { |
| 481 | if (g_slice_length < 10000) { | 491 | if (g_slice_length < 10000) { |
| 482 | g_slice_length += 10000; | 492 | g_slice_length += 10000; |
| 483 | Core::CPU().down_count += g_slice_length; | 493 | down_count += g_slice_length; |
| 484 | } | 494 | } |
| 485 | } else { | 495 | } else { |
| 486 | // Note that events can eat cycles as well. | 496 | // Note that events can eat cycles as well. |
| @@ -490,7 +500,7 @@ void Advance() { | |||
| 490 | 500 | ||
| 491 | const int diff = target - g_slice_length; | 501 | const int diff = target - g_slice_length; |
| 492 | g_slice_length += diff; | 502 | g_slice_length += diff; |
| 493 | Core::CPU().down_count += diff; | 503 | down_count += diff; |
| 494 | } | 504 | } |
| 495 | if (advance_callback) | 505 | if (advance_callback) |
| 496 | advance_callback(static_cast<int>(cycles_executed)); | 506 | advance_callback(static_cast<int>(cycles_executed)); |
| @@ -506,12 +516,12 @@ void LogPendingEvents() { | |||
| 506 | } | 516 | } |
| 507 | 517 | ||
| 508 | void Idle(int max_idle) { | 518 | void Idle(int max_idle) { |
| 509 | s64 cycles_down = Core::CPU().down_count; | 519 | s64 cycles_down = down_count; |
| 510 | if (max_idle != 0 && cycles_down > max_idle) | 520 | if (max_idle != 0 && cycles_down > max_idle) |
| 511 | cycles_down = max_idle; | 521 | cycles_down = max_idle; |
| 512 | 522 | ||
| 513 | if (first && cycles_down > 0) { | 523 | if (first && cycles_down > 0) { |
| 514 | s64 cycles_executed = g_slice_length - Core::CPU().down_count; | 524 | s64 cycles_executed = g_slice_length - down_count; |
| 515 | s64 cycles_next_event = first->time - global_timer; | 525 | s64 cycles_next_event = first->time - global_timer; |
| 516 | 526 | ||
| 517 | if (cycles_next_event < cycles_executed + cycles_down) { | 527 | if (cycles_next_event < cycles_executed + cycles_down) { |
| @@ -526,9 +536,9 @@ void Idle(int max_idle) { | |||
| 526 | cycles_down / (float)(g_clock_rate_arm11 * 0.001f)); | 536 | cycles_down / (float)(g_clock_rate_arm11 * 0.001f)); |
| 527 | 537 | ||
| 528 | idled_cycles += cycles_down; | 538 | idled_cycles += cycles_down; |
| 529 | Core::CPU().down_count -= cycles_down; | 539 | down_count -= cycles_down; |
| 530 | if (Core::CPU().down_count == 0) | 540 | if (down_count == 0) |
| 531 | Core::CPU().down_count = -1; | 541 | down_count = -1; |
| 532 | } | 542 | } |
| 533 | 543 | ||
| 534 | std::string GetScheduledEventsSummary() { | 544 | std::string GetScheduledEventsSummary() { |
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index d2f85cd4d..897350801 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -67,6 +67,12 @@ void Shutdown(); | |||
| 67 | typedef void (*MHzChangeCallback)(); | 67 | typedef void (*MHzChangeCallback)(); |
| 68 | typedef std::function<void(u64 userdata, int cycles_late)> TimedCallback; | 68 | typedef std::function<void(u64 userdata, int cycles_late)> TimedCallback; |
| 69 | 69 | ||
| 70 | /** | ||
| 71 | * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time) | ||
| 72 | * @param ticks Number of ticks to advance the CPU core | ||
| 73 | */ | ||
| 74 | void AddTicks(u64 ticks); | ||
| 75 | |||
| 70 | u64 GetTicks(); | 76 | u64 GetTicks(); |
| 71 | u64 GetIdleTicks(); | 77 | u64 GetIdleTicks(); |
| 72 | u64 GetGlobalTimeUs(); | 78 | u64 GetGlobalTimeUs(); |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index fefd50805..6be5db13f 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -1039,7 +1039,7 @@ static void SleepThread(s64 nanoseconds) { | |||
| 1039 | static s64 GetSystemTick() { | 1039 | static s64 GetSystemTick() { |
| 1040 | s64 result = CoreTiming::GetTicks(); | 1040 | s64 result = CoreTiming::GetTicks(); |
| 1041 | // Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end. | 1041 | // Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end. |
| 1042 | Core::CPU().AddTicks(150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b | 1042 | CoreTiming::AddTicks(150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b |
| 1043 | return result; | 1043 | return result; |
| 1044 | } | 1044 | } |
| 1045 | 1045 | ||
diff --git a/src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp b/src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp index 86de41773..83719a58e 100644 --- a/src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp +++ b/src/tests/core/arm/dyncom/arm_dyncom_vfp_tests.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <catch.hpp> | 5 | #include <catch.hpp> |
| 6 | 6 | ||
| 7 | #include "core/arm/dyncom/arm_dyncom.h" | 7 | #include "core/arm/dyncom/arm_dyncom.h" |
| 8 | #include "core/core_timing.h" | ||
| 8 | #include "tests/core/arm/arm_test_common.h" | 9 | #include "tests/core/arm/arm_test_common.h" |
| 9 | 10 | ||
| 10 | namespace ArmTests { | 11 | namespace ArmTests { |
| @@ -29,7 +30,6 @@ TEST_CASE("ARM_DynCom (vfp): vadd", "[arm_dyncom]") { | |||
| 29 | }}; | 30 | }}; |
| 30 | 31 | ||
| 31 | for (const auto& test_case : test_cases) { | 32 | for (const auto& test_case : test_cases) { |
| 32 | dyncom.down_count = 1000; // Ensure that CoreTimeing will not be called. | ||
| 33 | dyncom.SetPC(0); | 33 | dyncom.SetPC(0); |
| 34 | dyncom.SetVFPSystemReg(VFP_FPSCR, test_case.initial_fpscr); | 34 | dyncom.SetVFPSystemReg(VFP_FPSCR, test_case.initial_fpscr); |
| 35 | dyncom.SetVFPReg(4, test_case.a); | 35 | dyncom.SetVFPReg(4, test_case.a); |