summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/stream.cpp13
-rw-r--r--src/audio_core/stream.h4
-rw-r--r--src/core/core_timing.cpp7
-rw-r--r--src/core/core_timing.h10
-rw-r--r--src/core/hardware_interrupt_manager.cpp13
-rw-r--r--src/core/hle/kernel/kernel.cpp2
-rw-r--r--src/core/hle/kernel/server_session.cpp2
-rw-r--r--src/core/hle/kernel/time_manager.cpp2
-rw-r--r--src/core/hle/service/hid/hid.cpp9
-rw-r--r--src/core/hle/service/hid/hid.h7
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp6
-rw-r--r--src/core/memory/cheat_engine.cpp13
-rw-r--r--src/core/memory/cheat_engine.h3
-rw-r--r--src/core/tools/freezer.cpp12
-rw-r--r--src/core/tools/freezer.h3
-rw-r--r--src/tests/core/core_timing.cpp14
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
44void Stream::Play() { 44void Stream::Play() {
@@ -78,7 +78,7 @@ static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) {
78 } 78 }
79} 79}
80 80
81void Stream::PlayNextBuffer(s64 cycles_late) { 81void 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
112void Stream::ReleaseActiveBuffer(s64 cycles_late) { 113void 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
119bool Stream::QueueBuffer(BufferPtr&& buffer) { 120bool 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
92private: 92private:
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
24namespace Core::Timing { 22namespace 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.
27using TimedCallback = std::function<void(u64 userdata, s64 cycles_late)>; 25using 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.
30struct EventType { 28struct 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 */
52class CoreTiming { 50class CoreTiming {
53public: 51public:
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 @@
11namespace Core::Hardware { 11namespace Core::Hardware {
12 12
13InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) { 13InterruptManager::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
22InterruptManager::~InterruptManager() = default; 23InterruptManager::~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
17TimeManager::TimeManager(Core::System& system_) : system{system_} { 17TimeManager::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
111void IAppletResource::UpdateControllers(u64 userdata, s64 ns_late) { 111void 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
126class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { 125class 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
13namespace Core::Timing { 12namespace 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
190void CheatEngine::Initialize() { 190void 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
218MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70)); 220MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70));
219 221
220void CheatEngine::FrameCallback(u64 userdata, s64 ns_late) { 222void 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
73private: 74private:
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
56Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_) 56Freezer::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
161void Freezer::FrameCallback(u64 userdata, s64 ns_late) { 162void 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
180void Freezer::FillEntryReads() { 180void 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
74private: 75private:
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 @@
17namespace { 18namespace {
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.
19constexpr std::array<u64, 5> CB_IDS{{42, 144, 93, 1026, UINT64_C(0xFFFF7FFFF7FFFF)}}; 20constexpr std::array<u64, 5> CB_IDS{{42, 144, 93, 1026, UINT64_C(0xFFFF7FFFF7FFFF)}};
20constexpr int MAX_SLICE_LENGTH = 10000; // Copied from CoreTiming internals
21constexpr std::array<u64, 5> calls_order{{2, 0, 1, 4, 3}}; 21constexpr std::array<u64, 5> calls_order{{2, 0, 1, 4, 3}};
22std::array<s64, 5> delays{}; 22std::array<s64, 5> delays{};
23 23
@@ -25,12 +25,12 @@ std::bitset<CB_IDS.size()> callbacks_ran_flags;
25u64 expected_callback = 0; 25u64 expected_callback = 0;
26 26
27template <unsigned int IDX> 27template <unsigned int IDX>
28void HostCallbackTemplate(u64 userdata, s64 nanoseconds_late) { 28void 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());