diff options
| author | 2020-07-15 19:14:21 -0400 | |
|---|---|---|
| committer | 2020-07-15 19:41:22 -0400 | |
| commit | bef1844a51a37c1c8dc531e67069ef00821ffa9c (patch) | |
| tree | 2e46f404c3f0baf1b854e1bea916c19469fe424a /src | |
| parent | core_timing: Make use of std::chrono with ScheduleEvent (diff) | |
| download | yuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.tar.gz yuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.tar.xz yuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.zip | |
core_timing: Make TimedCallback take std::chrono::nanoseconds
Enforces our desired time units directly with a concrete type.
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/stream.cpp | 13 | ||||
| -rw-r--r-- | src/audio_core/stream.h | 4 | ||||
| -rw-r--r-- | src/core/core_timing.cpp | 7 | ||||
| -rw-r--r-- | src/core/core_timing.h | 10 | ||||
| -rw-r--r-- | src/core/hardware_interrupt_manager.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/time_manager.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.h | 7 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 6 | ||||
| -rw-r--r-- | src/core/memory/cheat_engine.cpp | 13 | ||||
| -rw-r--r-- | src/core/memory/cheat_engine.h | 3 | ||||
| -rw-r--r-- | src/core/tools/freezer.cpp | 12 | ||||
| -rw-r--r-- | src/core/tools/freezer.h | 3 | ||||
| -rw-r--r-- | src/tests/core/core_timing.cpp | 14 |
16 files changed, 62 insertions, 58 deletions
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index abd8576e2..f80ab92e4 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp | |||
| @@ -38,7 +38,7 @@ Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format fo | |||
| 38 | sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { | 38 | sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { |
| 39 | 39 | ||
| 40 | release_event = Core::Timing::CreateEvent( | 40 | release_event = Core::Timing::CreateEvent( |
| 41 | name, [this](u64 userdata, s64 cycles_late) { ReleaseActiveBuffer(cycles_late); }); | 41 | name, [this](u64, std::chrono::nanoseconds ns_late) { ReleaseActiveBuffer(ns_late); }); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void Stream::Play() { | 44 | void Stream::Play() { |
| @@ -78,7 +78,7 @@ static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) { | |||
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | void Stream::PlayNextBuffer(s64 cycles_late) { | 81 | void Stream::PlayNextBuffer(std::chrono::nanoseconds ns_late) { |
| 82 | if (!IsPlaying()) { | 82 | if (!IsPlaying()) { |
| 83 | // Ensure we are in playing state before playing the next buffer | 83 | // Ensure we are in playing state before playing the next buffer |
| 84 | sink_stream.Flush(); | 84 | sink_stream.Flush(); |
| @@ -103,17 +103,18 @@ void Stream::PlayNextBuffer(s64 cycles_late) { | |||
| 103 | 103 | ||
| 104 | sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); | 104 | sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); |
| 105 | 105 | ||
| 106 | const auto time_stretch_delta = std::chrono::nanoseconds{ | 106 | const auto time_stretch_delta = Settings::values.enable_audio_stretching.GetValue() |
| 107 | Settings::values.enable_audio_stretching.GetValue() ? 0 : cycles_late}; | 107 | ? std::chrono::nanoseconds::zero() |
| 108 | : ns_late; | ||
| 108 | const auto future_time = GetBufferReleaseNS(*active_buffer) - time_stretch_delta; | 109 | const auto future_time = GetBufferReleaseNS(*active_buffer) - time_stretch_delta; |
| 109 | core_timing.ScheduleEvent(future_time, release_event, {}); | 110 | core_timing.ScheduleEvent(future_time, release_event, {}); |
| 110 | } | 111 | } |
| 111 | 112 | ||
| 112 | void Stream::ReleaseActiveBuffer(s64 cycles_late) { | 113 | void Stream::ReleaseActiveBuffer(std::chrono::nanoseconds ns_late) { |
| 113 | ASSERT(active_buffer); | 114 | ASSERT(active_buffer); |
| 114 | released_buffers.push(std::move(active_buffer)); | 115 | released_buffers.push(std::move(active_buffer)); |
| 115 | release_callback(); | 116 | release_callback(); |
| 116 | PlayNextBuffer(cycles_late); | 117 | PlayNextBuffer(ns_late); |
| 117 | } | 118 | } |
| 118 | 119 | ||
| 119 | bool Stream::QueueBuffer(BufferPtr&& buffer) { | 120 | bool Stream::QueueBuffer(BufferPtr&& buffer) { |
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h index 2febd647c..6437b8591 100644 --- a/src/audio_core/stream.h +++ b/src/audio_core/stream.h | |||
| @@ -91,10 +91,10 @@ public: | |||
| 91 | 91 | ||
| 92 | private: | 92 | private: |
| 93 | /// Plays the next queued buffer in the audio stream, starting playback if necessary | 93 | /// Plays the next queued buffer in the audio stream, starting playback if necessary |
| 94 | void PlayNextBuffer(s64 cycles_late = 0); | 94 | void PlayNextBuffer(std::chrono::nanoseconds ns_late = {}); |
| 95 | 95 | ||
| 96 | /// Releases the actively playing buffer, signalling that it has been completed | 96 | /// Releases the actively playing buffer, signalling that it has been completed |
| 97 | void ReleaseActiveBuffer(s64 cycles_late = 0); | 97 | void ReleaseActiveBuffer(std::chrono::nanoseconds ns_late = {}); |
| 98 | 98 | ||
| 99 | /// Gets the number of core cycles when the specified buffer will be released | 99 | /// Gets the number of core cycles when the specified buffer will be released |
| 100 | std::chrono::nanoseconds GetBufferReleaseNS(const Buffer& buffer) const; | 100 | std::chrono::nanoseconds GetBufferReleaseNS(const Buffer& buffer) const; |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index a5d084e08..b5feb3f24 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -58,7 +58,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) { | |||
| 58 | event_fifo_id = 0; | 58 | event_fifo_id = 0; |
| 59 | shutting_down = false; | 59 | shutting_down = false; |
| 60 | ticks = 0; | 60 | ticks = 0; |
| 61 | const auto empty_timed_callback = [](u64, s64) {}; | 61 | const auto empty_timed_callback = [](u64, std::chrono::nanoseconds) {}; |
| 62 | ev_lost = CreateEvent("_lost_event", empty_timed_callback); | 62 | ev_lost = CreateEvent("_lost_event", empty_timed_callback); |
| 63 | if (is_multicore) { | 63 | if (is_multicore) { |
| 64 | timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this)); | 64 | timer_thread = std::make_unique<std::thread>(ThreadEntry, std::ref(*this)); |
| @@ -195,8 +195,9 @@ std::optional<s64> CoreTiming::Advance() { | |||
| 195 | event_queue.pop_back(); | 195 | event_queue.pop_back(); |
| 196 | basic_lock.unlock(); | 196 | basic_lock.unlock(); |
| 197 | 197 | ||
| 198 | if (auto event_type{evt.type.lock()}) { | 198 | if (const auto event_type{evt.type.lock()}) { |
| 199 | event_type->callback(evt.userdata, global_timer - evt.time); | 199 | event_type->callback( |
| 200 | evt.userdata, std::chrono::nanoseconds{static_cast<s64>(global_timer - evt.time)}); | ||
| 200 | } | 201 | } |
| 201 | 202 | ||
| 202 | basic_lock.lock(); | 203 | basic_lock.lock(); |
diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 9b9f18daf..a21356a08 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h | |||
| @@ -17,14 +17,12 @@ | |||
| 17 | #include "common/common_types.h" | 17 | #include "common/common_types.h" |
| 18 | #include "common/spin_lock.h" | 18 | #include "common/spin_lock.h" |
| 19 | #include "common/thread.h" | 19 | #include "common/thread.h" |
| 20 | #include "common/threadsafe_queue.h" | ||
| 21 | #include "common/wall_clock.h" | 20 | #include "common/wall_clock.h" |
| 22 | #include "core/hardware_properties.h" | ||
| 23 | 21 | ||
| 24 | namespace Core::Timing { | 22 | namespace Core::Timing { |
| 25 | 23 | ||
| 26 | /// A callback that may be scheduled for a particular core timing event. | 24 | /// A callback that may be scheduled for a particular core timing event. |
| 27 | using TimedCallback = std::function<void(u64 userdata, s64 cycles_late)>; | 25 | using TimedCallback = std::function<void(u64 userdata, std::chrono::nanoseconds ns_late)>; |
| 28 | 26 | ||
| 29 | /// Contains the characteristics of a particular event. | 27 | /// Contains the characteristics of a particular event. |
| 30 | struct EventType { | 28 | struct EventType { |
| @@ -42,12 +40,12 @@ struct EventType { | |||
| 42 | * in main CPU clock cycles. | 40 | * in main CPU clock cycles. |
| 43 | * | 41 | * |
| 44 | * To schedule an event, you first have to register its type. This is where you pass in the | 42 | * To schedule an event, you first have to register its type. This is where you pass in the |
| 45 | * callback. You then schedule events using the type id you get back. | 43 | * callback. You then schedule events using the type ID you get back. |
| 46 | * | 44 | * |
| 47 | * The int cyclesLate that the callbacks get is how many cycles late it was. | 45 | * The s64 ns_late that the callbacks get is how many ns late it was. |
| 48 | * So to schedule a new event on a regular basis: | 46 | * So to schedule a new event on a regular basis: |
| 49 | * inside callback: | 47 | * inside callback: |
| 50 | * ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever") | 48 | * ScheduleEvent(period_in_ns - ns_late, callback, "whatever") |
| 51 | */ | 49 | */ |
| 52 | class CoreTiming { | 50 | class CoreTiming { |
| 53 | public: | 51 | public: |
diff --git a/src/core/hardware_interrupt_manager.cpp b/src/core/hardware_interrupt_manager.cpp index e7fd71e2e..efc1030c1 100644 --- a/src/core/hardware_interrupt_manager.cpp +++ b/src/core/hardware_interrupt_manager.cpp | |||
| @@ -11,12 +11,13 @@ | |||
| 11 | namespace Core::Hardware { | 11 | namespace Core::Hardware { |
| 12 | 12 | ||
| 13 | InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) { | 13 | InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) { |
| 14 | gpu_interrupt_event = Core::Timing::CreateEvent("GPUInterrupt", [this](u64 message, s64) { | 14 | gpu_interrupt_event = |
| 15 | auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv"); | 15 | Core::Timing::CreateEvent("GPUInterrupt", [this](u64 message, std::chrono::nanoseconds) { |
| 16 | const u32 syncpt = static_cast<u32>(message >> 32); | 16 | auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv"); |
| 17 | const u32 value = static_cast<u32>(message); | 17 | const u32 syncpt = static_cast<u32>(message >> 32); |
| 18 | nvdrv->SignalGPUInterruptSyncpt(syncpt, value); | 18 | const u32 value = static_cast<u32>(message); |
| 19 | }); | 19 | nvdrv->SignalGPUInterruptSyncpt(syncpt, value); |
| 20 | }); | ||
| 20 | } | 21 | } |
| 21 | 22 | ||
| 22 | InterruptManager::~InterruptManager() = default; | 23 | InterruptManager::~InterruptManager() = default; |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 35fb270b8..22fc34b10 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -144,7 +144,7 @@ struct KernelCore::Impl { | |||
| 144 | 144 | ||
| 145 | void InitializePreemption(KernelCore& kernel) { | 145 | void InitializePreemption(KernelCore& kernel) { |
| 146 | preemption_event = Core::Timing::CreateEvent( | 146 | preemption_event = Core::Timing::CreateEvent( |
| 147 | "PreemptionCallback", [this, &kernel](u64 userdata, s64 cycles_late) { | 147 | "PreemptionCallback", [this, &kernel](u64, std::chrono::nanoseconds) { |
| 148 | { | 148 | { |
| 149 | SchedulerLock lock(kernel); | 149 | SchedulerLock lock(kernel); |
| 150 | global_scheduler.PreemptThreads(); | 150 | global_scheduler.PreemptThreads(); |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 8c32f28b5..af22f4c33 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -34,7 +34,7 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern | |||
| 34 | std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(kernel)}; | 34 | std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(kernel)}; |
| 35 | 35 | ||
| 36 | session->request_event = Core::Timing::CreateEvent( | 36 | session->request_event = Core::Timing::CreateEvent( |
| 37 | name, [session](u64 userdata, s64 cycles_late) { session->CompleteSyncRequest(); }); | 37 | name, [session](u64, std::chrono::nanoseconds) { session->CompleteSyncRequest(); }); |
| 38 | session->name = std::move(name); | 38 | session->name = std::move(name); |
| 39 | session->parent = std::move(parent); | 39 | session->parent = std::move(parent); |
| 40 | 40 | ||
diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp index ebb1e5568..88b01b751 100644 --- a/src/core/hle/kernel/time_manager.cpp +++ b/src/core/hle/kernel/time_manager.cpp | |||
| @@ -16,7 +16,7 @@ namespace Kernel { | |||
| 16 | 16 | ||
| 17 | TimeManager::TimeManager(Core::System& system_) : system{system_} { | 17 | TimeManager::TimeManager(Core::System& system_) : system{system_} { |
| 18 | time_manager_event_type = Core::Timing::CreateEvent( | 18 | time_manager_event_type = Core::Timing::CreateEvent( |
| 19 | "Kernel::TimeManagerCallback", [this](u64 thread_handle, [[maybe_unused]] s64 cycles_late) { | 19 | "Kernel::TimeManagerCallback", [this](u64 thread_handle, std::chrono::nanoseconds) { |
| 20 | SchedulerLock lock(system.Kernel()); | 20 | SchedulerLock lock(system.Kernel()); |
| 21 | Handle proper_handle = static_cast<Handle>(thread_handle); | 21 | Handle proper_handle = static_cast<Handle>(thread_handle); |
| 22 | if (cancelled_events[proper_handle]) { | 22 | if (cancelled_events[proper_handle]) { |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 62c942eac..680290cbd 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -76,8 +76,8 @@ IAppletResource::IAppletResource(Core::System& system) | |||
| 76 | GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); | 76 | GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); |
| 77 | 77 | ||
| 78 | // Register update callbacks | 78 | // Register update callbacks |
| 79 | pad_update_event = | 79 | pad_update_event = Core::Timing::CreateEvent( |
| 80 | Core::Timing::CreateEvent("HID::UpdatePadCallback", [this](u64 userdata, s64 ns_late) { | 80 | "HID::UpdatePadCallback", [this](u64 userdata, std::chrono::nanoseconds ns_late) { |
| 81 | UpdateControllers(userdata, ns_late); | 81 | UpdateControllers(userdata, ns_late); |
| 82 | }); | 82 | }); |
| 83 | 83 | ||
| @@ -108,7 +108,7 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { | |||
| 108 | rb.PushCopyObjects(shared_mem); | 108 | rb.PushCopyObjects(shared_mem); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | void IAppletResource::UpdateControllers(u64 userdata, s64 ns_late) { | 111 | void IAppletResource::UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late) { |
| 112 | auto& core_timing = system.CoreTiming(); | 112 | auto& core_timing = system.CoreTiming(); |
| 113 | 113 | ||
| 114 | const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); | 114 | const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); |
| @@ -119,8 +119,7 @@ void IAppletResource::UpdateControllers(u64 userdata, s64 ns_late) { | |||
| 119 | controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); | 119 | controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | const auto future_ns = pad_update_ns - std::chrono::nanoseconds{ns_late}; | 122 | core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); |
| 123 | core_timing.ScheduleEvent(future_ns, pad_update_event); | ||
| 124 | } | 123 | } |
| 125 | 124 | ||
| 126 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { | 125 | class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 6fb048360..c6f0a2584 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -4,10 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "core/hle/service/hid/controllers/controller_base.h" | 7 | #include <chrono> |
| 8 | #include "core/hle/service/service.h" | ||
| 9 | 8 | ||
| 10 | #include "controllers/controller_base.h" | 9 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 11 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 12 | 11 | ||
| 13 | namespace Core::Timing { | 12 | namespace Core::Timing { |
| @@ -65,7 +64,7 @@ private: | |||
| 65 | } | 64 | } |
| 66 | 65 | ||
| 67 | void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); | 66 | void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); |
| 68 | void UpdateControllers(u64 userdata, s64 cycles_late); | 67 | void UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late); |
| 69 | 68 | ||
| 70 | std::shared_ptr<Kernel::SharedMemory> shared_mem; | 69 | std::shared_ptr<Kernel::SharedMemory> shared_mem; |
| 71 | 70 | ||
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 76672264d..789856118 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -66,13 +66,13 @@ NVFlinger::NVFlinger(Core::System& system) : system(system) { | |||
| 66 | guard = std::make_shared<std::mutex>(); | 66 | guard = std::make_shared<std::mutex>(); |
| 67 | 67 | ||
| 68 | // Schedule the screen composition events | 68 | // Schedule the screen composition events |
| 69 | composition_event = | 69 | composition_event = Core::Timing::CreateEvent( |
| 70 | Core::Timing::CreateEvent("ScreenComposition", [this](u64 userdata, s64 ns_late) { | 70 | "ScreenComposition", [this](u64, std::chrono::nanoseconds ns_late) { |
| 71 | Lock(); | 71 | Lock(); |
| 72 | Compose(); | 72 | Compose(); |
| 73 | 73 | ||
| 74 | const auto ticks = std::chrono::nanoseconds{GetNextTicks()}; | 74 | const auto ticks = std::chrono::nanoseconds{GetNextTicks()}; |
| 75 | const auto ticks_delta = ticks - std::chrono::nanoseconds{ns_late}; | 75 | const auto ticks_delta = ticks - ns_late; |
| 76 | const auto future_ns = std::max(std::chrono::nanoseconds::zero(), ticks_delta); | 76 | const auto future_ns = std::max(std::chrono::nanoseconds::zero(), ticks_delta); |
| 77 | 77 | ||
| 78 | this->system.CoreTiming().ScheduleEvent(future_ns, composition_event); | 78 | this->system.CoreTiming().ScheduleEvent(future_ns, composition_event); |
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index 09bf8c5cf..ced41b1fe 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp | |||
| @@ -188,9 +188,11 @@ CheatEngine::~CheatEngine() { | |||
| 188 | } | 188 | } |
| 189 | 189 | ||
| 190 | void CheatEngine::Initialize() { | 190 | void CheatEngine::Initialize() { |
| 191 | event = Core::Timing::CreateEvent( | 191 | event = Core::Timing::CreateEvent("CheatEngine::FrameCallback::" + |
| 192 | "CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id), | 192 | Common::HexToString(metadata.main_nso_build_id), |
| 193 | [this](u64 userdata, s64 ns_late) { FrameCallback(userdata, ns_late); }); | 193 | [this](u64 userdata, std::chrono::nanoseconds ns_late) { |
| 194 | FrameCallback(userdata, ns_late); | ||
| 195 | }); | ||
| 194 | core_timing.ScheduleEvent(CHEAT_ENGINE_NS, event); | 196 | core_timing.ScheduleEvent(CHEAT_ENGINE_NS, event); |
| 195 | 197 | ||
| 196 | metadata.process_id = system.CurrentProcess()->GetProcessID(); | 198 | metadata.process_id = system.CurrentProcess()->GetProcessID(); |
| @@ -217,7 +219,7 @@ void CheatEngine::Reload(std::vector<CheatEntry> cheats) { | |||
| 217 | 219 | ||
| 218 | MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70)); | 220 | MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70)); |
| 219 | 221 | ||
| 220 | void CheatEngine::FrameCallback(u64 userdata, s64 ns_late) { | 222 | void CheatEngine::FrameCallback(u64, std::chrono::nanoseconds ns_late) { |
| 221 | if (is_pending_reload.exchange(false)) { | 223 | if (is_pending_reload.exchange(false)) { |
| 222 | vm.LoadProgram(cheats); | 224 | vm.LoadProgram(cheats); |
| 223 | } | 225 | } |
| @@ -230,8 +232,7 @@ void CheatEngine::FrameCallback(u64 userdata, s64 ns_late) { | |||
| 230 | 232 | ||
| 231 | vm.Execute(metadata); | 233 | vm.Execute(metadata); |
| 232 | 234 | ||
| 233 | const auto future_ns = CHEAT_ENGINE_NS - std::chrono::nanoseconds{ns_late}; | 235 | core_timing.ScheduleEvent(CHEAT_ENGINE_NS - ns_late, event); |
| 234 | core_timing.ScheduleEvent(future_ns, event); | ||
| 235 | } | 236 | } |
| 236 | 237 | ||
| 237 | } // namespace Core::Memory | 238 | } // namespace Core::Memory |
diff --git a/src/core/memory/cheat_engine.h b/src/core/memory/cheat_engine.h index 2649423f8..d4068cf84 100644 --- a/src/core/memory/cheat_engine.h +++ b/src/core/memory/cheat_engine.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <atomic> | 7 | #include <atomic> |
| 8 | #include <chrono> | ||
| 8 | #include <memory> | 9 | #include <memory> |
| 9 | #include <vector> | 10 | #include <vector> |
| 10 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| @@ -71,7 +72,7 @@ public: | |||
| 71 | void Reload(std::vector<CheatEntry> cheats); | 72 | void Reload(std::vector<CheatEntry> cheats); |
| 72 | 73 | ||
| 73 | private: | 74 | private: |
| 74 | void FrameCallback(u64 userdata, s64 cycles_late); | 75 | void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late); |
| 75 | 76 | ||
| 76 | DmntCheatVm vm; | 77 | DmntCheatVm vm; |
| 77 | CheatProcessMetadata metadata; | 78 | CheatProcessMetadata metadata; |
diff --git a/src/core/tools/freezer.cpp b/src/core/tools/freezer.cpp index 5dc52d1c1..27b894b51 100644 --- a/src/core/tools/freezer.cpp +++ b/src/core/tools/freezer.cpp | |||
| @@ -55,9 +55,10 @@ void MemoryWriteWidth(Core::Memory::Memory& memory, u32 width, VAddr addr, u64 v | |||
| 55 | 55 | ||
| 56 | Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_) | 56 | Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_) |
| 57 | : core_timing{core_timing_}, memory{memory_} { | 57 | : core_timing{core_timing_}, memory{memory_} { |
| 58 | event = Core::Timing::CreateEvent( | 58 | event = Core::Timing::CreateEvent("MemoryFreezer::FrameCallback", |
| 59 | "MemoryFreezer::FrameCallback", | 59 | [this](u64 userdata, std::chrono::nanoseconds ns_late) { |
| 60 | [this](u64 userdata, s64 ns_late) { FrameCallback(userdata, ns_late); }); | 60 | FrameCallback(userdata, ns_late); |
| 61 | }); | ||
| 61 | core_timing.ScheduleEvent(memory_freezer_ns, event); | 62 | core_timing.ScheduleEvent(memory_freezer_ns, event); |
| 62 | } | 63 | } |
| 63 | 64 | ||
| @@ -158,7 +159,7 @@ std::vector<Freezer::Entry> Freezer::GetEntries() const { | |||
| 158 | return entries; | 159 | return entries; |
| 159 | } | 160 | } |
| 160 | 161 | ||
| 161 | void Freezer::FrameCallback(u64 userdata, s64 ns_late) { | 162 | void Freezer::FrameCallback(u64, std::chrono::nanoseconds ns_late) { |
| 162 | if (!IsActive()) { | 163 | if (!IsActive()) { |
| 163 | LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events."); | 164 | LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events."); |
| 164 | return; | 165 | return; |
| @@ -173,8 +174,7 @@ void Freezer::FrameCallback(u64 userdata, s64 ns_late) { | |||
| 173 | MemoryWriteWidth(memory, entry.width, entry.address, entry.value); | 174 | MemoryWriteWidth(memory, entry.width, entry.address, entry.value); |
| 174 | } | 175 | } |
| 175 | 176 | ||
| 176 | const auto future_ns = memory_freezer_ns - std::chrono::nanoseconds{ns_late}; | 177 | core_timing.ScheduleEvent(memory_freezer_ns - ns_late, event); |
| 177 | core_timing.ScheduleEvent(future_ns, event); | ||
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | void Freezer::FillEntryReads() { | 180 | void Freezer::FillEntryReads() { |
diff --git a/src/core/tools/freezer.h b/src/core/tools/freezer.h index 62fc6aa6c..8438783d5 100644 --- a/src/core/tools/freezer.h +++ b/src/core/tools/freezer.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <atomic> | 7 | #include <atomic> |
| 8 | #include <chrono> | ||
| 8 | #include <memory> | 9 | #include <memory> |
| 9 | #include <mutex> | 10 | #include <mutex> |
| 10 | #include <optional> | 11 | #include <optional> |
| @@ -72,7 +73,7 @@ public: | |||
| 72 | std::vector<Entry> GetEntries() const; | 73 | std::vector<Entry> GetEntries() const; |
| 73 | 74 | ||
| 74 | private: | 75 | private: |
| 75 | void FrameCallback(u64 userdata, s64 cycles_late); | 76 | void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late); |
| 76 | void FillEntryReads(); | 77 | void FillEntryReads(); |
| 77 | 78 | ||
| 78 | std::atomic_bool active{false}; | 79 | std::atomic_bool active{false}; |
diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp index 4ede1bc2e..244463a47 100644 --- a/src/tests/core/core_timing.cpp +++ b/src/tests/core/core_timing.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <bitset> | 8 | #include <bitset> |
| 9 | #include <chrono> | ||
| 9 | #include <cstdlib> | 10 | #include <cstdlib> |
| 10 | #include <memory> | 11 | #include <memory> |
| 11 | #include <string> | 12 | #include <string> |
| @@ -17,7 +18,6 @@ | |||
| 17 | namespace { | 18 | namespace { |
| 18 | // Numbers are chosen randomly to make sure the correct one is given. | 19 | // Numbers are chosen randomly to make sure the correct one is given. |
| 19 | constexpr std::array<u64, 5> CB_IDS{{42, 144, 93, 1026, UINT64_C(0xFFFF7FFFF7FFFF)}}; | 20 | constexpr std::array<u64, 5> CB_IDS{{42, 144, 93, 1026, UINT64_C(0xFFFF7FFFF7FFFF)}}; |
| 20 | constexpr int MAX_SLICE_LENGTH = 10000; // Copied from CoreTiming internals | ||
| 21 | constexpr std::array<u64, 5> calls_order{{2, 0, 1, 4, 3}}; | 21 | constexpr std::array<u64, 5> calls_order{{2, 0, 1, 4, 3}}; |
| 22 | std::array<s64, 5> delays{}; | 22 | std::array<s64, 5> delays{}; |
| 23 | 23 | ||
| @@ -25,12 +25,12 @@ std::bitset<CB_IDS.size()> callbacks_ran_flags; | |||
| 25 | u64 expected_callback = 0; | 25 | u64 expected_callback = 0; |
| 26 | 26 | ||
| 27 | template <unsigned int IDX> | 27 | template <unsigned int IDX> |
| 28 | void HostCallbackTemplate(u64 userdata, s64 nanoseconds_late) { | 28 | void HostCallbackTemplate(u64 userdata, std::chrono::nanoseconds ns_late) { |
| 29 | static_assert(IDX < CB_IDS.size(), "IDX out of range"); | 29 | static_assert(IDX < CB_IDS.size(), "IDX out of range"); |
| 30 | callbacks_ran_flags.set(IDX); | 30 | callbacks_ran_flags.set(IDX); |
| 31 | REQUIRE(CB_IDS[IDX] == userdata); | 31 | REQUIRE(CB_IDS[IDX] == userdata); |
| 32 | REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]); | 32 | REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]); |
| 33 | delays[IDX] = nanoseconds_late; | 33 | delays[IDX] = ns_late.count(); |
| 34 | ++expected_callback; | 34 | ++expected_callback; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| @@ -77,10 +77,12 @@ TEST_CASE("CoreTiming[BasicOrder]", "[core]") { | |||
| 77 | 77 | ||
| 78 | core_timing.SyncPause(true); | 78 | core_timing.SyncPause(true); |
| 79 | 79 | ||
| 80 | u64 one_micro = 1000U; | 80 | const u64 one_micro = 1000U; |
| 81 | for (std::size_t i = 0; i < events.size(); i++) { | 81 | for (std::size_t i = 0; i < events.size(); i++) { |
| 82 | u64 order = calls_order[i]; | 82 | const u64 order = calls_order[i]; |
| 83 | core_timing.ScheduleEvent(i * one_micro + 100U, events[order], CB_IDS[order]); | 83 | const auto future_ns = std::chrono::nanoseconds{static_cast<s64>(i * one_micro + 100)}; |
| 84 | |||
| 85 | core_timing.ScheduleEvent(future_ns, events[order], CB_IDS[order]); | ||
| 84 | } | 86 | } |
| 85 | /// test pause | 87 | /// test pause |
| 86 | REQUIRE(callbacks_ran_flags.none()); | 88 | REQUIRE(callbacks_ran_flags.none()); |