summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/device/device_session.cpp4
-rw-r--r--src/core/core_timing.cpp48
-rw-r--r--src/core/core_timing.h27
-rw-r--r--src/core/hle/kernel/k_hardware_timer.cpp19
-rw-r--r--src/core/hle/kernel/kernel.cpp2
-rw-r--r--src/core/hle/service/hid/hidbus.cpp8
-rw-r--r--src/core/hle/service/hid/hidbus.h2
-rw-r--r--src/core/hle/service/hid/resource_manager.cpp42
-rw-r--r--src/core/hle/service/hid/resource_manager.h8
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.cpp8
-rw-r--r--src/core/memory/cheat_engine.cpp8
-rw-r--r--src/core/memory/cheat_engine.h2
-rw-r--r--src/core/tools/freezer.cpp17
-rw-r--r--src/core/tools/freezer.h2
-rw-r--r--src/tests/core/core_timing.cpp14
15 files changed, 101 insertions, 110 deletions
diff --git a/src/audio_core/device/device_session.cpp b/src/audio_core/device/device_session.cpp
index c41d9d1ea..ee42ae529 100644
--- a/src/audio_core/device/device_session.cpp
+++ b/src/audio_core/device/device_session.cpp
@@ -18,9 +18,7 @@ constexpr auto INCREMENT_TIME{5ms};
18DeviceSession::DeviceSession(Core::System& system_) 18DeviceSession::DeviceSession(Core::System& system_)
19 : system{system_}, thread_event{Core::Timing::CreateEvent( 19 : system{system_}, thread_event{Core::Timing::CreateEvent(
20 "AudioOutSampleTick", 20 "AudioOutSampleTick",
21 [this](std::uintptr_t, s64 time, std::chrono::nanoseconds) { 21 [this](s64 time, std::chrono::nanoseconds) { return ThreadFunc(); })} {}
22 return ThreadFunc();
23 })} {}
24 22
25DeviceSession::~DeviceSession() { 23DeviceSession::~DeviceSession() {
26 Finalize(); 24 Finalize();
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index d6b5abc68..fc536413b 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -29,7 +29,6 @@ std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callbac
29struct CoreTiming::Event { 29struct CoreTiming::Event {
30 s64 time; 30 s64 time;
31 u64 fifo_order; 31 u64 fifo_order;
32 std::uintptr_t user_data;
33 std::weak_ptr<EventType> type; 32 std::weak_ptr<EventType> type;
34 s64 reschedule_time; 33 s64 reschedule_time;
35 heap_t::handle_type handle{}; 34 heap_t::handle_type handle{};
@@ -67,17 +66,15 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
67 event_fifo_id = 0; 66 event_fifo_id = 0;
68 shutting_down = false; 67 shutting_down = false;
69 cpu_ticks = 0; 68 cpu_ticks = 0;
70 const auto empty_timed_callback = [](std::uintptr_t, u64, std::chrono::nanoseconds)
71 -> std::optional<std::chrono::nanoseconds> { return std::nullopt; };
72 ev_lost = CreateEvent("_lost_event", empty_timed_callback);
73 if (is_multicore) { 69 if (is_multicore) {
74 timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this)); 70 timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this));
75 } 71 }
76} 72}
77 73
78void CoreTiming::ClearPendingEvents() { 74void CoreTiming::ClearPendingEvents() {
79 std::scoped_lock lock{basic_lock}; 75 std::scoped_lock lock{advance_lock, basic_lock};
80 event_queue.clear(); 76 event_queue.clear();
77 event.Set();
81} 78}
82 79
83void CoreTiming::Pause(bool is_paused) { 80void CoreTiming::Pause(bool is_paused) {
@@ -119,14 +116,12 @@ bool CoreTiming::HasPendingEvents() const {
119} 116}
120 117
121void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, 118void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
122 const std::shared_ptr<EventType>& event_type, 119 const std::shared_ptr<EventType>& event_type, bool absolute_time) {
123 std::uintptr_t user_data, bool absolute_time) {
124 { 120 {
125 std::scoped_lock scope{basic_lock}; 121 std::scoped_lock scope{basic_lock};
126 const auto next_time{absolute_time ? ns_into_future : GetGlobalTimeNs() + ns_into_future}; 122 const auto next_time{absolute_time ? ns_into_future : GetGlobalTimeNs() + ns_into_future};
127 123
128 auto h{event_queue.emplace( 124 auto h{event_queue.emplace(Event{next_time.count(), event_fifo_id++, event_type, 0})};
129 Event{next_time.count(), event_fifo_id++, user_data, event_type, 0})};
130 (*h).handle = h; 125 (*h).handle = h;
131 } 126 }
132 127
@@ -136,13 +131,13 @@ void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
136void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time, 131void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
137 std::chrono::nanoseconds resched_time, 132 std::chrono::nanoseconds resched_time,
138 const std::shared_ptr<EventType>& event_type, 133 const std::shared_ptr<EventType>& event_type,
139 std::uintptr_t user_data, bool absolute_time) { 134 bool absolute_time) {
140 { 135 {
141 std::scoped_lock scope{basic_lock}; 136 std::scoped_lock scope{basic_lock};
142 const auto next_time{absolute_time ? start_time : GetGlobalTimeNs() + start_time}; 137 const auto next_time{absolute_time ? start_time : GetGlobalTimeNs() + start_time};
143 138
144 auto h{event_queue.emplace(Event{next_time.count(), event_fifo_id++, user_data, event_type, 139 auto h{event_queue.emplace(
145 resched_time.count()})}; 140 Event{next_time.count(), event_fifo_id++, event_type, resched_time.count()})};
146 (*h).handle = h; 141 (*h).handle = h;
147 } 142 }
148 143
@@ -150,14 +145,14 @@ void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
150} 145}
151 146
152void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, 147void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
153 std::uintptr_t user_data, bool wait) { 148 UnscheduleEventType type) {
154 { 149 {
155 std::scoped_lock lk{basic_lock}; 150 std::scoped_lock lk{basic_lock};
156 151
157 std::vector<heap_t::handle_type> to_remove; 152 std::vector<heap_t::handle_type> to_remove;
158 for (auto itr = event_queue.begin(); itr != event_queue.end(); itr++) { 153 for (auto itr = event_queue.begin(); itr != event_queue.end(); itr++) {
159 const Event& e = *itr; 154 const Event& e = *itr;
160 if (e.type.lock().get() == event_type.get() && e.user_data == user_data) { 155 if (e.type.lock().get() == event_type.get()) {
161 to_remove.push_back(itr->handle); 156 to_remove.push_back(itr->handle);
162 } 157 }
163 } 158 }
@@ -165,10 +160,12 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
165 for (auto h : to_remove) { 160 for (auto h : to_remove) {
166 event_queue.erase(h); 161 event_queue.erase(h);
167 } 162 }
163
164 event_type->sequence_number++;
168 } 165 }
169 166
170 // Force any in-progress events to finish 167 // Force any in-progress events to finish
171 if (wait) { 168 if (type == UnscheduleEventType::Wait) {
172 std::scoped_lock lk{advance_lock}; 169 std::scoped_lock lk{advance_lock};
173 } 170 }
174} 171}
@@ -208,28 +205,31 @@ std::optional<s64> CoreTiming::Advance() {
208 const Event& evt = event_queue.top(); 205 const Event& evt = event_queue.top();
209 206
210 if (const auto event_type{evt.type.lock()}) { 207 if (const auto event_type{evt.type.lock()}) {
211 if (evt.reschedule_time == 0) { 208 const auto evt_time = evt.time;
212 const auto evt_user_data = evt.user_data; 209 const auto evt_sequence_num = event_type->sequence_number;
213 const auto evt_time = evt.time;
214 210
211 if (evt.reschedule_time == 0) {
215 event_queue.pop(); 212 event_queue.pop();
216 213
217 basic_lock.unlock(); 214 basic_lock.unlock();
218 215
219 event_type->callback( 216 event_type->callback(
220 evt_user_data, evt_time, 217 evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time});
221 std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time});
222 218
223 basic_lock.lock(); 219 basic_lock.lock();
224 } else { 220 } else {
225 basic_lock.unlock(); 221 basic_lock.unlock();
226 222
227 const auto new_schedule_time{event_type->callback( 223 const auto new_schedule_time{event_type->callback(
228 evt.user_data, evt.time, 224 evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time})};
229 std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt.time})};
230 225
231 basic_lock.lock(); 226 basic_lock.lock();
232 227
228 if (evt_sequence_num != event_type->sequence_number) {
229 // Heap handle is invalidated after external modification.
230 continue;
231 }
232
233 const auto next_schedule_time{new_schedule_time.has_value() 233 const auto next_schedule_time{new_schedule_time.has_value()
234 ? new_schedule_time.value().count() 234 ? new_schedule_time.value().count()
235 : evt.reschedule_time}; 235 : evt.reschedule_time};
@@ -241,8 +241,8 @@ std::optional<s64> CoreTiming::Advance() {
241 next_time = pause_end_time + next_schedule_time; 241 next_time = pause_end_time + next_schedule_time;
242 } 242 }
243 243
244 event_queue.update(evt.handle, Event{next_time, event_fifo_id++, evt.user_data, 244 event_queue.update(evt.handle, Event{next_time, event_fifo_id++, evt.type,
245 evt.type, next_schedule_time, evt.handle}); 245 next_schedule_time, evt.handle});
246 } 246 }
247 } 247 }
248 248
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 21548f0a9..7e4dff7f3 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -22,17 +22,25 @@ namespace Core::Timing {
22 22
23/// A callback that may be scheduled for a particular core timing event. 23/// A callback that may be scheduled for a particular core timing event.
24using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>( 24using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>(
25 std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)>; 25 s64 time, std::chrono::nanoseconds ns_late)>;
26 26
27/// Contains the characteristics of a particular event. 27/// Contains the characteristics of a particular event.
28struct EventType { 28struct EventType {
29 explicit EventType(TimedCallback&& callback_, std::string&& name_) 29 explicit EventType(TimedCallback&& callback_, std::string&& name_)
30 : callback{std::move(callback_)}, name{std::move(name_)} {} 30 : callback{std::move(callback_)}, name{std::move(name_)}, sequence_number{0} {}
31 31
32 /// The event's callback function. 32 /// The event's callback function.
33 TimedCallback callback; 33 TimedCallback callback;
34 /// A pointer to the name of the event. 34 /// A pointer to the name of the event.
35 const std::string name; 35 const std::string name;
36 /// A monotonic sequence number, incremented when this event is
37 /// changed externally.
38 size_t sequence_number;
39};
40
41enum class UnscheduleEventType {
42 Wait,
43 NoWait,
36}; 44};
37 45
38/** 46/**
@@ -89,23 +97,17 @@ public:
89 97
90 /// Schedules an event in core timing 98 /// Schedules an event in core timing
91 void ScheduleEvent(std::chrono::nanoseconds ns_into_future, 99 void ScheduleEvent(std::chrono::nanoseconds ns_into_future,
92 const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data = 0, 100 const std::shared_ptr<EventType>& event_type, bool absolute_time = false);
93 bool absolute_time = false);
94 101
95 /// Schedules an event which will automatically re-schedule itself with the given time, until 102 /// Schedules an event which will automatically re-schedule itself with the given time, until
96 /// unscheduled 103 /// unscheduled
97 void ScheduleLoopingEvent(std::chrono::nanoseconds start_time, 104 void ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
98 std::chrono::nanoseconds resched_time, 105 std::chrono::nanoseconds resched_time,
99 const std::shared_ptr<EventType>& event_type, 106 const std::shared_ptr<EventType>& event_type,
100 std::uintptr_t user_data = 0, bool absolute_time = false); 107 bool absolute_time = false);
101 108
102 void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data, 109 void UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
103 bool wait = true); 110 UnscheduleEventType type = UnscheduleEventType::Wait);
104
105 void UnscheduleEventWithoutWait(const std::shared_ptr<EventType>& event_type,
106 std::uintptr_t user_data) {
107 UnscheduleEvent(event_type, user_data, false);
108 }
109 111
110 void AddTicks(u64 ticks_to_add); 112 void AddTicks(u64 ticks_to_add);
111 113
@@ -158,7 +160,6 @@ private:
158 heap_t event_queue; 160 heap_t event_queue;
159 u64 event_fifo_id = 0; 161 u64 event_fifo_id = 0;
160 162
161 std::shared_ptr<EventType> ev_lost;
162 Common::Event event{}; 163 Common::Event event{};
163 Common::Event pause_event{}; 164 Common::Event pause_event{};
164 mutable std::mutex basic_lock; 165 mutable std::mutex basic_lock;
diff --git a/src/core/hle/kernel/k_hardware_timer.cpp b/src/core/hle/kernel/k_hardware_timer.cpp
index 8e2e40307..4e947dd6b 100644
--- a/src/core/hle/kernel/k_hardware_timer.cpp
+++ b/src/core/hle/kernel/k_hardware_timer.cpp
@@ -10,15 +10,15 @@ namespace Kernel {
10 10
11void KHardwareTimer::Initialize() { 11void KHardwareTimer::Initialize() {
12 // Create the timing callback to register with CoreTiming. 12 // Create the timing callback to register with CoreTiming.
13 m_event_type = Core::Timing::CreateEvent( 13 m_event_type = Core::Timing::CreateEvent("KHardwareTimer::Callback",
14 "KHardwareTimer::Callback", [](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) { 14 [this](s64, std::chrono::nanoseconds) {
15 reinterpret_cast<KHardwareTimer*>(timer_handle)->DoTask(); 15 this->DoTask();
16 return std::nullopt; 16 return std::nullopt;
17 }); 17 });
18} 18}
19 19
20void KHardwareTimer::Finalize() { 20void KHardwareTimer::Finalize() {
21 m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type, reinterpret_cast<uintptr_t>(this)); 21 m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type);
22 m_wakeup_time = std::numeric_limits<s64>::max(); 22 m_wakeup_time = std::numeric_limits<s64>::max();
23 m_event_type.reset(); 23 m_event_type.reset();
24} 24}
@@ -57,13 +57,12 @@ void KHardwareTimer::EnableInterrupt(s64 wakeup_time) {
57 57
58 m_wakeup_time = wakeup_time; 58 m_wakeup_time = wakeup_time;
59 m_kernel.System().CoreTiming().ScheduleEvent(std::chrono::nanoseconds{m_wakeup_time}, 59 m_kernel.System().CoreTiming().ScheduleEvent(std::chrono::nanoseconds{m_wakeup_time},
60 m_event_type, reinterpret_cast<uintptr_t>(this), 60 m_event_type, true);
61 true);
62} 61}
63 62
64void KHardwareTimer::DisableInterrupt() { 63void KHardwareTimer::DisableInterrupt() {
65 m_kernel.System().CoreTiming().UnscheduleEventWithoutWait(m_event_type, 64 m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type,
66 reinterpret_cast<uintptr_t>(this)); 65 Core::Timing::UnscheduleEventType::NoWait);
67 m_wakeup_time = std::numeric_limits<s64>::max(); 66 m_wakeup_time = std::numeric_limits<s64>::max();
68} 67}
69 68
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index c14d2d2f3..1030f0c12 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -238,7 +238,7 @@ struct KernelCore::Impl {
238 void InitializePreemption(KernelCore& kernel) { 238 void InitializePreemption(KernelCore& kernel) {
239 preemption_event = Core::Timing::CreateEvent( 239 preemption_event = Core::Timing::CreateEvent(
240 "PreemptionCallback", 240 "PreemptionCallback",
241 [this, &kernel](std::uintptr_t, s64 time, 241 [this, &kernel](s64 time,
242 std::chrono::nanoseconds) -> std::optional<std::chrono::nanoseconds> { 242 std::chrono::nanoseconds) -> std::optional<std::chrono::nanoseconds> {
243 { 243 {
244 KScopedSchedulerLock lock(kernel); 244 KScopedSchedulerLock lock(kernel);
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp
index d12f9beb0..ffa7e144d 100644
--- a/src/core/hle/service/hid/hidbus.cpp
+++ b/src/core/hle/service/hid/hidbus.cpp
@@ -49,10 +49,10 @@ HidBus::HidBus(Core::System& system_)
49 // Register update callbacks 49 // Register update callbacks
50 hidbus_update_event = Core::Timing::CreateEvent( 50 hidbus_update_event = Core::Timing::CreateEvent(
51 "Hidbus::UpdateCallback", 51 "Hidbus::UpdateCallback",
52 [this](std::uintptr_t user_data, s64 time, 52 [this](s64 time,
53 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { 53 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
54 const auto guard = LockService(); 54 const auto guard = LockService();
55 UpdateHidbus(user_data, ns_late); 55 UpdateHidbus(ns_late);
56 return std::nullopt; 56 return std::nullopt;
57 }); 57 });
58 58
@@ -61,10 +61,10 @@ HidBus::HidBus(Core::System& system_)
61} 61}
62 62
63HidBus::~HidBus() { 63HidBus::~HidBus() {
64 system.CoreTiming().UnscheduleEvent(hidbus_update_event, 0); 64 system.CoreTiming().UnscheduleEvent(hidbus_update_event);
65} 65}
66 66
67void HidBus::UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 67void HidBus::UpdateHidbus(std::chrono::nanoseconds ns_late) {
68 if (is_hidbus_enabled) { 68 if (is_hidbus_enabled) {
69 for (std::size_t i = 0; i < devices.size(); ++i) { 69 for (std::size_t i = 0; i < devices.size(); ++i) {
70 if (!devices[i].is_device_initializated) { 70 if (!devices[i].is_device_initializated) {
diff --git a/src/core/hle/service/hid/hidbus.h b/src/core/hle/service/hid/hidbus.h
index c29b5e882..85a1df133 100644
--- a/src/core/hle/service/hid/hidbus.h
+++ b/src/core/hle/service/hid/hidbus.h
@@ -108,7 +108,7 @@ private:
108 void DisableJoyPollingReceiveMode(HLERequestContext& ctx); 108 void DisableJoyPollingReceiveMode(HLERequestContext& ctx);
109 void SetStatusManagerType(HLERequestContext& ctx); 109 void SetStatusManagerType(HLERequestContext& ctx);
110 110
111 void UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 111 void UpdateHidbus(std::chrono::nanoseconds ns_late);
112 std::optional<std::size_t> GetDeviceIndexFromHandle(BusHandle handle) const; 112 std::optional<std::size_t> GetDeviceIndexFromHandle(BusHandle handle) const;
113 113
114 template <typename T> 114 template <typename T>
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp
index 6c6cbd802..afc61f70d 100644
--- a/src/core/hle/service/hid/resource_manager.cpp
+++ b/src/core/hle/service/hid/resource_manager.cpp
@@ -227,8 +227,7 @@ void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) {
227 applet_resource->EnableTouchScreen(aruid, is_enabled); 227 applet_resource->EnableTouchScreen(aruid, is_enabled);
228} 228}
229 229
230void ResourceManager::UpdateControllers(std::uintptr_t user_data, 230void ResourceManager::UpdateControllers(std::chrono::nanoseconds ns_late) {
231 std::chrono::nanoseconds ns_late) {
232 auto& core_timing = system.CoreTiming(); 231 auto& core_timing = system.CoreTiming();
233 debug_pad->OnUpdate(core_timing); 232 debug_pad->OnUpdate(core_timing);
234 digitizer->OnUpdate(core_timing); 233 digitizer->OnUpdate(core_timing);
@@ -241,20 +240,19 @@ void ResourceManager::UpdateControllers(std::uintptr_t user_data,
241 capture_button->OnUpdate(core_timing); 240 capture_button->OnUpdate(core_timing);
242} 241}
243 242
244void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 243void ResourceManager::UpdateNpad(std::chrono::nanoseconds ns_late) {
245 auto& core_timing = system.CoreTiming(); 244 auto& core_timing = system.CoreTiming();
246 npad->OnUpdate(core_timing); 245 npad->OnUpdate(core_timing);
247} 246}
248 247
249void ResourceManager::UpdateMouseKeyboard(std::uintptr_t user_data, 248void ResourceManager::UpdateMouseKeyboard(std::chrono::nanoseconds ns_late) {
250 std::chrono::nanoseconds ns_late) {
251 auto& core_timing = system.CoreTiming(); 249 auto& core_timing = system.CoreTiming();
252 mouse->OnUpdate(core_timing); 250 mouse->OnUpdate(core_timing);
253 debug_mouse->OnUpdate(core_timing); 251 debug_mouse->OnUpdate(core_timing);
254 keyboard->OnUpdate(core_timing); 252 keyboard->OnUpdate(core_timing);
255} 253}
256 254
257void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 255void ResourceManager::UpdateMotion(std::chrono::nanoseconds ns_late) {
258 auto& core_timing = system.CoreTiming(); 256 auto& core_timing = system.CoreTiming();
259 six_axis->OnUpdate(core_timing); 257 six_axis->OnUpdate(core_timing);
260 seven_six_axis->OnUpdate(core_timing); 258 seven_six_axis->OnUpdate(core_timing);
@@ -273,34 +271,34 @@ IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<Resource
273 // Register update callbacks 271 // Register update callbacks
274 npad_update_event = Core::Timing::CreateEvent( 272 npad_update_event = Core::Timing::CreateEvent(
275 "HID::UpdatePadCallback", 273 "HID::UpdatePadCallback",
276 [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) 274 [this, resource](
277 -> std::optional<std::chrono::nanoseconds> { 275 s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
278 const auto guard = LockService(); 276 const auto guard = LockService();
279 resource->UpdateNpad(user_data, ns_late); 277 resource->UpdateNpad(ns_late);
280 return std::nullopt; 278 return std::nullopt;
281 }); 279 });
282 default_update_event = Core::Timing::CreateEvent( 280 default_update_event = Core::Timing::CreateEvent(
283 "HID::UpdateDefaultCallback", 281 "HID::UpdateDefaultCallback",
284 [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) 282 [this, resource](
285 -> std::optional<std::chrono::nanoseconds> { 283 s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
286 const auto guard = LockService(); 284 const auto guard = LockService();
287 resource->UpdateControllers(user_data, ns_late); 285 resource->UpdateControllers(ns_late);
288 return std::nullopt; 286 return std::nullopt;
289 }); 287 });
290 mouse_keyboard_update_event = Core::Timing::CreateEvent( 288 mouse_keyboard_update_event = Core::Timing::CreateEvent(
291 "HID::UpdateMouseKeyboardCallback", 289 "HID::UpdateMouseKeyboardCallback",
292 [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) 290 [this, resource](
293 -> std::optional<std::chrono::nanoseconds> { 291 s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
294 const auto guard = LockService(); 292 const auto guard = LockService();
295 resource->UpdateMouseKeyboard(user_data, ns_late); 293 resource->UpdateMouseKeyboard(ns_late);
296 return std::nullopt; 294 return std::nullopt;
297 }); 295 });
298 motion_update_event = Core::Timing::CreateEvent( 296 motion_update_event = Core::Timing::CreateEvent(
299 "HID::UpdateMotionCallback", 297 "HID::UpdateMotionCallback",
300 [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) 298 [this, resource](
301 -> std::optional<std::chrono::nanoseconds> { 299 s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
302 const auto guard = LockService(); 300 const auto guard = LockService();
303 resource->UpdateMotion(user_data, ns_late); 301 resource->UpdateMotion(ns_late);
304 return std::nullopt; 302 return std::nullopt;
305 }); 303 });
306 304
@@ -314,10 +312,10 @@ IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<Resource
314} 312}
315 313
316IAppletResource::~IAppletResource() { 314IAppletResource::~IAppletResource() {
317 system.CoreTiming().UnscheduleEvent(npad_update_event, 0); 315 system.CoreTiming().UnscheduleEvent(npad_update_event);
318 system.CoreTiming().UnscheduleEvent(default_update_event, 0); 316 system.CoreTiming().UnscheduleEvent(default_update_event);
319 system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0); 317 system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event);
320 system.CoreTiming().UnscheduleEvent(motion_update_event, 0); 318 system.CoreTiming().UnscheduleEvent(motion_update_event);
321 resource_manager->FreeAppletResourceId(aruid); 319 resource_manager->FreeAppletResourceId(aruid);
322} 320}
323 321
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h
index 5ad7cb564..5a6596099 100644
--- a/src/core/hle/service/hid/resource_manager.h
+++ b/src/core/hle/service/hid/resource_manager.h
@@ -81,10 +81,10 @@ public:
81 void EnablePadInput(u64 aruid, bool is_enabled); 81 void EnablePadInput(u64 aruid, bool is_enabled);
82 void EnableTouchScreen(u64 aruid, bool is_enabled); 82 void EnableTouchScreen(u64 aruid, bool is_enabled);
83 83
84 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 84 void UpdateControllers(std::chrono::nanoseconds ns_late);
85 void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 85 void UpdateNpad(std::chrono::nanoseconds ns_late);
86 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 86 void UpdateMouseKeyboard(std::chrono::nanoseconds ns_late);
87 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 87 void UpdateMotion(std::chrono::nanoseconds ns_late);
88 88
89private: 89private:
90 Result CreateAppletResourceImpl(u64 aruid); 90 Result CreateAppletResourceImpl(u64 aruid);
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp
index 6352b09a9..aa8aaa2d9 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.cpp
+++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp
@@ -67,7 +67,7 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
67 // Schedule the screen composition events 67 // Schedule the screen composition events
68 multi_composition_event = Core::Timing::CreateEvent( 68 multi_composition_event = Core::Timing::CreateEvent(
69 "ScreenComposition", 69 "ScreenComposition",
70 [this](std::uintptr_t, s64 time, 70 [this](s64 time,
71 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { 71 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
72 vsync_signal.Set(); 72 vsync_signal.Set();
73 return std::chrono::nanoseconds(GetNextTicks()); 73 return std::chrono::nanoseconds(GetNextTicks());
@@ -75,7 +75,7 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
75 75
76 single_composition_event = Core::Timing::CreateEvent( 76 single_composition_event = Core::Timing::CreateEvent(
77 "ScreenComposition", 77 "ScreenComposition",
78 [this](std::uintptr_t, s64 time, 78 [this](s64 time,
79 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { 79 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
80 const auto lock_guard = Lock(); 80 const auto lock_guard = Lock();
81 Compose(); 81 Compose();
@@ -93,11 +93,11 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
93 93
94Nvnflinger::~Nvnflinger() { 94Nvnflinger::~Nvnflinger() {
95 if (system.IsMulticore()) { 95 if (system.IsMulticore()) {
96 system.CoreTiming().UnscheduleEvent(multi_composition_event, {}); 96 system.CoreTiming().UnscheduleEvent(multi_composition_event);
97 vsync_thread.request_stop(); 97 vsync_thread.request_stop();
98 vsync_signal.Set(); 98 vsync_signal.Set();
99 } else { 99 } else {
100 system.CoreTiming().UnscheduleEvent(single_composition_event, {}); 100 system.CoreTiming().UnscheduleEvent(single_composition_event);
101 } 101 }
102 102
103 ShutdownLayers(); 103 ShutdownLayers();
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 3fc4024dc..7bc5b5ae5 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -190,15 +190,15 @@ CheatEngine::CheatEngine(System& system_, std::vector<CheatEntry> cheats_,
190} 190}
191 191
192CheatEngine::~CheatEngine() { 192CheatEngine::~CheatEngine() {
193 core_timing.UnscheduleEvent(event, 0); 193 core_timing.UnscheduleEvent(event);
194} 194}
195 195
196void CheatEngine::Initialize() { 196void CheatEngine::Initialize() {
197 event = Core::Timing::CreateEvent( 197 event = Core::Timing::CreateEvent(
198 "CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id), 198 "CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id),
199 [this](std::uintptr_t user_data, s64 time, 199 [this](s64 time,
200 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { 200 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
201 FrameCallback(user_data, ns_late); 201 FrameCallback(ns_late);
202 return std::nullopt; 202 return std::nullopt;
203 }); 203 });
204 core_timing.ScheduleLoopingEvent(CHEAT_ENGINE_NS, CHEAT_ENGINE_NS, event); 204 core_timing.ScheduleLoopingEvent(CHEAT_ENGINE_NS, CHEAT_ENGINE_NS, event);
@@ -239,7 +239,7 @@ void CheatEngine::Reload(std::vector<CheatEntry> reload_cheats) {
239 239
240MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70)); 240MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70));
241 241
242void CheatEngine::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) { 242void CheatEngine::FrameCallback(std::chrono::nanoseconds ns_late) {
243 if (is_pending_reload.exchange(false)) { 243 if (is_pending_reload.exchange(false)) {
244 vm.LoadProgram(cheats); 244 vm.LoadProgram(cheats);
245 } 245 }
diff --git a/src/core/memory/cheat_engine.h b/src/core/memory/cheat_engine.h
index 284abdd28..ced2168d1 100644
--- a/src/core/memory/cheat_engine.h
+++ b/src/core/memory/cheat_engine.h
@@ -70,7 +70,7 @@ public:
70 void Reload(std::vector<CheatEntry> reload_cheats); 70 void Reload(std::vector<CheatEntry> reload_cheats);
71 71
72private: 72private:
73 void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 73 void FrameCallback(std::chrono::nanoseconds ns_late);
74 74
75 DmntCheatVm vm; 75 DmntCheatVm vm;
76 CheatProcessMetadata metadata; 76 CheatProcessMetadata metadata;
diff --git a/src/core/tools/freezer.cpp b/src/core/tools/freezer.cpp
index 98ebbbf32..9d42c726e 100644
--- a/src/core/tools/freezer.cpp
+++ b/src/core/tools/freezer.cpp
@@ -51,18 +51,17 @@ void MemoryWriteWidth(Core::Memory::Memory& memory, u32 width, VAddr addr, u64 v
51 51
52Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_) 52Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_)
53 : core_timing{core_timing_}, memory{memory_} { 53 : core_timing{core_timing_}, memory{memory_} {
54 event = Core::Timing::CreateEvent( 54 event = Core::Timing::CreateEvent("MemoryFreezer::FrameCallback",
55 "MemoryFreezer::FrameCallback", 55 [this](s64 time, std::chrono::nanoseconds ns_late)
56 [this](std::uintptr_t user_data, s64 time, 56 -> std::optional<std::chrono::nanoseconds> {
57 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { 57 FrameCallback(ns_late);
58 FrameCallback(user_data, ns_late); 58 return std::nullopt;
59 return std::nullopt; 59 });
60 });
61 core_timing.ScheduleEvent(memory_freezer_ns, event); 60 core_timing.ScheduleEvent(memory_freezer_ns, event);
62} 61}
63 62
64Freezer::~Freezer() { 63Freezer::~Freezer() {
65 core_timing.UnscheduleEvent(event, 0); 64 core_timing.UnscheduleEvent(event);
66} 65}
67 66
68void Freezer::SetActive(bool is_active) { 67void Freezer::SetActive(bool is_active) {
@@ -159,7 +158,7 @@ Freezer::Entries::const_iterator Freezer::FindEntry(VAddr address) const {
159 [address](const Entry& entry) { return entry.address == address; }); 158 [address](const Entry& entry) { return entry.address == address; });
160} 159}
161 160
162void Freezer::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) { 161void Freezer::FrameCallback(std::chrono::nanoseconds ns_late) {
163 if (!IsActive()) { 162 if (!IsActive()) {
164 LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events."); 163 LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events.");
165 return; 164 return;
diff --git a/src/core/tools/freezer.h b/src/core/tools/freezer.h
index 0d6df5217..2efbc11f3 100644
--- a/src/core/tools/freezer.h
+++ b/src/core/tools/freezer.h
@@ -77,7 +77,7 @@ private:
77 Entries::iterator FindEntry(VAddr address); 77 Entries::iterator FindEntry(VAddr address);
78 Entries::const_iterator FindEntry(VAddr address) const; 78 Entries::const_iterator FindEntry(VAddr address) const;
79 79
80 void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 80 void FrameCallback(std::chrono::nanoseconds ns_late);
81 void FillEntryReads(); 81 void FillEntryReads();
82 82
83 std::atomic_bool active{false}; 83 std::atomic_bool active{false};
diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp
index f08afbf9a..81898a1d3 100644
--- a/src/tests/core/core_timing.cpp
+++ b/src/tests/core/core_timing.cpp
@@ -16,20 +16,16 @@
16 16
17namespace { 17namespace {
18// Numbers are chosen randomly to make sure the correct one is given. 18// 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> calls_order{{2, 0, 1, 4, 3}}; 19constexpr std::array<u64, 5> calls_order{{2, 0, 1, 4, 3}};
21std::array<s64, 5> delays{}; 20std::array<s64, 5> delays{};
22 21std::bitset<5> callbacks_ran_flags;
23std::bitset<CB_IDS.size()> callbacks_ran_flags;
24u64 expected_callback = 0; 22u64 expected_callback = 0;
25 23
26template <unsigned int IDX> 24template <unsigned int IDX>
27std::optional<std::chrono::nanoseconds> HostCallbackTemplate(std::uintptr_t user_data, s64 time, 25std::optional<std::chrono::nanoseconds> HostCallbackTemplate(s64 time,
28 std::chrono::nanoseconds ns_late) { 26 std::chrono::nanoseconds ns_late) {
29 static_assert(IDX < CB_IDS.size(), "IDX out of range"); 27 static_assert(IDX < callbacks_ran_flags.size(), "IDX out of range");
30 callbacks_ran_flags.set(IDX); 28 callbacks_ran_flags.set(IDX);
31 REQUIRE(CB_IDS[IDX] == user_data);
32 REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]);
33 delays[IDX] = ns_late.count(); 29 delays[IDX] = ns_late.count();
34 ++expected_callback; 30 ++expected_callback;
35 return std::nullopt; 31 return std::nullopt;
@@ -76,7 +72,7 @@ TEST_CASE("CoreTiming[BasicOrder]", "[core]") {
76 const u64 order = calls_order[i]; 72 const u64 order = calls_order[i];
77 const auto future_ns = std::chrono::nanoseconds{static_cast<s64>(i * one_micro + 100)}; 73 const auto future_ns = std::chrono::nanoseconds{static_cast<s64>(i * one_micro + 100)};
78 74
79 core_timing.ScheduleEvent(future_ns, events[order], CB_IDS[order]); 75 core_timing.ScheduleEvent(future_ns, events[order]);
80 } 76 }
81 /// test pause 77 /// test pause
82 REQUIRE(callbacks_ran_flags.none()); 78 REQUIRE(callbacks_ran_flags.none());
@@ -118,7 +114,7 @@ TEST_CASE("CoreTiming[BasicOrderNoPausing]", "[core]") {
118 for (std::size_t i = 0; i < events.size(); i++) { 114 for (std::size_t i = 0; i < events.size(); i++) {
119 const u64 order = calls_order[i]; 115 const u64 order = calls_order[i];
120 const auto future_ns = std::chrono::nanoseconds{static_cast<s64>(i * one_micro + 100)}; 116 const auto future_ns = std::chrono::nanoseconds{static_cast<s64>(i * one_micro + 100)};
121 core_timing.ScheduleEvent(future_ns, events[order], CB_IDS[order]); 117 core_timing.ScheduleEvent(future_ns, events[order]);
122 } 118 }
123 119
124 const u64 end = core_timing.GetGlobalTimeNs().count(); 120 const u64 end = core_timing.GetGlobalTimeNs().count();