From 8b50c660dfce50a07c2b2aa3c1b6b8642259a944 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 15 Jul 2020 18:30:06 -0400 Subject: [PATCH 1/3] core_timing: Make use of std::chrono with ScheduleEvent --- src/audio_core/stream.cpp | 14 ++++++-------- src/audio_core/stream.h | 6 ++---- src/core/core_timing.cpp | 8 ++++---- src/core/core_timing.h | 8 ++++---- src/core/hardware_interrupt_manager.cpp | 2 +- src/core/hle/kernel/kernel.cpp | 6 ++++-- src/core/hle/kernel/server_session.cpp | 4 ++-- src/core/hle/kernel/time_manager.cpp | 3 ++- src/core/hle/service/hid/hid.cpp | 12 +++++++----- src/core/hle/service/nvflinger/nvflinger.cpp | 15 +++++++++------ src/core/memory/cheat_engine.cpp | 7 ++++--- src/core/tools/freezer.cpp | 9 +++++---- src/tests/core/core_timing.cpp | 13 ++++++++----- 13 files changed, 58 insertions(+), 49 deletions(-) diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index aab3e979a..abd8576e2 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp @@ -59,11 +59,9 @@ Stream::State Stream::GetState() const { return state; } -s64 Stream::GetBufferReleaseNS(const Buffer& buffer) const { +std::chrono::nanoseconds Stream::GetBufferReleaseNS(const Buffer& buffer) const { const std::size_t num_samples{buffer.GetSamples().size() / GetNumChannels()}; - const auto ns = - std::chrono::nanoseconds((static_cast(num_samples) * 1000000000ULL) / sample_rate); - return ns.count(); + return std::chrono::nanoseconds((static_cast(num_samples) * 1000000000ULL) / sample_rate); } static void VolumeAdjustSamples(std::vector& samples, float game_volume) { @@ -105,10 +103,10 @@ void Stream::PlayNextBuffer(s64 cycles_late) { sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); - core_timing.ScheduleEvent( - GetBufferReleaseNS(*active_buffer) - - (Settings::values.enable_audio_stretching.GetValue() ? 0 : cycles_late), - release_event, {}); + const auto time_stretch_delta = std::chrono::nanoseconds{ + Settings::values.enable_audio_stretching.GetValue() ? 0 : cycles_late}; + const auto future_time = GetBufferReleaseNS(*active_buffer) - time_stretch_delta; + core_timing.ScheduleEvent(future_time, release_event, {}); } void Stream::ReleaseActiveBuffer(s64 cycles_late) { diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h index 524376257..2febd647c 100644 --- a/src/audio_core/stream.h +++ b/src/audio_core/stream.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include @@ -96,10 +97,7 @@ private: void ReleaseActiveBuffer(s64 cycles_late = 0); /// Gets the number of core cycles when the specified buffer will be released - s64 GetBufferReleaseNS(const Buffer& buffer) const; - - /// Gets the number of core cycles when the specified buffer will be released - s64 GetBufferReleaseNSHostTiming(const Buffer& buffer) const; + std::chrono::nanoseconds GetBufferReleaseNS(const Buffer& buffer) const; u32 sample_rate; ///< Sample rate of the stream Format format; ///< Format of the stream diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index a63e60461..a5d084e08 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -53,7 +53,7 @@ void CoreTiming::ThreadEntry(CoreTiming& instance) { instance.ThreadLoop(); } -void CoreTiming::Initialize(std::function&& on_thread_init_) { +void CoreTiming::Initialize(std::function&& on_thread_init_) { on_thread_init = std::move(on_thread_init_); event_fifo_id = 0; shutting_down = false; @@ -106,11 +106,11 @@ bool CoreTiming::HasPendingEvents() const { return !(wait_set && event_queue.empty()); } -void CoreTiming::ScheduleEvent(s64 ns_into_future, const std::shared_ptr& event_type, - u64 userdata) { +void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future, + const std::shared_ptr& event_type, u64 userdata) { { std::scoped_lock scope{basic_lock}; - const u64 timeout = static_cast(GetGlobalTimeNs().count() + ns_into_future); + const u64 timeout = static_cast((GetGlobalTimeNs() + ns_into_future).count()); event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type}); diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 72faaab64..9b9f18daf 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -62,7 +62,7 @@ public: /// CoreTiming begins at the boundary of timing slice -1. An initial call to Advance() is /// required to end slice - 1 and start slice 0 before the first cycle of code is executed. - void Initialize(std::function&& on_thread_init_); + void Initialize(std::function&& on_thread_init_); /// Tears down all timing related functionality. void Shutdown(); @@ -95,8 +95,8 @@ public: bool HasPendingEvents() const; /// Schedules an event in core timing - void ScheduleEvent(s64 ns_into_future, const std::shared_ptr& event_type, - u64 userdata = 0); + void ScheduleEvent(std::chrono::nanoseconds ns_into_future, + const std::shared_ptr& event_type, u64 userdata = 0); void UnscheduleEvent(const std::shared_ptr& event_type, u64 userdata); @@ -161,7 +161,7 @@ private: std::atomic wait_set{}; std::atomic shutting_down{}; std::atomic has_started{}; - std::function on_thread_init{}; + std::function on_thread_init{}; bool is_multicore{}; diff --git a/src/core/hardware_interrupt_manager.cpp b/src/core/hardware_interrupt_manager.cpp index c629d9fa1..e7fd71e2e 100644 --- a/src/core/hardware_interrupt_manager.cpp +++ b/src/core/hardware_interrupt_manager.cpp @@ -23,7 +23,7 @@ InterruptManager::~InterruptManager() = default; void InterruptManager::GPUInterruptSyncpt(const u32 syncpoint_id, const u32 value) { const u64 msg = (static_cast(syncpoint_id) << 32ULL) | value; - system.CoreTiming().ScheduleEvent(10, gpu_interrupt_event, msg); + system.CoreTiming().ScheduleEvent(std::chrono::nanoseconds{10}, gpu_interrupt_event, msg); } } // namespace Core::Hardware diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 1f2af7a1b..35fb270b8 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -149,11 +149,13 @@ struct KernelCore::Impl { SchedulerLock lock(kernel); global_scheduler.PreemptThreads(); } - s64 time_interval = Core::Timing::msToCycles(std::chrono::milliseconds(10)); + const auto time_interval = std::chrono::nanoseconds{ + Core::Timing::msToCycles(std::chrono::milliseconds(10))}; system.CoreTiming().ScheduleEvent(time_interval, preemption_event); }); - s64 time_interval = Core::Timing::msToCycles(std::chrono::milliseconds(10)); + const auto time_interval = + std::chrono::nanoseconds{Core::Timing::msToCycles(std::chrono::milliseconds(10))}; system.CoreTiming().ScheduleEvent(time_interval, preemption_event); } diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 7b23a6889..8c32f28b5 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -184,8 +184,8 @@ ResultCode ServerSession::CompleteSyncRequest() { ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread, Core::Memory::Memory& memory) { - ResultCode result = QueueSyncRequest(std::move(thread), memory); - const u64 delay = kernel.IsMulticore() ? 0U : 20000U; + const ResultCode result = QueueSyncRequest(std::move(thread), memory); + const auto delay = std::chrono::nanoseconds{kernel.IsMulticore() ? 0 : 20000}; Core::System::GetInstance().CoreTiming().ScheduleEvent(delay, request_event, {}); return result; } diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp index 941305e8e..ebb1e5568 100644 --- a/src/core/hle/kernel/time_manager.cpp +++ b/src/core/hle/kernel/time_manager.cpp @@ -34,7 +34,8 @@ void TimeManager::ScheduleTimeEvent(Handle& event_handle, Thread* timetask, s64 ASSERT(timetask); ASSERT(timetask->GetStatus() != ThreadStatus::Ready); ASSERT(timetask->GetStatus() != ThreadStatus::WaitMutex); - system.CoreTiming().ScheduleEvent(nanoseconds, time_manager_event_type, event_handle); + system.CoreTiming().ScheduleEvent(std::chrono::nanoseconds{nanoseconds}, + time_manager_event_type, event_handle); } else { event_handle = InvalidHandle; } diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index e9020e0dc..62c942eac 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -39,9 +39,10 @@ namespace Service::HID { // Updating period for each HID device. // TODO(ogniK): Find actual polling rate of hid -constexpr s64 pad_update_ticks = static_cast(1000000000 / 66); -[[maybe_unused]] constexpr s64 accelerometer_update_ticks = static_cast(1000000000 / 100); -[[maybe_unused]] constexpr s64 gyroscope_update_ticks = static_cast(1000000000 / 100); +constexpr auto pad_update_ns = std::chrono::nanoseconds{1000000000 / 66}; +[[maybe_unused]] constexpr auto accelerometer_update_ns = + std::chrono::nanoseconds{1000000000 / 100}; +[[maybe_unused]] constexpr auto gyroscope_update_ticks = std::chrono::nanoseconds{1000000000 / 100}; constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; IAppletResource::IAppletResource(Core::System& system) @@ -82,7 +83,7 @@ IAppletResource::IAppletResource(Core::System& system) // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) - system.CoreTiming().ScheduleEvent(pad_update_ticks, pad_update_event); + system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); ReloadInputDevices(); } @@ -118,7 +119,8 @@ void IAppletResource::UpdateControllers(u64 userdata, s64 ns_late) { controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); } - core_timing.ScheduleEvent(pad_update_ticks - ns_late, pad_update_event); + const auto future_ns = pad_update_ns - std::chrono::nanoseconds{ns_late}; + core_timing.ScheduleEvent(future_ns, pad_update_event); } class IActiveVibrationDeviceList final : public ServiceFramework { diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 2f44d3779..76672264d 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -28,8 +28,7 @@ namespace Service::NVFlinger { -constexpr s64 frame_ticks = static_cast(1000000000 / 60); -constexpr s64 frame_ticks_30fps = static_cast(1000000000 / 30); +constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60}; void NVFlinger::VSyncThread(NVFlinger& nv_flinger) { nv_flinger.SplitVSync(); @@ -71,16 +70,20 @@ NVFlinger::NVFlinger(Core::System& system) : system(system) { Core::Timing::CreateEvent("ScreenComposition", [this](u64 userdata, s64 ns_late) { Lock(); Compose(); - const auto ticks = GetNextTicks(); - this->system.CoreTiming().ScheduleEvent(std::max(0LL, ticks - ns_late), - composition_event); + + const auto ticks = std::chrono::nanoseconds{GetNextTicks()}; + const auto ticks_delta = ticks - std::chrono::nanoseconds{ns_late}; + const auto future_ns = std::max(std::chrono::nanoseconds::zero(), ticks_delta); + + this->system.CoreTiming().ScheduleEvent(future_ns, composition_event); }); + if (system.IsMulticore()) { is_running = true; wait_event = std::make_unique(); vsync_thread = std::make_unique(VSyncThread, std::ref(*this)); } else { - system.CoreTiming().ScheduleEvent(frame_ticks, composition_event); + system.CoreTiming().ScheduleEvent(frame_ns, composition_event); } } diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index 53d27859b..09bf8c5cf 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp @@ -20,7 +20,7 @@ namespace Core::Memory { -constexpr s64 CHEAT_ENGINE_TICKS = static_cast(1000000000 / 12); +constexpr auto CHEAT_ENGINE_NS = std::chrono::nanoseconds{1000000000 / 12}; constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF; StandardVmCallbacks::StandardVmCallbacks(Core::System& system, const CheatProcessMetadata& metadata) @@ -191,7 +191,7 @@ void CheatEngine::Initialize() { event = Core::Timing::CreateEvent( "CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id), [this](u64 userdata, s64 ns_late) { FrameCallback(userdata, ns_late); }); - core_timing.ScheduleEvent(CHEAT_ENGINE_TICKS, event); + core_timing.ScheduleEvent(CHEAT_ENGINE_NS, event); metadata.process_id = system.CurrentProcess()->GetProcessID(); metadata.title_id = system.CurrentProcess()->GetTitleID(); @@ -230,7 +230,8 @@ void CheatEngine::FrameCallback(u64 userdata, s64 ns_late) { vm.Execute(metadata); - core_timing.ScheduleEvent(CHEAT_ENGINE_TICKS - ns_late, event); + const auto future_ns = CHEAT_ENGINE_NS - std::chrono::nanoseconds{ns_late}; + core_timing.ScheduleEvent(future_ns, event); } } // namespace Core::Memory diff --git a/src/core/tools/freezer.cpp b/src/core/tools/freezer.cpp index 8b0c50d11..5dc52d1c1 100644 --- a/src/core/tools/freezer.cpp +++ b/src/core/tools/freezer.cpp @@ -14,7 +14,7 @@ namespace Tools { namespace { -constexpr s64 MEMORY_FREEZER_TICKS = static_cast(1000000000 / 60); +constexpr auto memory_freezer_ns = std::chrono::nanoseconds{1000000000 / 60}; u64 MemoryReadWidth(Core::Memory::Memory& memory, u32 width, VAddr addr) { switch (width) { @@ -58,7 +58,7 @@ Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& m event = Core::Timing::CreateEvent( "MemoryFreezer::FrameCallback", [this](u64 userdata, s64 ns_late) { FrameCallback(userdata, ns_late); }); - core_timing.ScheduleEvent(MEMORY_FREEZER_TICKS, event); + core_timing.ScheduleEvent(memory_freezer_ns, event); } Freezer::~Freezer() { @@ -68,7 +68,7 @@ Freezer::~Freezer() { void Freezer::SetActive(bool active) { if (!this->active.exchange(active)) { FillEntryReads(); - core_timing.ScheduleEvent(MEMORY_FREEZER_TICKS, event); + core_timing.ScheduleEvent(memory_freezer_ns, event); LOG_DEBUG(Common_Memory, "Memory freezer activated!"); } else { LOG_DEBUG(Common_Memory, "Memory freezer deactivated!"); @@ -173,7 +173,8 @@ void Freezer::FrameCallback(u64 userdata, s64 ns_late) { MemoryWriteWidth(memory, entry.width, entry.address, entry.value); } - core_timing.ScheduleEvent(MEMORY_FREEZER_TICKS - ns_late, event); + const auto future_ns = memory_freezer_ns - std::chrono::nanoseconds{ns_late}; + core_timing.ScheduleEvent(future_ns, event); } void Freezer::FillEntryReads() { diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp index e66db1940..4ede1bc2e 100644 --- a/src/tests/core/core_timing.cpp +++ b/src/tests/core/core_timing.cpp @@ -116,13 +116,16 @@ TEST_CASE("CoreTiming[BasicOrderNoPausing]", "[core]") { expected_callback = 0; - u64 start = core_timing.GetGlobalTimeNs().count(); - u64 one_micro = 1000U; + const u64 start = core_timing.GetGlobalTimeNs().count(); + const u64 one_micro = 1000U; + for (std::size_t i = 0; i < events.size(); i++) { - u64 order = calls_order[i]; - core_timing.ScheduleEvent(i * one_micro + 100U, events[order], CB_IDS[order]); + const u64 order = calls_order[i]; + const auto future_ns = std::chrono::nanoseconds{static_cast(i * one_micro + 100)}; + core_timing.ScheduleEvent(future_ns, events[order], CB_IDS[order]); } - u64 end = core_timing.GetGlobalTimeNs().count(); + + const u64 end = core_timing.GetGlobalTimeNs().count(); const double scheduling_time = static_cast(end - start); const double timer_time = static_cast(TestTimerSpeed(core_timing)); From bef1844a51a37c1c8dc531e67069ef00821ffa9c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 15 Jul 2020 19:14:21 -0400 Subject: [PATCH 2/3] core_timing: Make TimedCallback take std::chrono::nanoseconds Enforces our desired time units directly with a concrete type. --- src/audio_core/stream.cpp | 13 +++++++------ src/audio_core/stream.h | 4 ++-- src/core/core_timing.cpp | 7 ++++--- src/core/core_timing.h | 10 ++++------ src/core/hardware_interrupt_manager.cpp | 13 +++++++------ src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/kernel/server_session.cpp | 2 +- src/core/hle/kernel/time_manager.cpp | 2 +- src/core/hle/service/hid/hid.cpp | 9 ++++----- src/core/hle/service/hid/hid.h | 7 +++---- src/core/hle/service/nvflinger/nvflinger.cpp | 6 +++--- src/core/memory/cheat_engine.cpp | 13 +++++++------ src/core/memory/cheat_engine.h | 3 ++- src/core/tools/freezer.cpp | 12 ++++++------ src/core/tools/freezer.h | 3 ++- 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 sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { release_event = Core::Timing::CreateEvent( - name, [this](u64 userdata, s64 cycles_late) { ReleaseActiveBuffer(cycles_late); }); + name, [this](u64, std::chrono::nanoseconds ns_late) { ReleaseActiveBuffer(ns_late); }); } void Stream::Play() { @@ -78,7 +78,7 @@ static void VolumeAdjustSamples(std::vector& samples, float game_volume) { } } -void Stream::PlayNextBuffer(s64 cycles_late) { +void Stream::PlayNextBuffer(std::chrono::nanoseconds ns_late) { if (!IsPlaying()) { // Ensure we are in playing state before playing the next buffer sink_stream.Flush(); @@ -103,17 +103,18 @@ void Stream::PlayNextBuffer(s64 cycles_late) { sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); - const auto time_stretch_delta = std::chrono::nanoseconds{ - Settings::values.enable_audio_stretching.GetValue() ? 0 : cycles_late}; + const auto time_stretch_delta = Settings::values.enable_audio_stretching.GetValue() + ? std::chrono::nanoseconds::zero() + : ns_late; const auto future_time = GetBufferReleaseNS(*active_buffer) - time_stretch_delta; core_timing.ScheduleEvent(future_time, release_event, {}); } -void Stream::ReleaseActiveBuffer(s64 cycles_late) { +void Stream::ReleaseActiveBuffer(std::chrono::nanoseconds ns_late) { ASSERT(active_buffer); released_buffers.push(std::move(active_buffer)); release_callback(); - PlayNextBuffer(cycles_late); + PlayNextBuffer(ns_late); } 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: private: /// Plays the next queued buffer in the audio stream, starting playback if necessary - void PlayNextBuffer(s64 cycles_late = 0); + void PlayNextBuffer(std::chrono::nanoseconds ns_late = {}); /// Releases the actively playing buffer, signalling that it has been completed - void ReleaseActiveBuffer(s64 cycles_late = 0); + void ReleaseActiveBuffer(std::chrono::nanoseconds ns_late = {}); /// Gets the number of core cycles when the specified buffer will be released 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&& on_thread_init_) { event_fifo_id = 0; shutting_down = false; ticks = 0; - const auto empty_timed_callback = [](u64, s64) {}; + const auto empty_timed_callback = [](u64, std::chrono::nanoseconds) {}; ev_lost = CreateEvent("_lost_event", empty_timed_callback); if (is_multicore) { timer_thread = std::make_unique(ThreadEntry, std::ref(*this)); @@ -195,8 +195,9 @@ std::optional CoreTiming::Advance() { event_queue.pop_back(); basic_lock.unlock(); - if (auto event_type{evt.type.lock()}) { - event_type->callback(evt.userdata, global_timer - evt.time); + if (const auto event_type{evt.type.lock()}) { + event_type->callback( + evt.userdata, std::chrono::nanoseconds{static_cast(global_timer - evt.time)}); } 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 @@ #include "common/common_types.h" #include "common/spin_lock.h" #include "common/thread.h" -#include "common/threadsafe_queue.h" #include "common/wall_clock.h" -#include "core/hardware_properties.h" namespace Core::Timing { /// A callback that may be scheduled for a particular core timing event. -using TimedCallback = std::function; +using TimedCallback = std::function; /// Contains the characteristics of a particular event. struct EventType { @@ -42,12 +40,12 @@ struct EventType { * in main CPU clock cycles. * * To schedule an event, you first have to register its type. This is where you pass in the - * callback. You then schedule events using the type id you get back. + * callback. You then schedule events using the type ID you get back. * - * The int cyclesLate that the callbacks get is how many cycles late it was. + * The s64 ns_late that the callbacks get is how many ns late it was. * So to schedule a new event on a regular basis: * inside callback: - * ScheduleEvent(periodInCycles - cyclesLate, callback, "whatever") + * ScheduleEvent(period_in_ns - ns_late, callback, "whatever") */ class CoreTiming { 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 @@ namespace Core::Hardware { InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) { - gpu_interrupt_event = Core::Timing::CreateEvent("GPUInterrupt", [this](u64 message, s64) { - auto nvdrv = system.ServiceManager().GetService("nvdrv"); - const u32 syncpt = static_cast(message >> 32); - const u32 value = static_cast(message); - nvdrv->SignalGPUInterruptSyncpt(syncpt, value); - }); + gpu_interrupt_event = + Core::Timing::CreateEvent("GPUInterrupt", [this](u64 message, std::chrono::nanoseconds) { + auto nvdrv = system.ServiceManager().GetService("nvdrv"); + const u32 syncpt = static_cast(message >> 32); + const u32 value = static_cast(message); + nvdrv->SignalGPUInterruptSyncpt(syncpt, value); + }); } 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 { void InitializePreemption(KernelCore& kernel) { preemption_event = Core::Timing::CreateEvent( - "PreemptionCallback", [this, &kernel](u64 userdata, s64 cycles_late) { + "PreemptionCallback", [this, &kernel](u64, std::chrono::nanoseconds) { { SchedulerLock lock(kernel); 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> ServerSession::Create(KernelCore& kern std::shared_ptr session{std::make_shared(kernel)}; session->request_event = Core::Timing::CreateEvent( - name, [session](u64 userdata, s64 cycles_late) { session->CompleteSyncRequest(); }); + name, [session](u64, std::chrono::nanoseconds) { session->CompleteSyncRequest(); }); session->name = std::move(name); session->parent = std::move(parent); 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 { TimeManager::TimeManager(Core::System& system_) : system{system_} { time_manager_event_type = Core::Timing::CreateEvent( - "Kernel::TimeManagerCallback", [this](u64 thread_handle, [[maybe_unused]] s64 cycles_late) { + "Kernel::TimeManagerCallback", [this](u64 thread_handle, std::chrono::nanoseconds) { SchedulerLock lock(system.Kernel()); Handle proper_handle = static_cast(thread_handle); 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) GetController(HidController::Unknown3).SetCommonHeaderOffset(0x5000); // Register update callbacks - pad_update_event = - Core::Timing::CreateEvent("HID::UpdatePadCallback", [this](u64 userdata, s64 ns_late) { + pad_update_event = Core::Timing::CreateEvent( + "HID::UpdatePadCallback", [this](u64 userdata, std::chrono::nanoseconds ns_late) { UpdateControllers(userdata, ns_late); }); @@ -108,7 +108,7 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { rb.PushCopyObjects(shared_mem); } -void IAppletResource::UpdateControllers(u64 userdata, s64 ns_late) { +void IAppletResource::UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late) { auto& core_timing = system.CoreTiming(); const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); @@ -119,8 +119,7 @@ void IAppletResource::UpdateControllers(u64 userdata, s64 ns_late) { controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); } - const auto future_ns = pad_update_ns - std::chrono::nanoseconds{ns_late}; - core_timing.ScheduleEvent(future_ns, pad_update_event); + core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); } class IActiveVibrationDeviceList final : public ServiceFramework { 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 @@ #pragma once -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/service.h" +#include -#include "controllers/controller_base.h" +#include "core/hle/service/hid/controllers/controller_base.h" #include "core/hle/service/service.h" namespace Core::Timing { @@ -65,7 +64,7 @@ private: } void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); - void UpdateControllers(u64 userdata, s64 cycles_late); + void UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late); std::shared_ptr shared_mem; 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) { guard = std::make_shared(); // Schedule the screen composition events - composition_event = - Core::Timing::CreateEvent("ScreenComposition", [this](u64 userdata, s64 ns_late) { + composition_event = Core::Timing::CreateEvent( + "ScreenComposition", [this](u64, std::chrono::nanoseconds ns_late) { Lock(); Compose(); const auto ticks = std::chrono::nanoseconds{GetNextTicks()}; - const auto ticks_delta = ticks - std::chrono::nanoseconds{ns_late}; + const auto ticks_delta = ticks - ns_late; const auto future_ns = std::max(std::chrono::nanoseconds::zero(), ticks_delta); 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() { } void CheatEngine::Initialize() { - event = Core::Timing::CreateEvent( - "CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id), - [this](u64 userdata, s64 ns_late) { FrameCallback(userdata, ns_late); }); + event = Core::Timing::CreateEvent("CheatEngine::FrameCallback::" + + Common::HexToString(metadata.main_nso_build_id), + [this](u64 userdata, std::chrono::nanoseconds ns_late) { + FrameCallback(userdata, ns_late); + }); core_timing.ScheduleEvent(CHEAT_ENGINE_NS, event); metadata.process_id = system.CurrentProcess()->GetProcessID(); @@ -217,7 +219,7 @@ void CheatEngine::Reload(std::vector cheats) { MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70)); -void CheatEngine::FrameCallback(u64 userdata, s64 ns_late) { +void CheatEngine::FrameCallback(u64, std::chrono::nanoseconds ns_late) { if (is_pending_reload.exchange(false)) { vm.LoadProgram(cheats); } @@ -230,8 +232,7 @@ void CheatEngine::FrameCallback(u64 userdata, s64 ns_late) { vm.Execute(metadata); - const auto future_ns = CHEAT_ENGINE_NS - std::chrono::nanoseconds{ns_late}; - core_timing.ScheduleEvent(future_ns, event); + core_timing.ScheduleEvent(CHEAT_ENGINE_NS - ns_late, event); } } // 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 @@ #pragma once #include +#include #include #include #include "common/common_types.h" @@ -71,7 +72,7 @@ public: void Reload(std::vector cheats); private: - void FrameCallback(u64 userdata, s64 cycles_late); + void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late); DmntCheatVm vm; 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 Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_) : core_timing{core_timing_}, memory{memory_} { - event = Core::Timing::CreateEvent( - "MemoryFreezer::FrameCallback", - [this](u64 userdata, s64 ns_late) { FrameCallback(userdata, ns_late); }); + event = Core::Timing::CreateEvent("MemoryFreezer::FrameCallback", + [this](u64 userdata, std::chrono::nanoseconds ns_late) { + FrameCallback(userdata, ns_late); + }); core_timing.ScheduleEvent(memory_freezer_ns, event); } @@ -158,7 +159,7 @@ std::vector Freezer::GetEntries() const { return entries; } -void Freezer::FrameCallback(u64 userdata, s64 ns_late) { +void Freezer::FrameCallback(u64, std::chrono::nanoseconds ns_late) { if (!IsActive()) { LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events."); return; @@ -173,8 +174,7 @@ void Freezer::FrameCallback(u64 userdata, s64 ns_late) { MemoryWriteWidth(memory, entry.width, entry.address, entry.value); } - const auto future_ns = memory_freezer_ns - std::chrono::nanoseconds{ns_late}; - core_timing.ScheduleEvent(future_ns, event); + core_timing.ScheduleEvent(memory_freezer_ns - ns_late, event); } 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 @@ #pragma once #include +#include #include #include #include @@ -72,7 +73,7 @@ public: std::vector GetEntries() const; private: - void FrameCallback(u64 userdata, s64 cycles_late); + void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late); void FillEntryReads(); 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 @@ #include #include +#include #include #include #include @@ -17,7 +18,6 @@ namespace { // Numbers are chosen randomly to make sure the correct one is given. constexpr std::array CB_IDS{{42, 144, 93, 1026, UINT64_C(0xFFFF7FFFF7FFFF)}}; -constexpr int MAX_SLICE_LENGTH = 10000; // Copied from CoreTiming internals constexpr std::array calls_order{{2, 0, 1, 4, 3}}; std::array delays{}; @@ -25,12 +25,12 @@ std::bitset callbacks_ran_flags; u64 expected_callback = 0; template -void HostCallbackTemplate(u64 userdata, s64 nanoseconds_late) { +void HostCallbackTemplate(u64 userdata, std::chrono::nanoseconds ns_late) { static_assert(IDX < CB_IDS.size(), "IDX out of range"); callbacks_ran_flags.set(IDX); REQUIRE(CB_IDS[IDX] == userdata); REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]); - delays[IDX] = nanoseconds_late; + delays[IDX] = ns_late.count(); ++expected_callback; } @@ -77,10 +77,12 @@ TEST_CASE("CoreTiming[BasicOrder]", "[core]") { core_timing.SyncPause(true); - u64 one_micro = 1000U; + const u64 one_micro = 1000U; for (std::size_t i = 0; i < events.size(); i++) { - u64 order = calls_order[i]; - core_timing.ScheduleEvent(i * one_micro + 100U, events[order], CB_IDS[order]); + const u64 order = calls_order[i]; + const auto future_ns = std::chrono::nanoseconds{static_cast(i * one_micro + 100)}; + + core_timing.ScheduleEvent(future_ns, events[order], CB_IDS[order]); } /// test pause REQUIRE(callbacks_ran_flags.none()); From 0435b7d361d45aa5eccb552d01df4cea3f4016c4 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 15 Jul 2020 19:19:15 -0400 Subject: [PATCH 3/3] core_timing: Remove unused data member Shrinks the size of the CoreTiming class by 8 bytes. --- src/core/core_timing.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/core_timing.h b/src/core/core_timing.h index a21356a08..120c74e46 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -139,8 +139,6 @@ private: u64 global_timer = 0; - std::chrono::nanoseconds start_point; - // The queue is a min-heap using std::make_heap/push_heap/pop_heap. // We don't use std::priority_queue because we need to be able to serialize, unserialize and // erase arbitrary events (RemoveEvent()) regardless of the queue order. These aren't