mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-07-04 23:31:19 +01:00
Merge pull request #2973 from huwpascoe/down_count
Moved down_count to CoreTiming
This commit is contained in:
commit
5ba48c1610
9 changed files with 33 additions and 43 deletions
|
@ -124,12 +124,6 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual void SetCP15Register(CP15Register reg, u32 value) = 0;
|
virtual void SetCP15Register(CP15Register reg, u32 value) = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time)
|
|
||||||
* @param ticks Number of ticks to advance the CPU core
|
|
||||||
*/
|
|
||||||
virtual void AddTicks(u64 ticks) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the current CPU context
|
* Saves the current CPU context
|
||||||
* @param ctx Thread context to save
|
* @param ctx Thread context to save
|
||||||
|
@ -150,9 +144,6 @@ public:
|
||||||
return num_instructions;
|
return num_instructions;
|
||||||
}
|
}
|
||||||
|
|
||||||
s64 down_count = 0; ///< A decreasing counter of remaining cycles before the next event,
|
|
||||||
/// decreased by the cpu run loop
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Executes the given number of instructions
|
* Executes the given number of instructions
|
||||||
|
|
|
@ -124,13 +124,6 @@ void ARM_Dynarmic::SetCP15Register(CP15Register reg, u32 value) {
|
||||||
interpreter_state->CP15[reg] = value;
|
interpreter_state->CP15[reg] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_Dynarmic::AddTicks(u64 ticks) {
|
|
||||||
down_count -= ticks;
|
|
||||||
if (down_count < 0) {
|
|
||||||
CoreTiming::Advance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
|
MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
|
||||||
|
|
||||||
void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
|
void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
|
||||||
|
@ -139,7 +132,7 @@ void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
|
||||||
|
|
||||||
std::size_t ticks_executed = jit->Run(static_cast<unsigned>(num_instructions));
|
std::size_t ticks_executed = jit->Run(static_cast<unsigned>(num_instructions));
|
||||||
|
|
||||||
AddTicks(ticks_executed);
|
CoreTiming::AddTicks(ticks_executed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
|
void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
|
||||||
|
|
|
@ -32,8 +32,6 @@ public:
|
||||||
u32 GetCP15Register(CP15Register reg) override;
|
u32 GetCP15Register(CP15Register reg) override;
|
||||||
void SetCP15Register(CP15Register reg, u32 value) override;
|
void SetCP15Register(CP15Register reg, u32 value) override;
|
||||||
|
|
||||||
void AddTicks(u64 ticks) override;
|
|
||||||
|
|
||||||
void SaveContext(ThreadContext& ctx) override;
|
void SaveContext(ThreadContext& ctx) override;
|
||||||
void LoadContext(const ThreadContext& ctx) override;
|
void LoadContext(const ThreadContext& ctx) override;
|
||||||
|
|
||||||
|
|
|
@ -77,12 +77,6 @@ void ARM_DynCom::SetCP15Register(CP15Register reg, u32 value) {
|
||||||
state->CP15[reg] = value;
|
state->CP15[reg] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_DynCom::AddTicks(u64 ticks) {
|
|
||||||
down_count -= ticks;
|
|
||||||
if (down_count < 0)
|
|
||||||
CoreTiming::Advance();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ARM_DynCom::ExecuteInstructions(int num_instructions) {
|
void ARM_DynCom::ExecuteInstructions(int num_instructions) {
|
||||||
state->NumInstrsToExecute = num_instructions;
|
state->NumInstrsToExecute = num_instructions;
|
||||||
|
|
||||||
|
@ -90,7 +84,7 @@ void ARM_DynCom::ExecuteInstructions(int num_instructions) {
|
||||||
// executing one instruction at a time. Otherwise, if a block is being executed, more
|
// executing one instruction at a time. Otherwise, if a block is being executed, more
|
||||||
// instructions may actually be executed than specified.
|
// instructions may actually be executed than specified.
|
||||||
unsigned ticks_executed = InterpreterMainLoop(state.get());
|
unsigned ticks_executed = InterpreterMainLoop(state.get());
|
||||||
AddTicks(ticks_executed);
|
CoreTiming::AddTicks(ticks_executed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARM_DynCom::SaveContext(ThreadContext& ctx) {
|
void ARM_DynCom::SaveContext(ThreadContext& ctx) {
|
||||||
|
|
|
@ -31,8 +31,6 @@ public:
|
||||||
u32 GetCP15Register(CP15Register reg) override;
|
u32 GetCP15Register(CP15Register reg) override;
|
||||||
void SetCP15Register(CP15Register reg, u32 value) override;
|
void SetCP15Register(CP15Register reg, u32 value) override;
|
||||||
|
|
||||||
void AddTicks(u64 ticks) override;
|
|
||||||
|
|
||||||
void SaveContext(ThreadContext& ctx) override;
|
void SaveContext(ThreadContext& ctx) override;
|
||||||
void LoadContext(const ThreadContext& ctx) override;
|
void LoadContext(const ThreadContext& ctx) override;
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,9 @@ static s64 idled_cycles;
|
||||||
static s64 last_global_time_ticks;
|
static s64 last_global_time_ticks;
|
||||||
static s64 last_global_time_us;
|
static s64 last_global_time_us;
|
||||||
|
|
||||||
|
static s64 down_count = 0; ///< A decreasing counter of remaining cycles before the next event,
|
||||||
|
/// decreased by the cpu run loop
|
||||||
|
|
||||||
static std::recursive_mutex external_event_section;
|
static std::recursive_mutex external_event_section;
|
||||||
|
|
||||||
// Warning: not included in save state.
|
// Warning: not included in save state.
|
||||||
|
@ -146,7 +149,7 @@ void UnregisterAllEvents() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Init() {
|
void Init() {
|
||||||
Core::CPU().down_count = INITIAL_SLICE_LENGTH;
|
down_count = INITIAL_SLICE_LENGTH;
|
||||||
g_slice_length = INITIAL_SLICE_LENGTH;
|
g_slice_length = INITIAL_SLICE_LENGTH;
|
||||||
global_timer = 0;
|
global_timer = 0;
|
||||||
idled_cycles = 0;
|
idled_cycles = 0;
|
||||||
|
@ -185,8 +188,15 @@ void Shutdown() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddTicks(u64 ticks) {
|
||||||
|
down_count -= ticks;
|
||||||
|
if (down_count < 0) {
|
||||||
|
Advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u64 GetTicks() {
|
u64 GetTicks() {
|
||||||
return (u64)global_timer + g_slice_length - Core::CPU().down_count;
|
return (u64)global_timer + g_slice_length - down_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GetIdleTicks() {
|
u64 GetIdleTicks() {
|
||||||
|
@ -460,18 +470,18 @@ void MoveEvents() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForceCheck() {
|
void ForceCheck() {
|
||||||
s64 cycles_executed = g_slice_length - Core::CPU().down_count;
|
s64 cycles_executed = g_slice_length - down_count;
|
||||||
global_timer += cycles_executed;
|
global_timer += cycles_executed;
|
||||||
// This will cause us to check for new events immediately.
|
// This will cause us to check for new events immediately.
|
||||||
Core::CPU().down_count = 0;
|
down_count = 0;
|
||||||
// But let's not eat a bunch more time in Advance() because of this.
|
// But let's not eat a bunch more time in Advance() because of this.
|
||||||
g_slice_length = 0;
|
g_slice_length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Advance() {
|
void Advance() {
|
||||||
s64 cycles_executed = g_slice_length - Core::CPU().down_count;
|
s64 cycles_executed = g_slice_length - down_count;
|
||||||
global_timer += cycles_executed;
|
global_timer += cycles_executed;
|
||||||
Core::CPU().down_count = g_slice_length;
|
down_count = g_slice_length;
|
||||||
|
|
||||||
if (has_ts_events)
|
if (has_ts_events)
|
||||||
MoveEvents();
|
MoveEvents();
|
||||||
|
@ -480,7 +490,7 @@ void Advance() {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
if (g_slice_length < 10000) {
|
if (g_slice_length < 10000) {
|
||||||
g_slice_length += 10000;
|
g_slice_length += 10000;
|
||||||
Core::CPU().down_count += g_slice_length;
|
down_count += g_slice_length;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Note that events can eat cycles as well.
|
// Note that events can eat cycles as well.
|
||||||
|
@ -490,7 +500,7 @@ void Advance() {
|
||||||
|
|
||||||
const int diff = target - g_slice_length;
|
const int diff = target - g_slice_length;
|
||||||
g_slice_length += diff;
|
g_slice_length += diff;
|
||||||
Core::CPU().down_count += diff;
|
down_count += diff;
|
||||||
}
|
}
|
||||||
if (advance_callback)
|
if (advance_callback)
|
||||||
advance_callback(static_cast<int>(cycles_executed));
|
advance_callback(static_cast<int>(cycles_executed));
|
||||||
|
@ -506,12 +516,12 @@ void LogPendingEvents() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Idle(int max_idle) {
|
void Idle(int max_idle) {
|
||||||
s64 cycles_down = Core::CPU().down_count;
|
s64 cycles_down = down_count;
|
||||||
if (max_idle != 0 && cycles_down > max_idle)
|
if (max_idle != 0 && cycles_down > max_idle)
|
||||||
cycles_down = max_idle;
|
cycles_down = max_idle;
|
||||||
|
|
||||||
if (first && cycles_down > 0) {
|
if (first && cycles_down > 0) {
|
||||||
s64 cycles_executed = g_slice_length - Core::CPU().down_count;
|
s64 cycles_executed = g_slice_length - down_count;
|
||||||
s64 cycles_next_event = first->time - global_timer;
|
s64 cycles_next_event = first->time - global_timer;
|
||||||
|
|
||||||
if (cycles_next_event < cycles_executed + cycles_down) {
|
if (cycles_next_event < cycles_executed + cycles_down) {
|
||||||
|
@ -526,9 +536,9 @@ void Idle(int max_idle) {
|
||||||
cycles_down / (float)(g_clock_rate_arm11 * 0.001f));
|
cycles_down / (float)(g_clock_rate_arm11 * 0.001f));
|
||||||
|
|
||||||
idled_cycles += cycles_down;
|
idled_cycles += cycles_down;
|
||||||
Core::CPU().down_count -= cycles_down;
|
down_count -= cycles_down;
|
||||||
if (Core::CPU().down_count == 0)
|
if (down_count == 0)
|
||||||
Core::CPU().down_count = -1;
|
down_count = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetScheduledEventsSummary() {
|
std::string GetScheduledEventsSummary() {
|
||||||
|
|
|
@ -67,6 +67,12 @@ void Shutdown();
|
||||||
typedef void (*MHzChangeCallback)();
|
typedef void (*MHzChangeCallback)();
|
||||||
typedef std::function<void(u64 userdata, int cycles_late)> TimedCallback;
|
typedef std::function<void(u64 userdata, int cycles_late)> TimedCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time)
|
||||||
|
* @param ticks Number of ticks to advance the CPU core
|
||||||
|
*/
|
||||||
|
void AddTicks(u64 ticks);
|
||||||
|
|
||||||
u64 GetTicks();
|
u64 GetTicks();
|
||||||
u64 GetIdleTicks();
|
u64 GetIdleTicks();
|
||||||
u64 GetGlobalTimeUs();
|
u64 GetGlobalTimeUs();
|
||||||
|
|
|
@ -1039,7 +1039,7 @@ static void SleepThread(s64 nanoseconds) {
|
||||||
static s64 GetSystemTick() {
|
static s64 GetSystemTick() {
|
||||||
s64 result = CoreTiming::GetTicks();
|
s64 result = CoreTiming::GetTicks();
|
||||||
// Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end.
|
// Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end.
|
||||||
Core::CPU().AddTicks(150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b
|
CoreTiming::AddTicks(150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
#include "core/arm/dyncom/arm_dyncom.h"
|
#include "core/arm/dyncom/arm_dyncom.h"
|
||||||
|
#include "core/core_timing.h"
|
||||||
#include "tests/core/arm/arm_test_common.h"
|
#include "tests/core/arm/arm_test_common.h"
|
||||||
|
|
||||||
namespace ArmTests {
|
namespace ArmTests {
|
||||||
|
@ -29,7 +30,6 @@ TEST_CASE("ARM_DynCom (vfp): vadd", "[arm_dyncom]") {
|
||||||
}};
|
}};
|
||||||
|
|
||||||
for (const auto& test_case : test_cases) {
|
for (const auto& test_case : test_cases) {
|
||||||
dyncom.down_count = 1000; // Ensure that CoreTimeing will not be called.
|
|
||||||
dyncom.SetPC(0);
|
dyncom.SetPC(0);
|
||||||
dyncom.SetVFPSystemReg(VFP_FPSCR, test_case.initial_fpscr);
|
dyncom.SetVFPSystemReg(VFP_FPSCR, test_case.initial_fpscr);
|
||||||
dyncom.SetVFPReg(4, test_case.a);
|
dyncom.SetVFPReg(4, test_case.a);
|
||||||
|
|
Loading…
Reference in a new issue