CoreTiming: Refactor to class.

This commit is contained in:
Admiral H. Curtiss
2022-11-26 09:29:46 +01:00
parent ed84917eb3
commit c9558ecb4c
47 changed files with 718 additions and 566 deletions

View File

@ -49,7 +49,9 @@ public:
Config::Init();
SConfig::Init();
PowerPC::Init(PowerPC::CPUCore::Interpreter);
CoreTiming::Init();
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
core_timing.Init();
}
~ScopeInit()
{
@ -57,7 +59,9 @@ public:
{
return;
}
CoreTiming::Shutdown();
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
core_timing.Shutdown();
PowerPC::Shutdown();
SConfig::Shutdown();
Config::Shutdown();
@ -78,7 +82,9 @@ static void AdvanceAndCheck(u32 idx, int downcount, int expected_lateness = 0,
s_lateness = expected_lateness;
PowerPC::ppcState.downcount = cpu_downcount; // Pretend we executed X cycles of instructions.
CoreTiming::Advance();
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
core_timing.Advance();
EXPECT_EQ(decltype(s_callbacks_ran_flags)().set(idx), s_callbacks_ran_flags);
EXPECT_EQ(downcount, PowerPC::ppcState.downcount);
@ -89,25 +95,28 @@ TEST(CoreTiming, BasicOrder)
ScopeInit guard;
ASSERT_TRUE(guard.UserDirectoryExists());
CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>);
CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", CallbackTemplate<2>);
CoreTiming::EventType* cb_d = CoreTiming::RegisterEvent("callbackD", CallbackTemplate<3>);
CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", CallbackTemplate<4>);
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
CoreTiming::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>);
CoreTiming::EventType* cb_c = core_timing.RegisterEvent("callbackC", CallbackTemplate<2>);
CoreTiming::EventType* cb_d = core_timing.RegisterEvent("callbackD", CallbackTemplate<3>);
CoreTiming::EventType* cb_e = core_timing.RegisterEvent("callbackE", CallbackTemplate<4>);
// Enter slice 0
CoreTiming::Advance();
core_timing.Advance();
// D -> B -> C -> A -> E
CoreTiming::ScheduleEvent(1000, cb_a, CB_IDS[0]);
core_timing.ScheduleEvent(1000, cb_a, CB_IDS[0]);
EXPECT_EQ(1000, PowerPC::ppcState.downcount);
CoreTiming::ScheduleEvent(500, cb_b, CB_IDS[1]);
core_timing.ScheduleEvent(500, cb_b, CB_IDS[1]);
EXPECT_EQ(500, PowerPC::ppcState.downcount);
CoreTiming::ScheduleEvent(800, cb_c, CB_IDS[2]);
core_timing.ScheduleEvent(800, cb_c, CB_IDS[2]);
EXPECT_EQ(500, PowerPC::ppcState.downcount);
CoreTiming::ScheduleEvent(100, cb_d, CB_IDS[3]);
core_timing.ScheduleEvent(100, cb_d, CB_IDS[3]);
EXPECT_EQ(100, PowerPC::ppcState.downcount);
CoreTiming::ScheduleEvent(1200, cb_e, CB_IDS[4]);
core_timing.ScheduleEvent(1200, cb_e, CB_IDS[4]);
EXPECT_EQ(100, PowerPC::ppcState.downcount);
AdvanceAndCheck(3, 400);
@ -140,27 +149,30 @@ TEST(CoreTiming, SharedSlot)
ScopeInit guard;
ASSERT_TRUE(guard.UserDirectoryExists());
CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", FifoCallback<0>);
CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", FifoCallback<1>);
CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", FifoCallback<2>);
CoreTiming::EventType* cb_d = CoreTiming::RegisterEvent("callbackD", FifoCallback<3>);
CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", FifoCallback<4>);
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
CoreTiming::ScheduleEvent(1000, cb_a, CB_IDS[0]);
CoreTiming::ScheduleEvent(1000, cb_b, CB_IDS[1]);
CoreTiming::ScheduleEvent(1000, cb_c, CB_IDS[2]);
CoreTiming::ScheduleEvent(1000, cb_d, CB_IDS[3]);
CoreTiming::ScheduleEvent(1000, cb_e, CB_IDS[4]);
CoreTiming::EventType* cb_a = core_timing.RegisterEvent("callbackA", FifoCallback<0>);
CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", FifoCallback<1>);
CoreTiming::EventType* cb_c = core_timing.RegisterEvent("callbackC", FifoCallback<2>);
CoreTiming::EventType* cb_d = core_timing.RegisterEvent("callbackD", FifoCallback<3>);
CoreTiming::EventType* cb_e = core_timing.RegisterEvent("callbackE", FifoCallback<4>);
core_timing.ScheduleEvent(1000, cb_a, CB_IDS[0]);
core_timing.ScheduleEvent(1000, cb_b, CB_IDS[1]);
core_timing.ScheduleEvent(1000, cb_c, CB_IDS[2]);
core_timing.ScheduleEvent(1000, cb_d, CB_IDS[3]);
core_timing.ScheduleEvent(1000, cb_e, CB_IDS[4]);
// Enter slice 0
CoreTiming::Advance();
core_timing.Advance();
EXPECT_EQ(1000, PowerPC::ppcState.downcount);
s_callbacks_ran_flags = 0;
s_counter = 0;
s_lateness = 0;
PowerPC::ppcState.downcount = 0;
CoreTiming::Advance();
core_timing.Advance();
EXPECT_EQ(MAX_SLICE_LENGTH, PowerPC::ppcState.downcount);
EXPECT_EQ(0x1FULL, s_callbacks_ran_flags.to_ullong());
}
@ -170,14 +182,17 @@ TEST(CoreTiming, PredictableLateness)
ScopeInit guard;
ASSERT_TRUE(guard.UserDirectoryExists());
CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>);
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
CoreTiming::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>);
// Enter slice 0
CoreTiming::Advance();
core_timing.Advance();
CoreTiming::ScheduleEvent(100, cb_a, CB_IDS[0]);
CoreTiming::ScheduleEvent(200, cb_b, CB_IDS[1]);
core_timing.ScheduleEvent(100, cb_a, CB_IDS[0]);
core_timing.ScheduleEvent(200, cb_b, CB_IDS[1]);
AdvanceAndCheck(0, 90, 10, -10); // (100 - 10)
AdvanceAndCheck(1, MAX_SLICE_LENGTH, 50, -50);
@ -194,7 +209,10 @@ static void RescheduleCallback(Core::System& system, u64 userdata, s64 lateness)
EXPECT_EQ(s_lateness, lateness);
if (s_reschedules > 0)
CoreTiming::ScheduleEvent(1000, reinterpret_cast<CoreTiming::EventType*>(userdata), userdata);
{
system.GetCoreTiming().ScheduleEvent(1000, reinterpret_cast<CoreTiming::EventType*>(userdata),
userdata);
}
}
} // namespace ChainSchedulingTest
@ -205,19 +223,22 @@ TEST(CoreTiming, ChainScheduling)
ScopeInit guard;
ASSERT_TRUE(guard.UserDirectoryExists());
CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>);
CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", CallbackTemplate<2>);
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
CoreTiming::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>);
CoreTiming::EventType* cb_c = core_timing.RegisterEvent("callbackC", CallbackTemplate<2>);
CoreTiming::EventType* cb_rs =
CoreTiming::RegisterEvent("callbackReschedule", RescheduleCallback);
core_timing.RegisterEvent("callbackReschedule", RescheduleCallback);
// Enter slice 0
CoreTiming::Advance();
core_timing.Advance();
CoreTiming::ScheduleEvent(800, cb_a, CB_IDS[0]);
CoreTiming::ScheduleEvent(1000, cb_b, CB_IDS[1]);
CoreTiming::ScheduleEvent(2200, cb_c, CB_IDS[2]);
CoreTiming::ScheduleEvent(1000, cb_rs, reinterpret_cast<u64>(cb_rs));
core_timing.ScheduleEvent(800, cb_a, CB_IDS[0]);
core_timing.ScheduleEvent(1000, cb_b, CB_IDS[1]);
core_timing.ScheduleEvent(2200, cb_c, CB_IDS[2]);
core_timing.ScheduleEvent(1000, cb_rs, reinterpret_cast<u64>(cb_rs));
EXPECT_EQ(800, PowerPC::ppcState.downcount);
s_reschedules = 3;
@ -226,14 +247,14 @@ TEST(CoreTiming, ChainScheduling)
EXPECT_EQ(2, s_reschedules);
PowerPC::ppcState.downcount = 0;
CoreTiming::Advance(); // cb_rs
core_timing.Advance(); // cb_rs
EXPECT_EQ(1, s_reschedules);
EXPECT_EQ(200, PowerPC::ppcState.downcount);
AdvanceAndCheck(2, 800); // cb_c
PowerPC::ppcState.downcount = 0;
CoreTiming::Advance(); // cb_rs
core_timing.Advance(); // cb_rs
EXPECT_EQ(0, s_reschedules);
EXPECT_EQ(MAX_SLICE_LENGTH, PowerPC::ppcState.downcount);
}
@ -247,7 +268,7 @@ static void ChainCallback(Core::System& system, u64 userdata, s64 lateness)
EXPECT_EQ(CB_IDS[0] + 1, userdata);
EXPECT_EQ(0, lateness);
CoreTiming::ScheduleEvent(-1000, s_cb_next, userdata - 1);
system.GetCoreTiming().ScheduleEvent(-1000, s_cb_next, userdata - 1);
}
} // namespace ScheduleIntoPastTest
@ -261,14 +282,17 @@ TEST(CoreTiming, ScheduleIntoPast)
ScopeInit guard;
ASSERT_TRUE(guard.UserDirectoryExists());
s_cb_next = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>);
CoreTiming::EventType* cb_chain = CoreTiming::RegisterEvent("callbackChain", ChainCallback);
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
s_cb_next = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>);
CoreTiming::EventType* cb_chain = core_timing.RegisterEvent("callbackChain", ChainCallback);
// Enter slice 0
CoreTiming::Advance();
core_timing.Advance();
CoreTiming::ScheduleEvent(1000, cb_chain, CB_IDS[0] + 1);
core_timing.ScheduleEvent(1000, cb_chain, CB_IDS[0] + 1);
EXPECT_EQ(1000, PowerPC::ppcState.downcount);
AdvanceAndCheck(0, MAX_SLICE_LENGTH, 1000); // Run cb_chain into late cb_a
@ -282,7 +306,7 @@ TEST(CoreTiming, ScheduleIntoPast)
Core::UndeclareAsCPUThread();
auto& core_timing_globals = Core::System::GetInstance().GetCoreTimingGlobals();
core_timing_globals.global_timer -= 1000;
CoreTiming::ScheduleEvent(0, cb_b, CB_IDS[1], CoreTiming::FromThread::NON_CPU);
core_timing.ScheduleEvent(0, cb_b, CB_IDS[1], CoreTiming::FromThread::NON_CPU);
core_timing_globals.global_timer += 1000;
Core::DeclareAsCPUThread();
AdvanceAndCheck(1, MAX_SLICE_LENGTH, MAX_SLICE_LENGTH + 1000);
@ -290,7 +314,7 @@ TEST(CoreTiming, ScheduleIntoPast)
// Schedule directly into the past from the CPU.
// This shouldn't happen in practice, but it's best if we don't mess up the slice length and
// downcount if we do.
CoreTiming::ScheduleEvent(-1000, s_cb_next, CB_IDS[0]);
core_timing.ScheduleEvent(-1000, s_cb_next, CB_IDS[0]);
EXPECT_EQ(0, PowerPC::ppcState.downcount);
AdvanceAndCheck(0, MAX_SLICE_LENGTH, 1000);
}
@ -300,11 +324,14 @@ TEST(CoreTiming, Overclocking)
ScopeInit guard;
ASSERT_TRUE(guard.UserDirectoryExists());
CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>);
CoreTiming::EventType* cb_c = CoreTiming::RegisterEvent("callbackC", CallbackTemplate<2>);
CoreTiming::EventType* cb_d = CoreTiming::RegisterEvent("callbackD", CallbackTemplate<3>);
CoreTiming::EventType* cb_e = CoreTiming::RegisterEvent("callbackE", CallbackTemplate<4>);
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
CoreTiming::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>);
CoreTiming::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>);
CoreTiming::EventType* cb_c = core_timing.RegisterEvent("callbackC", CallbackTemplate<2>);
CoreTiming::EventType* cb_d = core_timing.RegisterEvent("callbackD", CallbackTemplate<3>);
CoreTiming::EventType* cb_e = core_timing.RegisterEvent("callbackE", CallbackTemplate<4>);
// Overclock
Config::SetCurrent(Config::MAIN_OVERCLOCK_ENABLE, true);
@ -312,13 +339,13 @@ TEST(CoreTiming, Overclocking)
// Enter slice 0
// Updates s_last_OC_factor.
CoreTiming::Advance();
core_timing.Advance();
CoreTiming::ScheduleEvent(100, cb_a, CB_IDS[0]);
CoreTiming::ScheduleEvent(200, cb_b, CB_IDS[1]);
CoreTiming::ScheduleEvent(400, cb_c, CB_IDS[2]);
CoreTiming::ScheduleEvent(800, cb_d, CB_IDS[3]);
CoreTiming::ScheduleEvent(1600, cb_e, CB_IDS[4]);
core_timing.ScheduleEvent(100, cb_a, CB_IDS[0]);
core_timing.ScheduleEvent(200, cb_b, CB_IDS[1]);
core_timing.ScheduleEvent(400, cb_c, CB_IDS[2]);
core_timing.ScheduleEvent(800, cb_d, CB_IDS[3]);
core_timing.ScheduleEvent(1600, cb_e, CB_IDS[4]);
EXPECT_EQ(200, PowerPC::ppcState.downcount);
AdvanceAndCheck(0, 200); // (200 - 100) * 2
@ -329,13 +356,13 @@ TEST(CoreTiming, Overclocking)
// Underclock
Config::SetCurrent(Config::MAIN_OVERCLOCK, 0.5f);
CoreTiming::Advance();
core_timing.Advance();
CoreTiming::ScheduleEvent(100, cb_a, CB_IDS[0]);
CoreTiming::ScheduleEvent(200, cb_b, CB_IDS[1]);
CoreTiming::ScheduleEvent(400, cb_c, CB_IDS[2]);
CoreTiming::ScheduleEvent(800, cb_d, CB_IDS[3]);
CoreTiming::ScheduleEvent(1600, cb_e, CB_IDS[4]);
core_timing.ScheduleEvent(100, cb_a, CB_IDS[0]);
core_timing.ScheduleEvent(200, cb_b, CB_IDS[1]);
core_timing.ScheduleEvent(400, cb_c, CB_IDS[2]);
core_timing.ScheduleEvent(800, cb_d, CB_IDS[3]);
core_timing.ScheduleEvent(1600, cb_e, CB_IDS[4]);
EXPECT_EQ(50, PowerPC::ppcState.downcount);
AdvanceAndCheck(0, 50); // (200 - 100) / 2
@ -346,13 +373,13 @@ TEST(CoreTiming, Overclocking)
// Try switching the clock mid-emulation
Config::SetCurrent(Config::MAIN_OVERCLOCK, 1.0f);
CoreTiming::Advance();
core_timing.Advance();
CoreTiming::ScheduleEvent(100, cb_a, CB_IDS[0]);
CoreTiming::ScheduleEvent(200, cb_b, CB_IDS[1]);
CoreTiming::ScheduleEvent(400, cb_c, CB_IDS[2]);
CoreTiming::ScheduleEvent(800, cb_d, CB_IDS[3]);
CoreTiming::ScheduleEvent(1600, cb_e, CB_IDS[4]);
core_timing.ScheduleEvent(100, cb_a, CB_IDS[0]);
core_timing.ScheduleEvent(200, cb_b, CB_IDS[1]);
core_timing.ScheduleEvent(400, cb_c, CB_IDS[2]);
core_timing.ScheduleEvent(800, cb_d, CB_IDS[3]);
core_timing.ScheduleEvent(1600, cb_e, CB_IDS[4]);
EXPECT_EQ(100, PowerPC::ppcState.downcount);
AdvanceAndCheck(0, 100); // (200 - 100)