From a7af349daee85237384dba07533c9a407cf15592 Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Mon, 27 Jul 2020 19:00:41 -0400
Subject: [PATCH] core_timing: Make use of uintptr_t to represent user_data

Makes the interface future-proofed for supporting other platforms in the event we ever support platforms with differing pointer sizes. This way, we have a type in place that is always guaranteed to be able to represent a pointer exactly.
---
 src/audio_core/stream.cpp                    |  7 ++++---
 src/core/core_timing.cpp                     | 16 +++++++++-------
 src/core/core_timing.h                       |  7 ++++---
 src/core/hardware_interrupt_manager.cpp      |  4 ++--
 src/core/hle/kernel/kernel.cpp               |  2 +-
 src/core/hle/kernel/server_session.cpp       |  6 ++++--
 src/core/hle/kernel/time_manager.cpp         | 10 +++++-----
 src/core/hle/service/hid/hid.cpp             |  8 +++++---
 src/core/hle/service/hid/hid.h               |  2 +-
 src/core/hle/service/nvflinger/nvflinger.cpp |  2 +-
 src/core/memory/cheat_engine.cpp             | 12 ++++++------
 src/core/memory/cheat_engine.h               |  2 +-
 src/core/tools/freezer.cpp                   | 11 ++++++-----
 src/core/tools/freezer.h                     |  2 +-
 src/tests/core/core_timing.cpp               |  4 ++--
 15 files changed, 52 insertions(+), 43 deletions(-)

diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp
index f80ab92e43..7be5d50872 100644
--- a/src/audio_core/stream.cpp
+++ b/src/audio_core/stream.cpp
@@ -36,9 +36,10 @@ Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format fo
                ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_)
     : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)},
       sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} {
-
-    release_event = Core::Timing::CreateEvent(
-        name, [this](u64, std::chrono::nanoseconds ns_late) { ReleaseActiveBuffer(ns_late); });
+    release_event =
+        Core::Timing::CreateEvent(name, [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
+            ReleaseActiveBuffer(ns_late);
+        });
 }
 
 void Stream::Play() {
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index b5feb3f241..71af26ec5c 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -23,7 +23,7 @@ std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callbac
 struct CoreTiming::Event {
     u64 time;
     u64 fifo_order;
-    u64 userdata;
+    std::uintptr_t user_data;
     std::weak_ptr<EventType> type;
 
     // Sort by time, unless the times are the same, in which case sort by
@@ -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, std::chrono::nanoseconds) {};
+    const auto empty_timed_callback = [](std::uintptr_t, 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));
@@ -107,22 +107,24 @@ bool CoreTiming::HasPendingEvents() const {
 }
 
 void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
-                               const std::shared_ptr<EventType>& event_type, u64 userdata) {
+                               const std::shared_ptr<EventType>& event_type,
+                               std::uintptr_t user_data) {
     {
         std::scoped_lock scope{basic_lock};
         const u64 timeout = static_cast<u64>((GetGlobalTimeNs() + ns_into_future).count());
 
-        event_queue.emplace_back(Event{timeout, event_fifo_id++, userdata, event_type});
+        event_queue.emplace_back(Event{timeout, event_fifo_id++, user_data, event_type});
 
         std::push_heap(event_queue.begin(), event_queue.end(), std::greater<>());
     }
     event.Set();
 }
 
-void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type, u64 userdata) {
+void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
+                                 std::uintptr_t user_data) {
     std::scoped_lock scope{basic_lock};
     const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
-        return e.type.lock().get() == event_type.get() && e.userdata == userdata;
+        return e.type.lock().get() == event_type.get() && e.user_data == user_data;
     });
 
     // Removing random items breaks the invariant so we have to re-establish it.
@@ -197,7 +199,7 @@ std::optional<s64> CoreTiming::Advance() {
 
         if (const auto event_type{evt.type.lock()}) {
             event_type->callback(
-                evt.userdata, std::chrono::nanoseconds{static_cast<s64>(global_timer - evt.time)});
+                evt.user_data, 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 120c74e469..b0b6036e42 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -22,7 +22,8 @@
 namespace Core::Timing {
 
 /// A callback that may be scheduled for a particular core timing event.
-using TimedCallback = std::function<void(u64 userdata, std::chrono::nanoseconds ns_late)>;
+using TimedCallback =
+    std::function<void(std::uintptr_t user_data, std::chrono::nanoseconds ns_late)>;
 
 /// Contains the characteristics of a particular event.
 struct EventType {
@@ -94,9 +95,9 @@ public:
 
     /// Schedules an event in core timing
     void ScheduleEvent(std::chrono::nanoseconds ns_into_future,
-                       const std::shared_ptr<EventType>& event_type, u64 userdata = 0);
+                       const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data = 0);
 
-    void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, u64 userdata);
+    void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data);
 
     /// We only permit one event of each type in the queue at a time.
     void RemoveEvent(const std::shared_ptr<EventType>& event_type);
diff --git a/src/core/hardware_interrupt_manager.cpp b/src/core/hardware_interrupt_manager.cpp
index efc1030c1d..645f26e913 100644
--- a/src/core/hardware_interrupt_manager.cpp
+++ b/src/core/hardware_interrupt_manager.cpp
@@ -11,8 +11,8 @@
 namespace Core::Hardware {
 
 InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) {
-    gpu_interrupt_event =
-        Core::Timing::CreateEvent("GPUInterrupt", [this](u64 message, std::chrono::nanoseconds) {
+    gpu_interrupt_event = Core::Timing::CreateEvent(
+        "GPUInterrupt", [this](std::uintptr_t 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);
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 8dd4a26370..cabe8d4187 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -145,7 +145,7 @@ struct KernelCore::Impl {
 
     void InitializePreemption(KernelCore& kernel) {
         preemption_event = Core::Timing::CreateEvent(
-            "PreemptionCallback", [this, &kernel](u64, std::chrono::nanoseconds) {
+            "PreemptionCallback", [this, &kernel](std::uintptr_t, 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 af22f4c33a..7e6391c6c0 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -33,8 +33,10 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern
                                                                 std::string name) {
     std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(kernel)};
 
-    session->request_event = Core::Timing::CreateEvent(
-        name, [session](u64, std::chrono::nanoseconds) { session->CompleteSyncRequest(); });
+    session->request_event =
+        Core::Timing::CreateEvent(name, [session](std::uintptr_t, 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 88b01b7514..95f2446c99 100644
--- a/src/core/hle/kernel/time_manager.cpp
+++ b/src/core/hle/kernel/time_manager.cpp
@@ -16,14 +16,14 @@ namespace Kernel {
 
 TimeManager::TimeManager(Core::System& system_) : system{system_} {
     time_manager_event_type = Core::Timing::CreateEvent(
-        "Kernel::TimeManagerCallback", [this](u64 thread_handle, std::chrono::nanoseconds) {
-            SchedulerLock lock(system.Kernel());
-            Handle proper_handle = static_cast<Handle>(thread_handle);
+        "Kernel::TimeManagerCallback",
+        [this](std::uintptr_t thread_handle, std::chrono::nanoseconds) {
+            const SchedulerLock lock(system.Kernel());
+            const auto proper_handle = static_cast<Handle>(thread_handle);
             if (cancelled_events[proper_handle]) {
                 return;
             }
-            std::shared_ptr<Thread> thread =
-                this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle);
+            auto thread = this->system.Kernel().RetrieveThreadFromGlobalHandleTable(proper_handle);
             thread->OnWakeUp();
         });
 }
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 680290cbd8..1e95b75806 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -77,8 +77,9 @@ IAppletResource::IAppletResource(Core::System& system)
 
     // Register update callbacks
     pad_update_event = Core::Timing::CreateEvent(
-        "HID::UpdatePadCallback", [this](u64 userdata, std::chrono::nanoseconds ns_late) {
-            UpdateControllers(userdata, ns_late);
+        "HID::UpdatePadCallback",
+        [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+            UpdateControllers(user_data, ns_late);
         });
 
     // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
@@ -108,7 +109,8 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
     rb.PushCopyObjects(shared_mem);
 }
 
-void IAppletResource::UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late) {
+void IAppletResource::UpdateControllers(std::uintptr_t user_data,
+                                        std::chrono::nanoseconds ns_late) {
     auto& core_timing = system.CoreTiming();
 
     const bool should_reload = Settings::values.is_device_reload_pending.exchange(false);
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index c6f0a25841..efb07547f7 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -64,7 +64,7 @@ private:
     }
 
     void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
-    void UpdateControllers(u64 userdata, std::chrono::nanoseconds ns_late);
+    void UpdateControllers(std::uintptr_t user_data, 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 e561bf6549..f644a460d3 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -67,7 +67,7 @@ NVFlinger::NVFlinger(Core::System& system) : system(system) {
 
     // Schedule the screen composition events
     composition_event = Core::Timing::CreateEvent(
-        "ScreenComposition", [this](u64, std::chrono::nanoseconds ns_late) {
+        "ScreenComposition", [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
             const auto guard = Lock();
             Compose();
 
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index ced41b1fe1..eeebdf02e6 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -188,11 +188,11 @@ CheatEngine::~CheatEngine() {
 }
 
 void CheatEngine::Initialize() {
-    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);
-                                      });
+    event = Core::Timing::CreateEvent(
+        "CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id),
+        [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+            FrameCallback(user_data, ns_late);
+        });
     core_timing.ScheduleEvent(CHEAT_ENGINE_NS, event);
 
     metadata.process_id = system.CurrentProcess()->GetProcessID();
@@ -219,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, std::chrono::nanoseconds ns_late) {
+void CheatEngine::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) {
     if (is_pending_reload.exchange(false)) {
         vm.LoadProgram(cheats);
     }
diff --git a/src/core/memory/cheat_engine.h b/src/core/memory/cheat_engine.h
index d4068cf842..fa039a8317 100644
--- a/src/core/memory/cheat_engine.h
+++ b/src/core/memory/cheat_engine.h
@@ -72,7 +72,7 @@ public:
     void Reload(std::vector<CheatEntry> cheats);
 
 private:
-    void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late);
+    void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
 
     DmntCheatVm vm;
     CheatProcessMetadata metadata;
diff --git a/src/core/tools/freezer.cpp b/src/core/tools/freezer.cpp
index 27b894b511..2003e096f9 100644
--- a/src/core/tools/freezer.cpp
+++ b/src/core/tools/freezer.cpp
@@ -55,10 +55,11 @@ 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, std::chrono::nanoseconds ns_late) {
-                                          FrameCallback(userdata, ns_late);
-                                      });
+    event = Core::Timing::CreateEvent(
+        "MemoryFreezer::FrameCallback",
+        [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+            FrameCallback(user_data, ns_late);
+        });
     core_timing.ScheduleEvent(memory_freezer_ns, event);
 }
 
@@ -159,7 +160,7 @@ std::vector<Freezer::Entry> Freezer::GetEntries() const {
     return entries;
 }
 
-void Freezer::FrameCallback(u64, std::chrono::nanoseconds ns_late) {
+void Freezer::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) {
     if (!IsActive()) {
         LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events.");
         return;
diff --git a/src/core/tools/freezer.h b/src/core/tools/freezer.h
index 8438783d5f..2b2326bc47 100644
--- a/src/core/tools/freezer.h
+++ b/src/core/tools/freezer.h
@@ -73,7 +73,7 @@ public:
     std::vector<Entry> GetEntries() const;
 
 private:
-    void FrameCallback(u64 userdata, std::chrono::nanoseconds ns_late);
+    void FrameCallback(std::uintptr_t user_data, 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 244463a47f..022b26e6d5 100644
--- a/src/tests/core/core_timing.cpp
+++ b/src/tests/core/core_timing.cpp
@@ -25,10 +25,10 @@ std::bitset<CB_IDS.size()> callbacks_ran_flags;
 u64 expected_callback = 0;
 
 template <unsigned int IDX>
-void HostCallbackTemplate(u64 userdata, std::chrono::nanoseconds ns_late) {
+void HostCallbackTemplate(std::uintptr_t user_data, 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] == user_data);
     REQUIRE(CB_IDS[IDX] == CB_IDS[calls_order[expected_callback]]);
     delays[IDX] = ns_late.count();
     ++expected_callback;