diff options
Diffstat (limited to 'src/tests')
| -rw-r--r-- | src/tests/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/tests/common/bit_field.cpp | 90 | ||||
| -rw-r--r-- | src/tests/common/bit_utils.cpp | 23 | ||||
| -rw-r--r-- | src/tests/common/multi_level_queue.cpp | 55 | ||||
| -rw-r--r-- | src/tests/core/arm/arm_test_common.cpp | 14 | ||||
| -rw-r--r-- | src/tests/core/arm/arm_test_common.h | 8 | ||||
| -rw-r--r-- | src/tests/core/core_timing.cpp | 220 | 
7 files changed, 297 insertions, 116 deletions
| diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 37f09ce5f..c7038b217 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,4 +1,7 @@  add_executable(tests +    common/bit_field.cpp +    common/bit_utils.cpp +    common/multi_level_queue.cpp      common/param_package.cpp      common/ring_buffer.cpp      core/arm/arm_test_common.cpp diff --git a/src/tests/common/bit_field.cpp b/src/tests/common/bit_field.cpp new file mode 100644 index 000000000..8ca1889f9 --- /dev/null +++ b/src/tests/common/bit_field.cpp @@ -0,0 +1,90 @@ +// Copyright 2019 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <array> +#include <cstring> +#include <type_traits> +#include <catch2/catch.hpp> +#include "common/bit_field.h" + +TEST_CASE("BitField", "[common]") { +    enum class TestEnum : u32 { +        A = 0b10111101, +        B = 0b10101110, +        C = 0b00001111, +    }; + +    union LEBitField { +        u32_le raw; +        BitField<0, 6, u32> a; +        BitField<6, 4, s32> b; +        BitField<10, 8, TestEnum> c; +        BitField<18, 14, u32> d; +    } le_bitfield; + +    union BEBitField { +        u32_be raw; +        BitFieldBE<0, 6, u32> a; +        BitFieldBE<6, 4, s32> b; +        BitFieldBE<10, 8, TestEnum> c; +        BitFieldBE<18, 14, u32> d; +    } be_bitfield; + +    static_assert(sizeof(LEBitField) == sizeof(u32)); +    static_assert(sizeof(BEBitField) == sizeof(u32)); +    static_assert(std::is_trivially_copyable_v<LEBitField>); +    static_assert(std::is_trivially_copyable_v<BEBitField>); + +    std::array<u8, 4> raw{{ +        0b01101100, +        0b11110110, +        0b10111010, +        0b11101100, +    }}; + +    std::memcpy(&le_bitfield, &raw, sizeof(raw)); +    std::memcpy(&be_bitfield, &raw, sizeof(raw)); + +    // bit fields: 11101100101110'10111101'1001'101100 +    REQUIRE(le_bitfield.raw == 0b11101100'10111010'11110110'01101100); +    REQUIRE(le_bitfield.a == 0b101100); +    REQUIRE(le_bitfield.b == -7); // 1001 as two's complement +    REQUIRE(le_bitfield.c == TestEnum::A); +    REQUIRE(le_bitfield.d == 0b11101100101110); + +    le_bitfield.a.Assign(0b000111); +    le_bitfield.b.Assign(-1); +    le_bitfield.c.Assign(TestEnum::C); +    le_bitfield.d.Assign(0b01010101010101); +    std::memcpy(&raw, &le_bitfield, sizeof(raw)); +    // bit fields: 01010101010101'00001111'1111'000111 +    REQUIRE(le_bitfield.raw == 0b01010101'01010100'00111111'11000111); +    REQUIRE(raw == std::array<u8, 4>{{ +                       0b11000111, +                       0b00111111, +                       0b01010100, +                       0b01010101, +                   }}); + +    // bit fields: 01101100111101'10101110'1011'101100 +    REQUIRE(be_bitfield.raw == 0b01101100'11110110'10111010'11101100); +    REQUIRE(be_bitfield.a == 0b101100); +    REQUIRE(be_bitfield.b == -5); // 1011 as two's complement +    REQUIRE(be_bitfield.c == TestEnum::B); +    REQUIRE(be_bitfield.d == 0b01101100111101); + +    be_bitfield.a.Assign(0b000111); +    be_bitfield.b.Assign(-1); +    be_bitfield.c.Assign(TestEnum::C); +    be_bitfield.d.Assign(0b01010101010101); +    std::memcpy(&raw, &be_bitfield, sizeof(raw)); +    // bit fields: 01010101010101'00001111'1111'000111 +    REQUIRE(be_bitfield.raw == 0b01010101'01010100'00111111'11000111); +    REQUIRE(raw == std::array<u8, 4>{{ +                       0b01010101, +                       0b01010100, +                       0b00111111, +                       0b11000111, +                   }}); +} diff --git a/src/tests/common/bit_utils.cpp b/src/tests/common/bit_utils.cpp new file mode 100644 index 000000000..479b5995a --- /dev/null +++ b/src/tests/common/bit_utils.cpp @@ -0,0 +1,23 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <catch2/catch.hpp> +#include <math.h> +#include "common/bit_util.h" + +namespace Common { + +TEST_CASE("BitUtils::CountTrailingZeroes", "[common]") { +    REQUIRE(Common::CountTrailingZeroes32(0) == 32); +    REQUIRE(Common::CountTrailingZeroes64(0) == 64); +    REQUIRE(Common::CountTrailingZeroes32(9) == 0); +    REQUIRE(Common::CountTrailingZeroes32(8) == 3); +    REQUIRE(Common::CountTrailingZeroes32(0x801000) == 12); +    REQUIRE(Common::CountTrailingZeroes64(9) == 0); +    REQUIRE(Common::CountTrailingZeroes64(8) == 3); +    REQUIRE(Common::CountTrailingZeroes64(0x801000) == 12); +    REQUIRE(Common::CountTrailingZeroes64(0x801000000000UL) == 36); +} + +} // namespace Common diff --git a/src/tests/common/multi_level_queue.cpp b/src/tests/common/multi_level_queue.cpp new file mode 100644 index 000000000..cca7ec7da --- /dev/null +++ b/src/tests/common/multi_level_queue.cpp @@ -0,0 +1,55 @@ +// Copyright 2019 Yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <catch2/catch.hpp> +#include <math.h> +#include "common/common_types.h" +#include "common/multi_level_queue.h" + +namespace Common { + +TEST_CASE("MultiLevelQueue", "[common]") { +    std::array<f32, 8> values = {0.0, 5.0, 1.0, 9.0, 8.0, 2.0, 6.0, 7.0}; +    Common::MultiLevelQueue<f32, 64> mlq; +    REQUIRE(mlq.empty()); +    mlq.add(values[2], 2); +    mlq.add(values[7], 7); +    mlq.add(values[3], 3); +    mlq.add(values[4], 4); +    mlq.add(values[0], 0); +    mlq.add(values[5], 5); +    mlq.add(values[6], 6); +    mlq.add(values[1], 1); +    u32 index = 0; +    bool all_set = true; +    for (auto& f : mlq) { +        all_set &= (f == values[index]); +        index++; +    } +    REQUIRE(all_set); +    REQUIRE(!mlq.empty()); +    f32 v = 8.0; +    mlq.add(v, 2); +    v = -7.0; +    mlq.add(v, 2, false); +    REQUIRE(mlq.front(2) == -7.0); +    mlq.yield(2); +    REQUIRE(mlq.front(2) == values[2]); +    REQUIRE(mlq.back(2) == -7.0); +    REQUIRE(mlq.empty(8)); +    v = 10.0; +    mlq.add(v, 8); +    mlq.adjust(v, 8, 9); +    REQUIRE(mlq.front(9) == v); +    REQUIRE(mlq.empty(8)); +    REQUIRE(!mlq.empty(9)); +    mlq.adjust(values[0], 0, 9); +    REQUIRE(mlq.highest_priority_set() == 1); +    REQUIRE(mlq.lowest_priority_set() == 9); +    mlq.remove(values[1], 1); +    REQUIRE(mlq.highest_priority_set() == 2); +    REQUIRE(mlq.empty(1)); +} + +} // namespace Common diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index 9b8a44fa1..58af41f6e 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -4,6 +4,7 @@  #include <algorithm> +#include "common/page_table.h"  #include "core/core.h"  #include "core/hle/kernel/process.h"  #include "core/memory.h" @@ -13,21 +14,20 @@  namespace ArmTests {  TestEnvironment::TestEnvironment(bool mutable_memory_) -    : mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) { - -    auto process = Kernel::Process::Create(kernel, ""); -    kernel.MakeCurrentProcess(process.get()); -    page_table = &Core::CurrentProcess()->VMManager().page_table; +    : mutable_memory(mutable_memory_), +      test_memory(std::make_shared<TestMemory>(this)), kernel{Core::System::GetInstance()} { +    auto process = Kernel::Process::Create(Core::System::GetInstance(), ""); +    page_table = &process->VMManager().page_table;      std::fill(page_table->pointers.begin(), page_table->pointers.end(), nullptr);      page_table->special_regions.clear();      std::fill(page_table->attributes.begin(), page_table->attributes.end(), -              Memory::PageType::Unmapped); +              Common::PageType::Unmapped);      Memory::MapIoRegion(*page_table, 0x00000000, 0x80000000, test_memory);      Memory::MapIoRegion(*page_table, 0x80000000, 0x80000000, test_memory); -    Memory::SetCurrentPageTable(page_table); +    kernel.MakeCurrentProcess(process.get());  }  TestEnvironment::~TestEnvironment() { diff --git a/src/tests/core/arm/arm_test_common.h b/src/tests/core/arm/arm_test_common.h index 0b7539601..d145dbfcc 100644 --- a/src/tests/core/arm/arm_test_common.h +++ b/src/tests/core/arm/arm_test_common.h @@ -9,10 +9,10 @@  #include <vector>  #include "common/common_types.h" +#include "common/memory_hook.h"  #include "core/hle/kernel/kernel.h" -#include "core/memory_hook.h" -namespace Memory { +namespace Common {  struct PageTable;  } @@ -58,7 +58,7 @@ public:  private:      friend struct TestMemory; -    struct TestMemory final : Memory::MemoryHook { +    struct TestMemory final : Common::MemoryHook {          explicit TestMemory(TestEnvironment* env_) : env(env_) {}          TestEnvironment* env; @@ -86,7 +86,7 @@ private:      bool mutable_memory;      std::shared_ptr<TestMemory> test_memory;      std::vector<WriteRecord> write_records; -    Memory::PageTable* page_table = nullptr; +    Common::PageTable* page_table = nullptr;      Kernel::KernelCore kernel;  }; diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp index 2242c14cf..340d6a272 100644 --- a/src/tests/core/core_timing.cpp +++ b/src/tests/core/core_timing.cpp @@ -28,100 +28,103 @@ void CallbackTemplate(u64 userdata, s64 cycles_late) {      REQUIRE(lateness == cycles_late);  } -class ScopeInit final { -public: +struct ScopeInit final {      ScopeInit() { -        CoreTiming::Init(); +        core_timing.Initialize();      }      ~ScopeInit() { -        CoreTiming::Shutdown(); +        core_timing.Shutdown();      } + +    Core::Timing::CoreTiming core_timing;  }; -static void AdvanceAndCheck(u32 idx, int downcount, int expected_lateness = 0, -                            int cpu_downcount = 0) { +static void AdvanceAndCheck(Core::Timing::CoreTiming& core_timing, u32 idx, int downcount, +                            int expected_lateness = 0, int cpu_downcount = 0) {      callbacks_ran_flags = 0;      expected_callback = CB_IDS[idx];      lateness = expected_lateness; -    CoreTiming::AddTicks(CoreTiming::GetDowncount() - -                         cpu_downcount); // Pretend we executed X cycles of instructions. -    CoreTiming::Advance(); +    // Pretend we executed X cycles of instructions. +    core_timing.AddTicks(core_timing.GetDowncount() - cpu_downcount); +    core_timing.Advance();      REQUIRE(decltype(callbacks_ran_flags)().set(idx) == callbacks_ran_flags); -    REQUIRE(downcount == CoreTiming::GetDowncount()); +    REQUIRE(downcount == core_timing.GetDowncount());  }  TEST_CASE("CoreTiming[BasicOrder]", "[core]") {      ScopeInit guard; +    auto& core_timing = guard.core_timing; -    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>); +    Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>); +    Core::Timing::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>); +    Core::Timing::EventType* cb_c = core_timing.RegisterEvent("callbackC", CallbackTemplate<2>); +    Core::Timing::EventType* cb_d = core_timing.RegisterEvent("callbackD", CallbackTemplate<3>); +    Core::Timing::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]); -    REQUIRE(1000 == CoreTiming::GetDowncount()); -    CoreTiming::ScheduleEvent(500, cb_b, CB_IDS[1]); -    REQUIRE(500 == CoreTiming::GetDowncount()); -    CoreTiming::ScheduleEvent(800, cb_c, CB_IDS[2]); -    REQUIRE(500 == CoreTiming::GetDowncount()); -    CoreTiming::ScheduleEvent(100, cb_d, CB_IDS[3]); -    REQUIRE(100 == CoreTiming::GetDowncount()); -    CoreTiming::ScheduleEvent(1200, cb_e, CB_IDS[4]); -    REQUIRE(100 == CoreTiming::GetDowncount()); - -    AdvanceAndCheck(3, 400); -    AdvanceAndCheck(1, 300); -    AdvanceAndCheck(2, 200); -    AdvanceAndCheck(0, 200); -    AdvanceAndCheck(4, MAX_SLICE_LENGTH); +    core_timing.ScheduleEvent(1000, cb_a, CB_IDS[0]); +    REQUIRE(1000 == core_timing.GetDowncount()); +    core_timing.ScheduleEvent(500, cb_b, CB_IDS[1]); +    REQUIRE(500 == core_timing.GetDowncount()); +    core_timing.ScheduleEvent(800, cb_c, CB_IDS[2]); +    REQUIRE(500 == core_timing.GetDowncount()); +    core_timing.ScheduleEvent(100, cb_d, CB_IDS[3]); +    REQUIRE(100 == core_timing.GetDowncount()); +    core_timing.ScheduleEvent(1200, cb_e, CB_IDS[4]); +    REQUIRE(100 == core_timing.GetDowncount()); + +    AdvanceAndCheck(core_timing, 3, 400); +    AdvanceAndCheck(core_timing, 1, 300); +    AdvanceAndCheck(core_timing, 2, 200); +    AdvanceAndCheck(core_timing, 0, 200); +    AdvanceAndCheck(core_timing, 4, MAX_SLICE_LENGTH);  }  TEST_CASE("CoreTiming[Threadsave]", "[core]") {      ScopeInit guard; +    auto& core_timing = guard.core_timing; -    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>); +    Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>); +    Core::Timing::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>); +    Core::Timing::EventType* cb_c = core_timing.RegisterEvent("callbackC", CallbackTemplate<2>); +    Core::Timing::EventType* cb_d = core_timing.RegisterEvent("callbackD", CallbackTemplate<3>); +    Core::Timing::EventType* cb_e = core_timing.RegisterEvent("callbackE", CallbackTemplate<4>);      // Enter slice 0 -    CoreTiming::Advance(); +    core_timing.Advance();      // D -> B -> C -> A -> E -    CoreTiming::ScheduleEventThreadsafe(1000, cb_a, CB_IDS[0]); +    core_timing.ScheduleEventThreadsafe(1000, cb_a, CB_IDS[0]);      // Manually force since ScheduleEventThreadsafe doesn't call it -    CoreTiming::ForceExceptionCheck(1000); -    REQUIRE(1000 == CoreTiming::GetDowncount()); -    CoreTiming::ScheduleEventThreadsafe(500, cb_b, CB_IDS[1]); +    core_timing.ForceExceptionCheck(1000); +    REQUIRE(1000 == core_timing.GetDowncount()); +    core_timing.ScheduleEventThreadsafe(500, cb_b, CB_IDS[1]);      // Manually force since ScheduleEventThreadsafe doesn't call it -    CoreTiming::ForceExceptionCheck(500); -    REQUIRE(500 == CoreTiming::GetDowncount()); -    CoreTiming::ScheduleEventThreadsafe(800, cb_c, CB_IDS[2]); +    core_timing.ForceExceptionCheck(500); +    REQUIRE(500 == core_timing.GetDowncount()); +    core_timing.ScheduleEventThreadsafe(800, cb_c, CB_IDS[2]);      // Manually force since ScheduleEventThreadsafe doesn't call it -    CoreTiming::ForceExceptionCheck(800); -    REQUIRE(500 == CoreTiming::GetDowncount()); -    CoreTiming::ScheduleEventThreadsafe(100, cb_d, CB_IDS[3]); +    core_timing.ForceExceptionCheck(800); +    REQUIRE(500 == core_timing.GetDowncount()); +    core_timing.ScheduleEventThreadsafe(100, cb_d, CB_IDS[3]);      // Manually force since ScheduleEventThreadsafe doesn't call it -    CoreTiming::ForceExceptionCheck(100); -    REQUIRE(100 == CoreTiming::GetDowncount()); -    CoreTiming::ScheduleEventThreadsafe(1200, cb_e, CB_IDS[4]); +    core_timing.ForceExceptionCheck(100); +    REQUIRE(100 == core_timing.GetDowncount()); +    core_timing.ScheduleEventThreadsafe(1200, cb_e, CB_IDS[4]);      // Manually force since ScheduleEventThreadsafe doesn't call it -    CoreTiming::ForceExceptionCheck(1200); -    REQUIRE(100 == CoreTiming::GetDowncount()); - -    AdvanceAndCheck(3, 400); -    AdvanceAndCheck(1, 300); -    AdvanceAndCheck(2, 200); -    AdvanceAndCheck(0, 200); -    AdvanceAndCheck(4, MAX_SLICE_LENGTH); +    core_timing.ForceExceptionCheck(1200); +    REQUIRE(100 == core_timing.GetDowncount()); + +    AdvanceAndCheck(core_timing, 3, 400); +    AdvanceAndCheck(core_timing, 1, 300); +    AdvanceAndCheck(core_timing, 2, 200); +    AdvanceAndCheck(core_timing, 0, 200); +    AdvanceAndCheck(core_timing, 4, MAX_SLICE_LENGTH);  }  namespace SharedSlotTest { @@ -142,59 +145,63 @@ TEST_CASE("CoreTiming[SharedSlot]", "[core]") {      using namespace SharedSlotTest;      ScopeInit guard; +    auto& core_timing = guard.core_timing; -    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>); +    Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", FifoCallback<0>); +    Core::Timing::EventType* cb_b = core_timing.RegisterEvent("callbackB", FifoCallback<1>); +    Core::Timing::EventType* cb_c = core_timing.RegisterEvent("callbackC", FifoCallback<2>); +    Core::Timing::EventType* cb_d = core_timing.RegisterEvent("callbackD", FifoCallback<3>); +    Core::Timing::EventType* cb_e = core_timing.RegisterEvent("callbackE", FifoCallback<4>); -    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]); +    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(); -    REQUIRE(1000 == CoreTiming::GetDowncount()); +    core_timing.Advance(); +    REQUIRE(1000 == core_timing.GetDowncount());      callbacks_ran_flags = 0;      counter = 0;      lateness = 0; -    CoreTiming::AddTicks(CoreTiming::GetDowncount()); -    CoreTiming::Advance(); -    REQUIRE(MAX_SLICE_LENGTH == CoreTiming::GetDowncount()); +    core_timing.AddTicks(core_timing.GetDowncount()); +    core_timing.Advance(); +    REQUIRE(MAX_SLICE_LENGTH == core_timing.GetDowncount());      REQUIRE(0x1FULL == callbacks_ran_flags.to_ullong());  } -TEST_CASE("CoreTiming[PredictableLateness]", "[core]") { +TEST_CASE("Core::Timing[PredictableLateness]", "[core]") {      ScopeInit guard; +    auto& core_timing = guard.core_timing; -    CoreTiming::EventType* cb_a = CoreTiming::RegisterEvent("callbackA", CallbackTemplate<0>); -    CoreTiming::EventType* cb_b = CoreTiming::RegisterEvent("callbackB", CallbackTemplate<1>); +    Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>); +    Core::Timing::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); +    AdvanceAndCheck(core_timing, 0, 90, 10, -10); // (100 - 10) +    AdvanceAndCheck(core_timing, 1, MAX_SLICE_LENGTH, 50, -50);  }  namespace ChainSchedulingTest {  static int reschedules = 0; -static void RescheduleCallback(u64 userdata, s64 cycles_late) { +static void RescheduleCallback(Core::Timing::CoreTiming& core_timing, u64 userdata, +                               s64 cycles_late) {      --reschedules;      REQUIRE(reschedules >= 0);      REQUIRE(lateness == cycles_late); -    if (reschedules > 0) -        CoreTiming::ScheduleEvent(1000, reinterpret_cast<CoreTiming::EventType*>(userdata), +    if (reschedules > 0) { +        core_timing.ScheduleEvent(1000, reinterpret_cast<Core::Timing::EventType*>(userdata),                                    userdata); +    }  }  } // namespace ChainSchedulingTest @@ -202,36 +209,39 @@ TEST_CASE("CoreTiming[ChainScheduling]", "[core]") {      using namespace ChainSchedulingTest;      ScopeInit guard; +    auto& core_timing = guard.core_timing; -    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_rs = -        CoreTiming::RegisterEvent("callbackReschedule", RescheduleCallback); +    Core::Timing::EventType* cb_a = core_timing.RegisterEvent("callbackA", CallbackTemplate<0>); +    Core::Timing::EventType* cb_b = core_timing.RegisterEvent("callbackB", CallbackTemplate<1>); +    Core::Timing::EventType* cb_c = core_timing.RegisterEvent("callbackC", CallbackTemplate<2>); +    Core::Timing::EventType* cb_rs = core_timing.RegisterEvent( +        "callbackReschedule", [&core_timing](u64 userdata, s64 cycles_late) { +            RescheduleCallback(core_timing, userdata, cycles_late); +        });      // 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)); -    REQUIRE(800 == CoreTiming::GetDowncount()); +    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)); +    REQUIRE(800 == core_timing.GetDowncount());      reschedules = 3; -    AdvanceAndCheck(0, 200);  // cb_a -    AdvanceAndCheck(1, 1000); // cb_b, cb_rs +    AdvanceAndCheck(core_timing, 0, 200);  // cb_a +    AdvanceAndCheck(core_timing, 1, 1000); // cb_b, cb_rs      REQUIRE(2 == reschedules); -    CoreTiming::AddTicks(CoreTiming::GetDowncount()); -    CoreTiming::Advance(); // cb_rs +    core_timing.AddTicks(core_timing.GetDowncount()); +    core_timing.Advance(); // cb_rs      REQUIRE(1 == reschedules); -    REQUIRE(200 == CoreTiming::GetDowncount()); +    REQUIRE(200 == core_timing.GetDowncount()); -    AdvanceAndCheck(2, 800); // cb_c +    AdvanceAndCheck(core_timing, 2, 800); // cb_c -    CoreTiming::AddTicks(CoreTiming::GetDowncount()); -    CoreTiming::Advance(); // cb_rs +    core_timing.AddTicks(core_timing.GetDowncount()); +    core_timing.Advance(); // cb_rs      REQUIRE(0 == reschedules); -    REQUIRE(MAX_SLICE_LENGTH == CoreTiming::GetDowncount()); +    REQUIRE(MAX_SLICE_LENGTH == core_timing.GetDowncount());  } | 
