summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2020-07-16 01:14:21 +0200
committerLioncash <mathew1800@gmail.com>2020-07-16 01:41:22 +0200
commitbef1844a51a37c1c8dc531e67069ef00821ffa9c (patch)
tree2e46f404c3f0baf1b854e1bea916c19469fe424a
parentcore_timing: Make use of std::chrono with ScheduleEvent (diff)
downloadyuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.tar
yuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.tar.gz
yuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.tar.bz2
yuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.tar.lz
yuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.tar.xz
yuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.tar.zst
yuzu-bef1844a51a37c1c8dc531e67069ef00821ffa9c.zip
-rw-r--r--src/audio_core/stream.cpp13
-rw-r--r--src/audio_core/stream.h4
-rw-r--r--src/core/core_timing.cpp7
-rw-r--r--src/core/core_timing.h10
-rw-r--r--src/core/hardware_interrupt_manager.cpp13
-rw-r--r--src/core/hle/kernel/kernel.cpp2
-rw-r--r--src/core/hle/kernel/server_session.cpp2
-rw-r--r--src/core/hle/kernel/time_manager.cpp2
-rw-r--r--src/core/hle/service/hid/hid.cpp9
-rw-r--r--src/core/hle/service/hid/hid.h7
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp6
-rw-r--r--src/core/memory/cheat_engine.cpp13
-rw-r--r--src/core/memory/cheat_engine.h3
-rw-r--r--src/core/tools/freezer.cpp12
-rw-r--r--src/core/tools/freezer.h3
-rw-r--r--src/tests/core/core_timing.cpp14
16 files changed, 62 insertions, 58 deletions
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index abd8576e2..f80ab92e4 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -38,7 +38,7 @@ Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format fo
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<s16>& 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<void()>&& 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<std::thread>(ThreadEntry, std::ref(*this));
@@ -195,8 +195,9 @@ std::optional<s64> 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<s64>(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<void(u64 userdata, s64 cycles_late)>;
+using TimedCallback = std::function<void(u64 userdata, std::chrono::nanoseconds ns_late)>;
/// 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<Service::Nvidia::NVDRV>("nvdrv");
- const u32 syncpt = static_cast<u32>(message >> 32);
- const u32 value = static_cast<u32>(message);
- nvdrv->SignalGPUInterruptSyncpt(syncpt, value);
- });
+ gpu_interrupt_event =
+ Core::Timing::CreateEvent("GPUInterrupt", [this](u64 message, std::chrono::nanoseconds) {
+ auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv");
+ const u32 syncpt = static_cast<u32>(message >> 32);
+ const u32 value = static_cast<u32>(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<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern
std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(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<Handle>(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<Controller_Stubbed>(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<IActiveVibrationDeviceList> {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 6fb048360..c6f0a2584 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -4,10 +4,9 @@
#pragma once
-#include "core/hle/service/hid/controllers/controller_base.h"
-#include "core/hle/service/service.h"
+#include <chrono>
-#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<Kernel::SharedMemory> 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<std::mutex>();
// 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<CheatEntry> 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 <atomic>
+#include <chrono>
#include <memory>
#include <vector>
#include "common/common_types.h"
@@ -71,7 +72,7 @@ public:
void Reload(std::vector<CheatEntry> 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::Entry> 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 <atomic>
+#include <chrono>
#include <memory>
#include <mutex>
#include <optional>
@@ -72,7 +73,7 @@ public:
std::vector<Entry> 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 <array>
#include <bitset>
+#include <chrono>
#include <cstdlib>
#include <memory>
#include <string>
@@ -17,7 +18,6 @@
namespace {
// 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 int MAX_SLICE_LENGTH = 10000; // Copied from CoreTiming internals
constexpr std::array<u64, 5> calls_order{{2, 0, 1, 4, 3}};
std::array<s64, 5> delays{};
@@ -25,12 +25,12 @@ std::bitset<CB_IDS.size()> callbacks_ran_flags;
u64 expected_callback = 0;
template <unsigned int IDX>
-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<s64>(i * one_micro + 100)};
+
+ core_timing.ScheduleEvent(future_ns, events[order], CB_IDS[order]);
}
/// test pause
REQUIRE(callbacks_ran_flags.none());