Merge pull request #12454 from liamwhite/ct-stuff

core_timing: minor refactors
This commit is contained in:
Narr the Reg 2024-01-01 13:56:31 -06:00 committed by GitHub
commit aa9ff2ffc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 101 additions and 110 deletions

View file

@ -18,9 +18,7 @@ constexpr auto INCREMENT_TIME{5ms};
DeviceSession::DeviceSession(Core::System& system_) DeviceSession::DeviceSession(Core::System& system_)
: system{system_}, thread_event{Core::Timing::CreateEvent( : system{system_}, thread_event{Core::Timing::CreateEvent(
"AudioOutSampleTick", "AudioOutSampleTick",
[this](std::uintptr_t, s64 time, std::chrono::nanoseconds) { [this](s64 time, std::chrono::nanoseconds) { return ThreadFunc(); })} {}
return ThreadFunc();
})} {}
DeviceSession::~DeviceSession() { DeviceSession::~DeviceSession() {
Finalize(); Finalize();

View file

@ -29,7 +29,6 @@ std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callbac
struct CoreTiming::Event { struct CoreTiming::Event {
s64 time; s64 time;
u64 fifo_order; u64 fifo_order;
std::uintptr_t user_data;
std::weak_ptr<EventType> type; std::weak_ptr<EventType> type;
s64 reschedule_time; s64 reschedule_time;
heap_t::handle_type handle{}; heap_t::handle_type handle{};
@ -67,17 +66,15 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
event_fifo_id = 0; event_fifo_id = 0;
shutting_down = false; shutting_down = false;
cpu_ticks = 0; cpu_ticks = 0;
const auto empty_timed_callback = [](std::uintptr_t, u64, std::chrono::nanoseconds)
-> std::optional<std::chrono::nanoseconds> { return std::nullopt; };
ev_lost = CreateEvent("_lost_event", empty_timed_callback);
if (is_multicore) { if (is_multicore) {
timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this)); timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this));
} }
} }
void CoreTiming::ClearPendingEvents() { void CoreTiming::ClearPendingEvents() {
std::scoped_lock lock{basic_lock}; std::scoped_lock lock{advance_lock, basic_lock};
event_queue.clear(); event_queue.clear();
event.Set();
} }
void CoreTiming::Pause(bool is_paused) { void CoreTiming::Pause(bool is_paused) {
@ -119,14 +116,12 @@ bool CoreTiming::HasPendingEvents() const {
} }
void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
const std::shared_ptr<EventType>& event_type, const std::shared_ptr<EventType>& event_type, bool absolute_time) {
std::uintptr_t user_data, bool absolute_time) {
{ {
std::scoped_lock scope{basic_lock}; std::scoped_lock scope{basic_lock};
const auto next_time{absolute_time ? ns_into_future : GetGlobalTimeNs() + ns_into_future}; const auto next_time{absolute_time ? ns_into_future : GetGlobalTimeNs() + ns_into_future};
auto h{event_queue.emplace( auto h{event_queue.emplace(Event{next_time.count(), event_fifo_id++, event_type, 0})};
Event{next_time.count(), event_fifo_id++, user_data, event_type, 0})};
(*h).handle = h; (*h).handle = h;
} }
@ -136,13 +131,13 @@ void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time, void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
std::chrono::nanoseconds resched_time, std::chrono::nanoseconds resched_time,
const std::shared_ptr<EventType>& event_type, const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data, bool absolute_time) { bool absolute_time) {
{ {
std::scoped_lock scope{basic_lock}; std::scoped_lock scope{basic_lock};
const auto next_time{absolute_time ? start_time : GetGlobalTimeNs() + start_time}; const auto next_time{absolute_time ? start_time : GetGlobalTimeNs() + start_time};
auto h{event_queue.emplace(Event{next_time.count(), event_fifo_id++, user_data, event_type, auto h{event_queue.emplace(
resched_time.count()})}; Event{next_time.count(), event_fifo_id++, event_type, resched_time.count()})};
(*h).handle = h; (*h).handle = h;
} }
@ -150,14 +145,14 @@ void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
} }
void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data, bool wait) { UnscheduleEventType type) {
{ {
std::scoped_lock lk{basic_lock}; std::scoped_lock lk{basic_lock};
std::vector<heap_t::handle_type> to_remove; std::vector<heap_t::handle_type> to_remove;
for (auto itr = event_queue.begin(); itr != event_queue.end(); itr++) { for (auto itr = event_queue.begin(); itr != event_queue.end(); itr++) {
const Event& e = *itr; const Event& e = *itr;
if (e.type.lock().get() == event_type.get() && e.user_data == user_data) { if (e.type.lock().get() == event_type.get()) {
to_remove.push_back(itr->handle); to_remove.push_back(itr->handle);
} }
} }
@ -165,10 +160,12 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
for (auto h : to_remove) { for (auto h : to_remove) {
event_queue.erase(h); event_queue.erase(h);
} }
event_type->sequence_number++;
} }
// Force any in-progress events to finish // Force any in-progress events to finish
if (wait) { if (type == UnscheduleEventType::Wait) {
std::scoped_lock lk{advance_lock}; std::scoped_lock lk{advance_lock};
} }
} }
@ -208,28 +205,31 @@ std::optional<s64> CoreTiming::Advance() {
const Event& evt = event_queue.top(); const Event& evt = event_queue.top();
if (const auto event_type{evt.type.lock()}) { if (const auto event_type{evt.type.lock()}) {
if (evt.reschedule_time == 0) {
const auto evt_user_data = evt.user_data;
const auto evt_time = evt.time; const auto evt_time = evt.time;
const auto evt_sequence_num = event_type->sequence_number;
if (evt.reschedule_time == 0) {
event_queue.pop(); event_queue.pop();
basic_lock.unlock(); basic_lock.unlock();
event_type->callback( event_type->callback(
evt_user_data, evt_time, evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time});
std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time});
basic_lock.lock(); basic_lock.lock();
} else { } else {
basic_lock.unlock(); basic_lock.unlock();
const auto new_schedule_time{event_type->callback( const auto new_schedule_time{event_type->callback(
evt.user_data, evt.time, evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time})};
std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt.time})};
basic_lock.lock(); basic_lock.lock();
if (evt_sequence_num != event_type->sequence_number) {
// Heap handle is invalidated after external modification.
continue;
}
const auto next_schedule_time{new_schedule_time.has_value() const auto next_schedule_time{new_schedule_time.has_value()
? new_schedule_time.value().count() ? new_schedule_time.value().count()
: evt.reschedule_time}; : evt.reschedule_time};
@ -241,8 +241,8 @@ std::optional<s64> CoreTiming::Advance() {
next_time = pause_end_time + next_schedule_time; next_time = pause_end_time + next_schedule_time;
} }
event_queue.update(evt.handle, Event{next_time, event_fifo_id++, evt.user_data, event_queue.update(evt.handle, Event{next_time, event_fifo_id++, evt.type,
evt.type, next_schedule_time, evt.handle}); next_schedule_time, evt.handle});
} }
} }

View file

@ -22,17 +22,25 @@ namespace Core::Timing {
/// A callback that may be scheduled for a particular core timing event. /// A callback that may be scheduled for a particular core timing event.
using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>( using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>(
std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)>; s64 time, std::chrono::nanoseconds ns_late)>;
/// Contains the characteristics of a particular event. /// Contains the characteristics of a particular event.
struct EventType { struct EventType {
explicit EventType(TimedCallback&& callback_, std::string&& name_) explicit EventType(TimedCallback&& callback_, std::string&& name_)
: callback{std::move(callback_)}, name{std::move(name_)} {} : callback{std::move(callback_)}, name{std::move(name_)}, sequence_number{0} {}
/// The event's callback function. /// The event's callback function.
TimedCallback callback; TimedCallback callback;
/// A pointer to the name of the event. /// A pointer to the name of the event.
const std::string name; const std::string name;
/// A monotonic sequence number, incremented when this event is
/// changed externally.
size_t sequence_number;
};
enum class UnscheduleEventType {
Wait,
NoWait,
}; };
/** /**
@ -89,23 +97,17 @@ public:
/// Schedules an event in core timing /// Schedules an event in core timing
void ScheduleEvent(std::chrono::nanoseconds ns_into_future, void ScheduleEvent(std::chrono::nanoseconds ns_into_future,
const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data = 0, const std::shared_ptr<EventType>& event_type, bool absolute_time = false);
bool absolute_time = false);
/// Schedules an event which will automatically re-schedule itself with the given time, until /// Schedules an event which will automatically re-schedule itself with the given time, until
/// unscheduled /// unscheduled
void ScheduleLoopingEvent(std::chrono::nanoseconds start_time, void ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
std::chrono::nanoseconds resched_time, std::chrono::nanoseconds resched_time,
const std::shared_ptr<EventType>& event_type, const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data = 0, bool absolute_time = false); bool absolute_time = false);
void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data, void UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
bool wait = true); UnscheduleEventType type = UnscheduleEventType::Wait);
void UnscheduleEventWithoutWait(const std::shared_ptr<EventType>& event_type,
std::uintptr_t user_data) {
UnscheduleEvent(event_type, user_data, false);
}
void AddTicks(u64 ticks_to_add); void AddTicks(u64 ticks_to_add);
@ -158,7 +160,6 @@ private:
heap_t event_queue; heap_t event_queue;
u64 event_fifo_id = 0; u64 event_fifo_id = 0;
std::shared_ptr<EventType> ev_lost;
Common::Event event{}; Common::Event event{};
Common::Event pause_event{}; Common::Event pause_event{};
mutable std::mutex basic_lock; mutable std::mutex basic_lock;

View file

@ -10,15 +10,15 @@ namespace Kernel {
void KHardwareTimer::Initialize() { void KHardwareTimer::Initialize() {
// Create the timing callback to register with CoreTiming. // Create the timing callback to register with CoreTiming.
m_event_type = Core::Timing::CreateEvent( m_event_type = Core::Timing::CreateEvent("KHardwareTimer::Callback",
"KHardwareTimer::Callback", [](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) { [this](s64, std::chrono::nanoseconds) {
reinterpret_cast<KHardwareTimer*>(timer_handle)->DoTask(); this->DoTask();
return std::nullopt; return std::nullopt;
}); });
} }
void KHardwareTimer::Finalize() { void KHardwareTimer::Finalize() {
m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type, reinterpret_cast<uintptr_t>(this)); m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type);
m_wakeup_time = std::numeric_limits<s64>::max(); m_wakeup_time = std::numeric_limits<s64>::max();
m_event_type.reset(); m_event_type.reset();
} }
@ -57,13 +57,12 @@ void KHardwareTimer::EnableInterrupt(s64 wakeup_time) {
m_wakeup_time = wakeup_time; m_wakeup_time = wakeup_time;
m_kernel.System().CoreTiming().ScheduleEvent(std::chrono::nanoseconds{m_wakeup_time}, m_kernel.System().CoreTiming().ScheduleEvent(std::chrono::nanoseconds{m_wakeup_time},
m_event_type, reinterpret_cast<uintptr_t>(this), m_event_type, true);
true);
} }
void KHardwareTimer::DisableInterrupt() { void KHardwareTimer::DisableInterrupt() {
m_kernel.System().CoreTiming().UnscheduleEventWithoutWait(m_event_type, m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type,
reinterpret_cast<uintptr_t>(this)); Core::Timing::UnscheduleEventType::NoWait);
m_wakeup_time = std::numeric_limits<s64>::max(); m_wakeup_time = std::numeric_limits<s64>::max();
} }

View file

@ -238,7 +238,7 @@ struct KernelCore::Impl {
void InitializePreemption(KernelCore& kernel) { void InitializePreemption(KernelCore& kernel) {
preemption_event = Core::Timing::CreateEvent( preemption_event = Core::Timing::CreateEvent(
"PreemptionCallback", "PreemptionCallback",
[this, &kernel](std::uintptr_t, s64 time, [this, &kernel](s64 time,
std::chrono::nanoseconds) -> std::optional<std::chrono::nanoseconds> { std::chrono::nanoseconds) -> std::optional<std::chrono::nanoseconds> {
{ {
KScopedSchedulerLock lock(kernel); KScopedSchedulerLock lock(kernel);

View file

@ -49,10 +49,10 @@ HidBus::HidBus(Core::System& system_)
// Register update callbacks // Register update callbacks
hidbus_update_event = Core::Timing::CreateEvent( hidbus_update_event = Core::Timing::CreateEvent(
"Hidbus::UpdateCallback", "Hidbus::UpdateCallback",
[this](std::uintptr_t user_data, s64 time, [this](s64 time,
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService(); const auto guard = LockService();
UpdateHidbus(user_data, ns_late); UpdateHidbus(ns_late);
return std::nullopt; return std::nullopt;
}); });
@ -61,10 +61,10 @@ HidBus::HidBus(Core::System& system_)
} }
HidBus::~HidBus() { HidBus::~HidBus() {
system.CoreTiming().UnscheduleEvent(hidbus_update_event, 0); system.CoreTiming().UnscheduleEvent(hidbus_update_event);
} }
void HidBus::UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { void HidBus::UpdateHidbus(std::chrono::nanoseconds ns_late) {
if (is_hidbus_enabled) { if (is_hidbus_enabled) {
for (std::size_t i = 0; i < devices.size(); ++i) { for (std::size_t i = 0; i < devices.size(); ++i) {
if (!devices[i].is_device_initializated) { if (!devices[i].is_device_initializated) {

View file

@ -108,7 +108,7 @@ private:
void DisableJoyPollingReceiveMode(HLERequestContext& ctx); void DisableJoyPollingReceiveMode(HLERequestContext& ctx);
void SetStatusManagerType(HLERequestContext& ctx); void SetStatusManagerType(HLERequestContext& ctx);
void UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateHidbus(std::chrono::nanoseconds ns_late);
std::optional<std::size_t> GetDeviceIndexFromHandle(BusHandle handle) const; std::optional<std::size_t> GetDeviceIndexFromHandle(BusHandle handle) const;
template <typename T> template <typename T>

View file

@ -227,8 +227,7 @@ void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) {
applet_resource->EnableTouchScreen(aruid, is_enabled); applet_resource->EnableTouchScreen(aruid, is_enabled);
} }
void ResourceManager::UpdateControllers(std::uintptr_t user_data, void ResourceManager::UpdateControllers(std::chrono::nanoseconds ns_late) {
std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming(); auto& core_timing = system.CoreTiming();
debug_pad->OnUpdate(core_timing); debug_pad->OnUpdate(core_timing);
digitizer->OnUpdate(core_timing); digitizer->OnUpdate(core_timing);
@ -241,20 +240,19 @@ void ResourceManager::UpdateControllers(std::uintptr_t user_data,
capture_button->OnUpdate(core_timing); capture_button->OnUpdate(core_timing);
} }
void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { void ResourceManager::UpdateNpad(std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming(); auto& core_timing = system.CoreTiming();
npad->OnUpdate(core_timing); npad->OnUpdate(core_timing);
} }
void ResourceManager::UpdateMouseKeyboard(std::uintptr_t user_data, void ResourceManager::UpdateMouseKeyboard(std::chrono::nanoseconds ns_late) {
std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming(); auto& core_timing = system.CoreTiming();
mouse->OnUpdate(core_timing); mouse->OnUpdate(core_timing);
debug_mouse->OnUpdate(core_timing); debug_mouse->OnUpdate(core_timing);
keyboard->OnUpdate(core_timing); keyboard->OnUpdate(core_timing);
} }
void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { void ResourceManager::UpdateMotion(std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming(); auto& core_timing = system.CoreTiming();
six_axis->OnUpdate(core_timing); six_axis->OnUpdate(core_timing);
seven_six_axis->OnUpdate(core_timing); seven_six_axis->OnUpdate(core_timing);
@ -273,34 +271,34 @@ IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<Resource
// Register update callbacks // Register update callbacks
npad_update_event = Core::Timing::CreateEvent( npad_update_event = Core::Timing::CreateEvent(
"HID::UpdatePadCallback", "HID::UpdatePadCallback",
[this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) [this, resource](
-> std::optional<std::chrono::nanoseconds> { s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService(); const auto guard = LockService();
resource->UpdateNpad(user_data, ns_late); resource->UpdateNpad(ns_late);
return std::nullopt; return std::nullopt;
}); });
default_update_event = Core::Timing::CreateEvent( default_update_event = Core::Timing::CreateEvent(
"HID::UpdateDefaultCallback", "HID::UpdateDefaultCallback",
[this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) [this, resource](
-> std::optional<std::chrono::nanoseconds> { s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService(); const auto guard = LockService();
resource->UpdateControllers(user_data, ns_late); resource->UpdateControllers(ns_late);
return std::nullopt; return std::nullopt;
}); });
mouse_keyboard_update_event = Core::Timing::CreateEvent( mouse_keyboard_update_event = Core::Timing::CreateEvent(
"HID::UpdateMouseKeyboardCallback", "HID::UpdateMouseKeyboardCallback",
[this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) [this, resource](
-> std::optional<std::chrono::nanoseconds> { s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService(); const auto guard = LockService();
resource->UpdateMouseKeyboard(user_data, ns_late); resource->UpdateMouseKeyboard(ns_late);
return std::nullopt; return std::nullopt;
}); });
motion_update_event = Core::Timing::CreateEvent( motion_update_event = Core::Timing::CreateEvent(
"HID::UpdateMotionCallback", "HID::UpdateMotionCallback",
[this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) [this, resource](
-> std::optional<std::chrono::nanoseconds> { s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService(); const auto guard = LockService();
resource->UpdateMotion(user_data, ns_late); resource->UpdateMotion(ns_late);
return std::nullopt; return std::nullopt;
}); });
@ -314,10 +312,10 @@ IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<Resource
} }
IAppletResource::~IAppletResource() { IAppletResource::~IAppletResource() {
system.CoreTiming().UnscheduleEvent(npad_update_event, 0); system.CoreTiming().UnscheduleEvent(npad_update_event);
system.CoreTiming().UnscheduleEvent(default_update_event, 0); system.CoreTiming().UnscheduleEvent(default_update_event);
system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0); system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event);
system.CoreTiming().UnscheduleEvent(motion_update_event, 0); system.CoreTiming().UnscheduleEvent(motion_update_event);
resource_manager->FreeAppletResourceId(aruid); resource_manager->FreeAppletResourceId(aruid);
} }

View file

@ -81,10 +81,10 @@ public:
void EnablePadInput(u64 aruid, bool is_enabled); void EnablePadInput(u64 aruid, bool is_enabled);
void EnableTouchScreen(u64 aruid, bool is_enabled); void EnableTouchScreen(u64 aruid, bool is_enabled);
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateControllers(std::chrono::nanoseconds ns_late);
void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateNpad(std::chrono::nanoseconds ns_late);
void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateMouseKeyboard(std::chrono::nanoseconds ns_late);
void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateMotion(std::chrono::nanoseconds ns_late);
private: private:
Result CreateAppletResourceImpl(u64 aruid); Result CreateAppletResourceImpl(u64 aruid);

View file

@ -67,7 +67,7 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
// Schedule the screen composition events // Schedule the screen composition events
multi_composition_event = Core::Timing::CreateEvent( multi_composition_event = Core::Timing::CreateEvent(
"ScreenComposition", "ScreenComposition",
[this](std::uintptr_t, s64 time, [this](s64 time,
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
vsync_signal.Set(); vsync_signal.Set();
return std::chrono::nanoseconds(GetNextTicks()); return std::chrono::nanoseconds(GetNextTicks());
@ -75,7 +75,7 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
single_composition_event = Core::Timing::CreateEvent( single_composition_event = Core::Timing::CreateEvent(
"ScreenComposition", "ScreenComposition",
[this](std::uintptr_t, s64 time, [this](s64 time,
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto lock_guard = Lock(); const auto lock_guard = Lock();
Compose(); Compose();
@ -93,11 +93,11 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
Nvnflinger::~Nvnflinger() { Nvnflinger::~Nvnflinger() {
if (system.IsMulticore()) { if (system.IsMulticore()) {
system.CoreTiming().UnscheduleEvent(multi_composition_event, {}); system.CoreTiming().UnscheduleEvent(multi_composition_event);
vsync_thread.request_stop(); vsync_thread.request_stop();
vsync_signal.Set(); vsync_signal.Set();
} else { } else {
system.CoreTiming().UnscheduleEvent(single_composition_event, {}); system.CoreTiming().UnscheduleEvent(single_composition_event);
} }
ShutdownLayers(); ShutdownLayers();

View file

@ -190,15 +190,15 @@ CheatEngine::CheatEngine(System& system_, std::vector<CheatEntry> cheats_,
} }
CheatEngine::~CheatEngine() { CheatEngine::~CheatEngine() {
core_timing.UnscheduleEvent(event, 0); core_timing.UnscheduleEvent(event);
} }
void CheatEngine::Initialize() { void CheatEngine::Initialize() {
event = Core::Timing::CreateEvent( event = Core::Timing::CreateEvent(
"CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id), "CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id),
[this](std::uintptr_t user_data, s64 time, [this](s64 time,
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
FrameCallback(user_data, ns_late); FrameCallback(ns_late);
return std::nullopt; return std::nullopt;
}); });
core_timing.ScheduleLoopingEvent(CHEAT_ENGINE_NS, CHEAT_ENGINE_NS, event); core_timing.ScheduleLoopingEvent(CHEAT_ENGINE_NS, CHEAT_ENGINE_NS, event);
@ -239,7 +239,7 @@ void CheatEngine::Reload(std::vector<CheatEntry> reload_cheats) {
MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70)); MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70));
void CheatEngine::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) { void CheatEngine::FrameCallback(std::chrono::nanoseconds ns_late) {
if (is_pending_reload.exchange(false)) { if (is_pending_reload.exchange(false)) {
vm.LoadProgram(cheats); vm.LoadProgram(cheats);
} }

View file

@ -70,7 +70,7 @@ public:
void Reload(std::vector<CheatEntry> reload_cheats); void Reload(std::vector<CheatEntry> reload_cheats);
private: private:
void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void FrameCallback(std::chrono::nanoseconds ns_late);
DmntCheatVm vm; DmntCheatVm vm;
CheatProcessMetadata metadata; CheatProcessMetadata metadata;

View file

@ -51,18 +51,17 @@ void MemoryWriteWidth(Core::Memory::Memory& memory, u32 width, VAddr addr, u64 v
Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_) Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_)
: core_timing{core_timing_}, memory{memory_} { : core_timing{core_timing_}, memory{memory_} {
event = Core::Timing::CreateEvent( event = Core::Timing::CreateEvent("MemoryFreezer::FrameCallback",
"MemoryFreezer::FrameCallback", [this](s64 time, std::chrono::nanoseconds ns_late)
[this](std::uintptr_t user_data, s64 time, -> std::optional<std::chrono::nanoseconds> {
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { FrameCallback(ns_late);
FrameCallback(user_data, ns_late);
return std::nullopt; return std::nullopt;
}); });
core_timing.ScheduleEvent(memory_freezer_ns, event); core_timing.ScheduleEvent(memory_freezer_ns, event);
} }
Freezer::~Freezer() { Freezer::~Freezer() {
core_timing.UnscheduleEvent(event, 0); core_timing.UnscheduleEvent(event);
} }
void Freezer::SetActive(bool is_active) { void Freezer::SetActive(bool is_active) {
@ -159,7 +158,7 @@ Freezer::Entries::const_iterator Freezer::FindEntry(VAddr address) const {
[address](const Entry& entry) { return entry.address == address; }); [address](const Entry& entry) { return entry.address == address; });
} }
void Freezer::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) { void Freezer::FrameCallback(std::chrono::nanoseconds ns_late) {
if (!IsActive()) { if (!IsActive()) {
LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events."); LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events.");
return; return;

View file

@ -77,7 +77,7 @@ private:
Entries::iterator FindEntry(VAddr address); Entries::iterator FindEntry(VAddr address);
Entries::const_iterator FindEntry(VAddr address) const; Entries::const_iterator FindEntry(VAddr address) const;
void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void FrameCallback(std::chrono::nanoseconds ns_late);
void FillEntryReads(); void FillEntryReads();
std::atomic_bool active{false}; std::atomic_bool active{false};

View file

@ -16,20 +16,16 @@
namespace { namespace {
// Numbers are chosen randomly to make sure the correct one is given. // Numbers are chosen randomly to make sure the correct one is given.
constexpr std::array<u64, 5> CB_IDS{{42, 144, 93, 1026, UINT64_C(0xFFFF7FFFF7FFFF)}};
constexpr std::array<u64, 5> calls_order{{2, 0, 1, 4, 3}}; constexpr std::array<u64, 5> calls_order{{2, 0, 1, 4, 3}};
std::array<s64, 5> delays{}; std::array<s64, 5> delays{};
std::bitset<5> callbacks_ran_flags;
std::bitset<CB_IDS.size()> callbacks_ran_flags;
u64 expected_callback = 0; u64 expected_callback = 0;
template <unsigned int IDX> template <unsigned int IDX>
std::optional<std::chrono::nanoseconds> HostCallbackTemplate(std::uintptr_t user_data, s64 time, std::optional<std::chrono::nanoseconds> HostCallbackTemplate(s64 time,
std::chrono::nanoseconds ns_late) { std::chrono::nanoseconds ns_late) {
static_assert(IDX < CB_IDS.size(), "IDX out of range"); static_assert(IDX < callbacks_ran_flags.size(), "IDX out of range");
callbacks_ran_flags.set(IDX); callbacks_ran_flags.set(IDX);
REQUIRE(CB_IDS[IDX] == user_data);
REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]);
delays[IDX] = ns_late.count(); delays[IDX] = ns_late.count();
++expected_callback; ++expected_callback;
return std::nullopt; return std::nullopt;
@ -76,7 +72,7 @@ TEST_CASE("CoreTiming[BasicOrder]", "[core]") {
const u64 order = calls_order[i]; const u64 order = calls_order[i];
const auto future_ns = std::chrono::nanoseconds{static_cast<s64>(i * one_micro + 100)}; const auto future_ns = std::chrono::nanoseconds{static_cast<s64>(i * one_micro + 100)};
core_timing.ScheduleEvent(future_ns, events[order], CB_IDS[order]); core_timing.ScheduleEvent(future_ns, events[order]);
} }
/// test pause /// test pause
REQUIRE(callbacks_ran_flags.none()); REQUIRE(callbacks_ran_flags.none());
@ -118,7 +114,7 @@ TEST_CASE("CoreTiming[BasicOrderNoPausing]", "[core]") {
for (std::size_t i = 0; i < events.size(); i++) { for (std::size_t i = 0; i < events.size(); i++) {
const u64 order = calls_order[i]; const u64 order = calls_order[i];
const auto future_ns = std::chrono::nanoseconds{static_cast<s64>(i * one_micro + 100)}; const auto future_ns = std::chrono::nanoseconds{static_cast<s64>(i * one_micro + 100)};
core_timing.ScheduleEvent(future_ns, events[order], CB_IDS[order]); core_timing.ScheduleEvent(future_ns, events[order]);
} }
const u64 end = core_timing.GetGlobalTimeNs().count(); const u64 end = core_timing.GetGlobalTimeNs().count();