From ff610103b58b3e0dd39fafb539a1cc0bc0fae577 Mon Sep 17 00:00:00 2001
From: Zach Hilman <zachhilman@gmail.com>
Date: Mon, 26 Nov 2018 18:34:07 -0500
Subject: [PATCH] core: Port all current usages of Event to
 Readable/WritableEvent

---
 src/audio_core/audio_renderer.cpp             |  4 +-
 src/audio_core/audio_renderer.h               |  7 ++-
 src/core/hle/kernel/svc.cpp                   | 11 ++--
 src/core/hle/service/am/am.cpp                | 38 +++++++------
 src/core/hle/service/am/am.h                  | 16 +++---
 src/core/hle/service/am/applets/applets.cpp   | 31 +++++++----
 src/core/hle/service/am/applets/applets.h     | 17 +++---
 src/core/hle/service/aoc/aoc_u.cpp            | 13 +++--
 src/core/hle/service/aoc/aoc_u.h              |  6 +-
 src/core/hle/service/audio/audout_u.cpp       | 14 +++--
 src/core/hle/service/audio/audren_u.cpp       | 24 +++++---
 src/core/hle/service/btdrv/btdrv.cpp          | 16 ++++--
 src/core/hle/service/btm/btm.cpp              | 55 ++++++++++++-------
 src/core/hle/service/hid/controllers/npad.cpp | 14 +++--
 src/core/hle/service/hid/controllers/npad.h   | 11 +++-
 src/core/hle/service/hid/hid.cpp              |  3 +-
 src/core/hle/service/nfp/nfp.cpp              | 35 +++++++-----
 src/core/hle/service/nfp/nfp.h                | 10 +++-
 src/core/hle/service/nifm/nifm.cpp            | 18 ++++--
 src/core/hle/service/nim/nim.cpp              | 16 ++++--
 src/core/hle/service/nvdrv/interface.cpp      | 11 +++-
 src/core/hle/service/nvdrv/interface.h        |  7 ++-
 .../hle/service/nvflinger/buffer_queue.cpp    | 17 +++++-
 src/core/hle/service/nvflinger/buffer_queue.h | 15 +++--
 src/core/hle/service/nvflinger/nvflinger.cpp  | 13 +++--
 src/core/hle/service/nvflinger/nvflinger.h    | 11 +++-
 src/core/hle/service/vi/vi.cpp                |  5 +-
 src/yuzu/debugger/wait_tree.cpp               |  9 +--
 src/yuzu/debugger/wait_tree.h                 |  4 +-
 29 files changed, 287 insertions(+), 164 deletions(-)

diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 23e5d3f100..2e59894ab4 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -8,7 +8,7 @@
 #include "audio_core/codec.h"
 #include "common/assert.h"
 #include "common/logging/log.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/memory.h"
 
 namespace AudioCore {
@@ -72,7 +72,7 @@ private:
     EffectInStatus info{};
 };
 AudioRenderer::AudioRenderer(AudioRendererParameter params,
-                             Kernel::SharedPtr<Kernel::Event> buffer_event)
+                             Kernel::SharedPtr<Kernel::WritableEvent> buffer_event)
     : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count),
       effects(params.effect_count) {
 
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index 71ba4be40a..7826881bf5 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -15,7 +15,7 @@
 #include "core/hle/kernel/object.h"
 
 namespace Kernel {
-class Event;
+class WritableEvent;
 }
 
 namespace AudioCore {
@@ -208,7 +208,8 @@ static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size
 
 class AudioRenderer {
 public:
-    AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event);
+    AudioRenderer(AudioRendererParameter params,
+                  Kernel::SharedPtr<Kernel::WritableEvent> buffer_event);
     ~AudioRenderer();
 
     std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
@@ -224,7 +225,7 @@ private:
     class VoiceState;
 
     AudioRendererParameter worker_params;
-    Kernel::SharedPtr<Kernel::Event> buffer_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> buffer_event;
     std::vector<VoiceState> voices;
     std::vector<EffectState> effects;
     std::unique_ptr<AudioOut> audio_out;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 5e9660a484..85a9c50fbe 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -20,17 +20,18 @@
 #include "core/hle/kernel/address_arbiter.h"
 #include "core/hle/kernel/client_port.h"
 #include "core/hle/kernel/client_session.h"
-#include "core/hle/kernel/event.h"
 #include "core/hle/kernel/handle_table.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/mutex.h"
 #include "core/hle/kernel/process.h"
+#include "core/hle/kernel/readable_event.h"
 #include "core/hle/kernel/resource_limit.h"
 #include "core/hle/kernel/scheduler.h"
 #include "core/hle/kernel/shared_memory.h"
 #include "core/hle/kernel/svc.h"
 #include "core/hle/kernel/svc_wrap.h"
 #include "core/hle/kernel/thread.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/lock.h"
 #include "core/hle/result.h"
 #include "core/hle/service/service.h"
@@ -1361,11 +1362,11 @@ static ResultCode ResetSignal(Handle handle) {
     LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle);
 
     const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
-    auto event = handle_table.Get<Event>(handle);
+    auto event = handle_table.Get<ReadableEvent>(handle);
 
     ASSERT(event != nullptr);
 
-    event->Clear();
+    event->PromoteToWritable()->Clear();
     return RESULT_SUCCESS;
 }
 
@@ -1524,13 +1525,13 @@ static ResultCode ClearEvent(Handle handle) {
     LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
 
     const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
-    SharedPtr<Event> evt = handle_table.Get<Event>(handle);
+    SharedPtr<ReadableEvent> evt = handle_table.Get<ReadableEvent>(handle);
     if (evt == nullptr) {
         LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle);
         return ERR_INVALID_HANDLE;
     }
 
-    evt->Clear();
+    evt->PromoteToWritable()->Clear();
     return RESULT_SUCCESS;
 }
 
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index d595c37b0a..43c91e521d 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -9,9 +9,11 @@
 #include "audio_core/audio_renderer.h"
 #include "core/core.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/process.h"
+#include "core/hle/kernel/readable_event.h"
 #include "core/hle/kernel/shared_memory.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/acc/profile_manager.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/applet_ae.h"
@@ -208,8 +210,8 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
     RegisterHandlers(functions);
 
     auto& kernel = Core::System::GetInstance().Kernel();
-    launchable_event =
-        Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "ISelfController:LaunchableEvent");
+    launchable_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::Sticky, "ISelfController:LaunchableEvent");
 }
 
 ISelfController::~ISelfController() = default;
@@ -299,8 +301,7 @@ void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext&
 
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(launchable_event);
-}
+    rb.PushCopyObjects(event->second);
 
 void ISelfController::SetScreenShotImageOrientation(Kernel::HLERequestContext& ctx) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
@@ -348,20 +349,26 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
 
 AppletMessageQueue::AppletMessageQueue() {
     auto& kernel = Core::System::GetInstance().Kernel();
-    on_new_message = Kernel::Event::Create(kernel, Kernel::ResetType::Sticky,
-                                           "AMMessageQueue:OnMessageRecieved");
-    on_operation_mode_changed = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
-                                                      "AMMessageQueue:OperationModeChanged");
+    on_new_message = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::Sticky, "AMMessageQueue:OnMessageRecieved");
+    on_operation_mode_changed = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::OneShot, "AMMessageQueue:OperationModeChanged");
 }
 
 AppletMessageQueue::~AppletMessageQueue() = default;
 
-const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetMesssageRecieveEvent() const {
-    return on_new_message;
+const Kernel::SharedPtr<Kernel::ReadableEvent>& AppletMessageQueue::GetMesssageRecieveEvent()
+    const {
+    const auto& event{
+        Core::System::GetInstance().Kernel().FindNamedEvent("AMMessageQueue:OnMessageRecieved")};
+    return event->second;
 }
 
-const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetOperationModeChangedEvent() const {
-    return on_operation_mode_changed;
+const Kernel::SharedPtr<Kernel::ReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent()
+    const {
+    const auto& event{
+        Core::System::GetInstance().Kernel().FindNamedEvent("AMMessageQueue:OperationModeChanged")};
+    return event->second;
 }
 
 void AppletMessageQueue::PushMessage(AppletMessage msg) {
@@ -426,9 +433,6 @@ ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_q
     // clang-format on
 
     RegisterHandlers(functions);
-
-    auto& kernel = Core::System::GetInstance().Kernel();
-    event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
 }
 
 ICommonStateGetter::~ICommonStateGetter() = default;
@@ -564,8 +568,8 @@ private:
     void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) {
         LOG_DEBUG(Service_AM, "called");
 
+        applet->GetBroker().SignalStateChanged();
         const auto event = applet->GetBroker().GetStateChangedEvent();
-        event->Signal();
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 44c1bcde5d..ef90b07024 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -9,8 +9,9 @@
 #include "core/hle/service/service.h"
 
 namespace Kernel {
-class Event;
-}
+class ReadableEvent;
+class WritableEvent;
+} // namespace Kernel
 
 namespace Service {
 namespace NVFlinger {
@@ -52,8 +53,8 @@ public:
     AppletMessageQueue();
     ~AppletMessageQueue();
 
-    const Kernel::SharedPtr<Kernel::Event>& GetMesssageRecieveEvent() const;
-    const Kernel::SharedPtr<Kernel::Event>& GetOperationModeChangedEvent() const;
+    const Kernel::SharedPtr<Kernel::ReadableEvent>& GetMesssageRecieveEvent() const;
+    const Kernel::SharedPtr<Kernel::ReadableEvent>& GetOperationModeChangedEvent() const;
     void PushMessage(AppletMessage msg);
     AppletMessage PopMessage();
     std::size_t GetMessageCount() const;
@@ -61,8 +62,8 @@ public:
 
 private:
     std::queue<AppletMessage> messages;
-    Kernel::SharedPtr<Kernel::Event> on_new_message;
-    Kernel::SharedPtr<Kernel::Event> on_operation_mode_changed;
+    Kernel::SharedPtr<Kernel::WritableEvent> on_new_message;
+    Kernel::SharedPtr<Kernel::WritableEvent> on_operation_mode_changed;
 };
 
 class IWindowController final : public ServiceFramework<IWindowController> {
@@ -122,7 +123,7 @@ private:
     void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
 
     std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
-    Kernel::SharedPtr<Kernel::Event> launchable_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> launchable_event;
     u32 idle_time_detection_extension = 0;
 };
 
@@ -151,7 +152,6 @@ private:
     void GetBootMode(Kernel::HLERequestContext& ctx);
     void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
 
-    Kernel::SharedPtr<Kernel::Event> event;
     std::shared_ptr<AppletMessageQueue> msg_queue;
 };
 
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index becbadd060..4942053229 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -5,8 +5,9 @@
 #include <cstring>
 #include "common/assert.h"
 #include "core/core.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/readable_event.h"
 #include "core/hle/kernel/server_port.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/am/am.h"
 #include "core/hle/service/am/applets/applets.h"
 
@@ -14,11 +15,11 @@ namespace Service::AM::Applets {
 
 AppletDataBroker::AppletDataBroker() {
     auto& kernel = Core::System::GetInstance().Kernel();
-    state_changed_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
-                                                "ILibraryAppletAccessor:StateChangedEvent");
-    pop_out_data_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
-                                               "ILibraryAppletAccessor:PopDataOutEvent");
-    pop_interactive_out_data_event = Kernel::Event::Create(
+    state_changed_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::OneShot, "ILibraryAppletAccessor:StateChangedEvent");
+    pop_out_data_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::OneShot, "ILibraryAppletAccessor:PopDataOutEvent");
+    pop_interactive_out_data_event = Kernel::WritableEvent::CreateRegisteredEventPair(
         kernel, Kernel::ResetType::OneShot, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
 }
 
@@ -82,16 +83,22 @@ void AppletDataBroker::SignalStateChanged() const {
     state_changed_event->Signal();
 }
 
-Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetNormalDataEvent() const {
-    return pop_out_data_event;
+Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetNormalDataEvent() const {
+    const auto& event{Core::System::GetInstance().Kernel().FindNamedEvent(
+        "ILibraryAppletAccessor:PopDataOutEvent")};
+    return event->second;
 }
 
-Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetInteractiveDataEvent() const {
-    return pop_interactive_out_data_event;
+Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const {
+    const auto& event{Core::System::GetInstance().Kernel().FindNamedEvent(
+        "ILibraryAppletAccessor:PopInteractiveDataOutEvent")};
+    return event->second;
 }
 
-Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetStateChangedEvent() const {
-    return state_changed_event;
+Kernel::SharedPtr<Kernel::ReadableEvent> AppletDataBroker::GetStateChangedEvent() const {
+    const auto& event{Core::System::GetInstance().Kernel().FindNamedEvent(
+        "ILibraryAppletAccessor:StateChangedEvent")};
+    return event->second;
 }
 
 Applet::Applet() = default;
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index f65ea119c8..5cd6232ccd 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -12,8 +12,9 @@
 union ResultCode;
 
 namespace Kernel {
-class Event;
-}
+class ReadableEvent;
+class WritableEvent;
+} // namespace Kernel
 
 namespace Service::AM {
 
@@ -40,9 +41,9 @@ public:
 
     void SignalStateChanged() const;
 
-    Kernel::SharedPtr<Kernel::Event> GetNormalDataEvent() const;
-    Kernel::SharedPtr<Kernel::Event> GetInteractiveDataEvent() const;
-    Kernel::SharedPtr<Kernel::Event> GetStateChangedEvent() const;
+    Kernel::SharedPtr<Kernel::ReadableEvent> GetNormalDataEvent() const;
+    Kernel::SharedPtr<Kernel::ReadableEvent> GetInteractiveDataEvent() const;
+    Kernel::SharedPtr<Kernel::ReadableEvent> GetStateChangedEvent() const;
 
 private:
     // Queues are named from applet's perspective
@@ -59,13 +60,13 @@ private:
     // PopInteractiveDataToGame and PushInteractiveDataFromApplet
     std::queue<std::unique_ptr<IStorage>> out_interactive_channel;
 
-    Kernel::SharedPtr<Kernel::Event> state_changed_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> state_changed_event;
 
     // Signaled on PushNormalDataFromApplet
-    Kernel::SharedPtr<Kernel::Event> pop_out_data_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> pop_out_data_event;
 
     // Signaled on PushInteractiveDataFromApplet
-    Kernel::SharedPtr<Kernel::Event> pop_interactive_out_data_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> pop_interactive_out_data_event;
 };
 
 class Applet {
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index bacf19de23..a89f99dc79 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -13,8 +13,10 @@
 #include "core/file_sys/patch_manager.h"
 #include "core/file_sys/registered_cache.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/process.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/aoc/aoc_u.h"
 #include "core/hle/service/filesystem/filesystem.h"
 #include "core/loader/loader.h"
@@ -61,8 +63,8 @@ AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs
     RegisterHandlers(functions);
 
     auto& kernel = Core::System::GetInstance().Kernel();
-    aoc_change_event = Kernel::Event::Create(kernel, Kernel::ResetType::Sticky,
-                                             "GetAddOnContentListChanged:Event");
+    aoc_change_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::Sticky, "GetAddOnContentListChanged:Event");
 }
 
 AOC_U::~AOC_U() = default;
@@ -142,9 +144,12 @@ void AOC_U::PrepareAddOnContent(Kernel::HLERequestContext& ctx) {
 void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) {
     LOG_WARNING(Service_AOC, "(STUBBED) called");
 
+    const auto& event{
+        Core::System::GetInstance().Kernel().FindNamedEvent("GetAddOnContentListChanged:Event")};
+
     IPC::ResponseBuilder rb{ctx, 2, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(aoc_change_event);
+    rb.PushCopyObjects(event->second);
 }
 
 void InstallInterfaces(SM::ServiceManager& service_manager) {
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h
index 68d94fdaa3..f32a757aa0 100644
--- a/src/core/hle/service/aoc/aoc_u.h
+++ b/src/core/hle/service/aoc/aoc_u.h
@@ -6,6 +6,10 @@
 
 #include "core/hle/service/service.h"
 
+namespace Kernel {
+class WritableEvent;
+}
+
 namespace Service::AOC {
 
 class AOC_U final : public ServiceFramework<AOC_U> {
@@ -21,7 +25,7 @@ private:
     void GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx);
 
     std::vector<u64> add_on_content;
-    Kernel::SharedPtr<Kernel::Event> aoc_change_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> aoc_change_event;
 };
 
 /// Registers all AOC services with the specified service manager.
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 2ee9bc2734..b5012e5796 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -13,8 +13,10 @@
 #include "common/swap.h"
 #include "core/core.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
 #include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/audio/audout_u.h"
 #include "core/memory.h"
 
@@ -67,8 +69,8 @@ public:
 
         // This is the event handle used to check if the audio buffer was released
         auto& kernel = Core::System::GetInstance().Kernel();
-        buffer_event =
-            Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "IAudioOutBufferReleased");
+        buffer_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::Sticky, "IAudioOutBufferReleased");
 
         stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count,
                                        std::move(unique_name), [=]() { buffer_event->Signal(); });
@@ -121,7 +123,9 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(buffer_event);
+        const auto& event{
+            Core::System::GetInstance().Kernel().FindNamedEvent("IAudioOutBufferReleased")};
+        rb.PushCopyObjects(event->second);
     }
 
     void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
@@ -188,7 +192,7 @@ private:
     AudoutParams audio_params{};
 
     /// This is the evend handle used to check if the audio buffer was released
-    Kernel::SharedPtr<Kernel::Event> buffer_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> buffer_event;
 };
 
 void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 1c418a9bb2..9b7f7b2013 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -12,8 +12,10 @@
 #include "common/logging/log.h"
 #include "core/core.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
 #include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/audio/audren_u.h"
 
 namespace Service::Audio {
@@ -41,8 +43,8 @@ public:
         RegisterHandlers(functions);
 
         auto& kernel = Core::System::GetInstance().Kernel();
-        system_event =
-            Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent");
+        system_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent");
         renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event);
     }
 
@@ -112,7 +114,9 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(system_event);
+        const auto& event{
+            Core::System::GetInstance().Kernel().FindNamedEvent("IAudioRenderer:SystemEvent")};
+        rb.PushCopyObjects(event->second);
     }
 
     void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) {
@@ -135,7 +139,7 @@ private:
         rb.Push(rendering_time_limit_percent);
     }
 
-    Kernel::SharedPtr<Kernel::Event> system_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> system_event;
     std::unique_ptr<AudioCore::AudioRenderer> renderer;
     u32 rendering_time_limit_percent = 100;
 };
@@ -162,8 +166,8 @@ public:
         RegisterHandlers(functions);
 
         auto& kernel = Core::System::GetInstance().Kernel();
-        buffer_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
-                                             "IAudioOutBufferReleasedEvent");
+        buffer_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "IAudioOutBufferReleasedEvent");
     }
 
 private:
@@ -211,7 +215,9 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(buffer_event);
+        const auto& event{
+            Core::System::GetInstance().Kernel().FindNamedEvent("IAudioOutBufferReleasedEvent")};
+        rb.PushCopyObjects(event->second);
     }
 
     void GetActiveChannelCount(Kernel::HLERequestContext& ctx) {
@@ -222,7 +228,7 @@ private:
         rb.Push<u32>(1);
     }
 
-    Kernel::SharedPtr<Kernel::Event> buffer_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> buffer_event;
 
 }; // namespace Audio
 
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index 2eadcdd051..04c78e81ab 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -4,8 +4,10 @@
 
 #include "common/logging/log.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
 #include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/btdrv/btdrv.h"
 #include "core/hle/service/service.h"
 #include "core/hle/service/sm/sm.h"
@@ -30,20 +32,22 @@ public:
         };
         // clang-format on
         RegisterHandlers(functions);
+
+        auto& kernel = Core::System::GetInstance().Kernel();
+        register_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "BT:RegisterEvent");
     }
 
 private:
     void RegisterEvent(Kernel::HLERequestContext& ctx) {
         LOG_WARNING(Service_BTM, "(STUBBED) called");
 
-        auto& kernel = Core::System::GetInstance().Kernel();
-        register_event =
-            Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "BT:RegisterEvent");
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(register_event);
+        const auto& event{Core::System::GetInstance().Kernel().FindNamedEvent("BT:RegisterEvent")};
+        rb.PushCopyObjects(event->second);
     }
-    Kernel::SharedPtr<Kernel::Event> register_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> register_event;
 };
 
 class BtDrv final : public ServiceFramework<BtDrv> {
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index 463a793514..3ee2981610 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -6,8 +6,10 @@
 
 #include "common/logging/log.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
 #include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/btm/btm.h"
 #include "core/hle/service/service.h"
 
@@ -53,53 +55,64 @@ public:
         };
         // clang-format on
         RegisterHandlers(functions);
+
+        auto& kernel = Core::System::GetInstance().Kernel();
+        scan_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "IBtmUserCore:ScanEvent");
+        connection_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "IBtmUserCore:ConnectionEvent");
+        service_discovery = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "IBtmUserCore:Discovery");
+        config_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "IBtmUserCore:ConfigEvent");
     }
 
 private:
     void GetScanEvent(Kernel::HLERequestContext& ctx) {
         LOG_WARNING(Service_BTM, "(STUBBED) called");
 
-        auto& kernel = Core::System::GetInstance().Kernel();
-        scan_event =
-            Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IBtmUserCore:ScanEvent");
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(scan_event);
+
+        const auto& event{
+            Core::System::GetInstance().Kernel().FindNamedEvent("IBtmUserCore:ScanEvent")};
+        rb.PushCopyObjects(event->second);
     }
     void GetConnectionEvent(Kernel::HLERequestContext& ctx) {
         LOG_WARNING(Service_BTM, "(STUBBED) called");
 
-        auto& kernel = Core::System::GetInstance().Kernel();
-        connection_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
-                                                 "IBtmUserCore:ConnectionEvent");
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(connection_event);
+
+        const auto& event{
+            Core::System::GetInstance().Kernel().FindNamedEvent("IBtmUserCore:ConnectionEvent")};
+        rb.PushCopyObjects(event->second);
     }
     void GetDiscoveryEvent(Kernel::HLERequestContext& ctx) {
         LOG_WARNING(Service_BTM, "(STUBBED) called");
 
-        auto& kernel = Core::System::GetInstance().Kernel();
-        service_discovery =
-            Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IBtmUserCore:Discovery");
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(service_discovery);
+
+        const auto& event{
+            Core::System::GetInstance().Kernel().FindNamedEvent("IBtmUserCore:Discovery")};
+        rb.PushCopyObjects(event->second);
     }
     void GetConfigEvent(Kernel::HLERequestContext& ctx) {
         LOG_WARNING(Service_BTM, "(STUBBED) called");
 
-        auto& kernel = Core::System::GetInstance().Kernel();
-        config_event =
-            Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IBtmUserCore:ConfigEvent");
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(config_event);
+
+        const auto& event{
+            Core::System::GetInstance().Kernel().FindNamedEvent("IBtmUserCore:ConfigEvent")};
+        rb.PushCopyObjects(event->second);
     }
-    Kernel::SharedPtr<Kernel::Event> scan_event;
-    Kernel::SharedPtr<Kernel::Event> connection_event;
-    Kernel::SharedPtr<Kernel::Event> service_discovery;
-    Kernel::SharedPtr<Kernel::Event> config_event;
+
+    Kernel::SharedPtr<Kernel::WritableEvent> scan_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> connection_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> service_discovery;
+    Kernel::SharedPtr<Kernel::WritableEvent> config_event;
 };
 
 class BTM_USR final : public ServiceFramework<BTM_USR> {
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 22e87a50a2..df39a6dc44 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -12,7 +12,9 @@
 #include "core/core.h"
 #include "core/core_timing.h"
 #include "core/frontend/input.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/hid/controllers/npad.h"
 #include "core/settings.h"
 
@@ -167,8 +169,8 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
 
 void Controller_NPad::OnInit() {
     auto& kernel = Core::System::GetInstance().Kernel();
-    styleset_changed_event =
-        Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "npad:NpadStyleSetChanged");
+    styleset_changed_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::OneShot, "npad:NpadStyleSetChanged");
 
     if (!IsControllerActivated()) {
         return;
@@ -538,11 +540,13 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
     last_processed_vibration = vibrations.back();
 }
 
-Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() const {
+Kernel::SharedPtr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent() const {
     // TODO(ogniK): Figure out the best time to signal this event. This event seems that it should
     // be signalled at least once, and signaled after a new controller is connected?
     styleset_changed_event->Signal();
-    return styleset_changed_event;
+    const auto& event{
+        Core::System::GetInstance().Kernel().FindNamedEvent("npad:NpadStyleSetChanged")};
+    return event->second;
 }
 
 Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index abff6544d5..c960d0f577 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -8,10 +8,15 @@
 #include "common/bit_field.h"
 #include "common/common_types.h"
 #include "core/frontend/input.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/object.h"
 #include "core/hle/service/hid/controllers/controller_base.h"
 #include "core/settings.h"
 
+namespace Kernel {
+class ReadableEvent;
+class WritableEvent;
+} // namespace Kernel
+
 namespace Service::HID {
 
 constexpr u32 NPAD_HANDHELD = 32;
@@ -108,7 +113,7 @@ public:
     void VibrateController(const std::vector<u32>& controller_ids,
                            const std::vector<Vibration>& vibrations);
 
-    Kernel::SharedPtr<Kernel::Event> GetStyleSetChangedEvent() const;
+    Kernel::SharedPtr<Kernel::ReadableEvent> GetStyleSetChangedEvent() const;
     Vibration GetLastVibration() const;
 
     void AddNewController(NPadControllerType controller);
@@ -303,7 +308,7 @@ private:
         sticks;
     std::vector<u32> supported_npad_id_types{};
     NpadHoldType hold_type{NpadHoldType::Vertical};
-    Kernel::SharedPtr<Kernel::Event> styleset_changed_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> styleset_changed_event;
     Vibration last_processed_vibration{};
     std::array<ControllerHolder, 10> connected_controllers{};
     bool can_controllers_vibrate{true};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 46496e9bb1..2ec38c726a 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -13,8 +13,9 @@
 #include "core/hle/ipc_helpers.h"
 #include "core/hle/kernel/client_port.h"
 #include "core/hle/kernel/client_session.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/readable_event.h"
 #include "core/hle/kernel/shared_memory.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/hid/hid.h"
 #include "core/hle/service/hid/irs.h"
 #include "core/hle/service/hid/xcd.h"
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index ff9170c240..75c6053640 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -7,7 +7,9 @@
 #include "common/logging/log.h"
 #include "core/core.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/lock.h"
 #include "core/hle/service/hid/hid.h"
 #include "core/hle/service/nfp/nfp.h"
@@ -23,8 +25,8 @@ constexpr ResultCode ERR_TAG_FAILED(ErrorModule::NFP,
 Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
     : ServiceFramework(name), module(std::move(module)) {
     auto& kernel = Core::System::GetInstance().Kernel();
-    nfc_tag_load =
-        Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IUser:NFCTagDetected");
+    nfc_tag_load = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::OneShot, "IUser:NFCTagDetected");
 }
 
 Module::Interface::~Interface() = default;
@@ -63,10 +65,10 @@ public:
         RegisterHandlers(functions);
 
         auto& kernel = Core::System::GetInstance().Kernel();
-        deactivate_event =
-            Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IUser:DeactivateEvent");
-        availability_change_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
-                                                          "IUser:AvailabilityChangeEvent");
+        deactivate_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "IUser:DeactivateEvent");
+        availability_change_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "IUser:AvailabilityChangeEvent");
     }
 
 private:
@@ -164,7 +166,10 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(deactivate_event);
+
+        const auto& event{
+            Core::System::GetInstance().Kernel().FindNamedEvent("IUser:DeactivateEvent")};
+        rb.PushCopyObjects(event->second);
     }
 
     void StopDetection(Kernel::HLERequestContext& ctx) {
@@ -264,7 +269,9 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(availability_change_event);
+        const auto& event{
+            Core::System::GetInstance().Kernel().FindNamedEvent("IUser:AvailabilityChangeEvent")};
+        rb.PushCopyObjects(event->second);
     }
 
     void GetRegisterInfo(Kernel::HLERequestContext& ctx) {
@@ -319,8 +326,8 @@ private:
     const u32 npad_id{0}; // Player 1 controller
     State state{State::NonInitialized};
     DeviceState device_state{DeviceState::Initialized};
-    Kernel::SharedPtr<Kernel::Event> deactivate_event;
-    Kernel::SharedPtr<Kernel::Event> availability_change_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> deactivate_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> availability_change_event;
     const Module::Interface& nfp_interface;
 };
 
@@ -342,8 +349,10 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
     nfc_tag_load->Signal();
     return true;
 }
-const Kernel::SharedPtr<Kernel::Event>& Module::Interface::GetNFCEvent() const {
-    return nfc_tag_load;
+
+const Kernel::SharedPtr<Kernel::ReadableEvent>& Module::Interface::GetNFCEvent() const {
+    const auto& event{Core::System::GetInstance().Kernel().FindNamedEvent("IUser:NFCTagDetected")};
+    return event->second;
 }
 const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const {
     return amiibo;
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h
index 5c0ae8a547..0ab1ca9970 100644
--- a/src/core/hle/service/nfp/nfp.h
+++ b/src/core/hle/service/nfp/nfp.h
@@ -6,9 +6,13 @@
 
 #include <array>
 #include <vector>
-#include "core/hle/kernel/event.h"
 #include "core/hle/service/service.h"
 
+namespace Kernel {
+class ReadableEvent;
+class WritableEvent;
+} // namespace Kernel
+
 namespace Service::NFP {
 
 class Module final {
@@ -33,11 +37,11 @@ public:
 
         void CreateUserInterface(Kernel::HLERequestContext& ctx);
         bool LoadAmiibo(const std::vector<u8>& buffer);
-        const Kernel::SharedPtr<Kernel::Event>& GetNFCEvent() const;
+        const Kernel::SharedPtr<Kernel::ReadableEvent>& GetNFCEvent() const;
         const AmiiboFile& GetAmiiboBuffer() const;
 
     private:
-        Kernel::SharedPtr<Kernel::Event> nfc_tag_load{};
+        Kernel::SharedPtr<Kernel::WritableEvent> nfc_tag_load{};
         AmiiboFile amiibo{};
 
     protected:
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index dee3912015..80a66bce39 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -4,7 +4,9 @@
 
 #include "core/core.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/nifm/nifm.h"
 #include "core/hle/service/service.h"
 
@@ -56,8 +58,10 @@ public:
         RegisterHandlers(functions);
 
         auto& kernel = Core::System::GetInstance().Kernel();
-        event1 = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IRequest:Event1");
-        event2 = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IRequest:Event2");
+        event1 = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "IRequest:Event1");
+        event2 = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot, "IRequest:Event2");
     }
 
 private:
@@ -88,7 +92,11 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 2};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(event1, event2);
+
+        const auto& event1{Core::System::GetInstance().Kernel().FindNamedEvent("IRequest:Event1")};
+        const auto& event2{Core::System::GetInstance().Kernel().FindNamedEvent("IRequest:Event2")};
+
+        rb.PushCopyObjects(event1->second, event2->second);
     }
 
     void Cancel(Kernel::HLERequestContext& ctx) {
@@ -105,7 +113,7 @@ private:
         rb.Push(RESULT_SUCCESS);
     }
 
-    Kernel::SharedPtr<Kernel::Event> event1, event2;
+    Kernel::SharedPtr<Kernel::WritableEvent> event1, event2;
 };
 
 class INetworkProfile final : public ServiceFramework<INetworkProfile> {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index 1bbccd4445..d181a781cf 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -6,7 +6,9 @@
 #include <ctime>
 #include "core/core.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/nim/nim.h"
 #include "core/hle/service/service.h"
 #include "core/hle/service/sm/sm.h"
@@ -138,13 +140,13 @@ public:
         RegisterHandlers(functions);
 
         auto& kernel = Core::System::GetInstance().Kernel();
-        finished_event =
-            Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
-                                  "IEnsureNetworkClockAvailabilityService:FinishEvent");
+        finished_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+            kernel, Kernel::ResetType::OneShot,
+            "IEnsureNetworkClockAvailabilityService:FinishEvent");
     }
 
 private:
-    Kernel::SharedPtr<Kernel::Event> finished_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> finished_event;
 
     void StartTask(Kernel::HLERequestContext& ctx) {
         // No need to connect to the internet, just finish the task straight away.
@@ -160,7 +162,9 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushCopyObjects(finished_event);
+        const auto& event{Core::System::GetInstance().Kernel().FindNamedEvent(
+            "IEnsureNetworkClockAvailabilityService:FinishEvent")};
+        rb.PushCopyObjects(event->second);
     }
 
     void GetResult(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index ff76e05242..3d89b40206 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -6,7 +6,9 @@
 #include "common/logging/log.h"
 #include "core/core.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/nvdrv/interface.h"
 #include "core/hle/service/nvdrv/nvdrv.h"
 
@@ -69,7 +71,9 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
 
     IPC::ResponseBuilder rb{ctx, 3, 1};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(query_event);
+
+    const auto& event{Core::System::GetInstance().Kernel().FindNamedEvent("NVDRV::query_event")};
+    rb.PushCopyObjects(event->second);
     rb.Push<u32>(0);
 }
 
@@ -127,7 +131,8 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name)
     RegisterHandlers(functions);
 
     auto& kernel = Core::System::GetInstance().Kernel();
-    query_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "NVDRV::query_event");
+    query_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::OneShot, "NVDRV::query_event");
 }
 
 NVDRV::~NVDRV() = default;
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h
index 5a1e4baa76..a272520380 100644
--- a/src/core/hle/service/nvdrv/interface.h
+++ b/src/core/hle/service/nvdrv/interface.h
@@ -5,10 +5,13 @@
 #pragma once
 
 #include <memory>
-#include "core/hle/kernel/event.h"
 #include "core/hle/service/nvdrv/nvdrv.h"
 #include "core/hle/service/service.h"
 
+namespace Kernel {
+class WritableEvent;
+}
+
 namespace Service::Nvidia {
 
 class NVDRV final : public ServiceFramework<NVDRV> {
@@ -31,7 +34,7 @@ private:
 
     u64 pid{};
 
-    Kernel::SharedPtr<Kernel::Event> query_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> query_event;
 };
 
 } // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index 172a1a4412..7b07750b5c 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -7,14 +7,17 @@
 #include "common/assert.h"
 #include "common/logging/log.h"
 #include "core/core.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/nvflinger/buffer_queue.h"
 
 namespace Service::NVFlinger {
 
 BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {
     auto& kernel = Core::System::GetInstance().Kernel();
-    buffer_wait_event =
-        Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "BufferQueue NativeHandle");
+    buffer_wait_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::Sticky, "BufferQueue NativeHandle");
 }
 
 BufferQueue::~BufferQueue() = default;
@@ -104,4 +107,14 @@ u32 BufferQueue::Query(QueryType type) {
     return 0;
 }
 
+Kernel::SharedPtr<Kernel::WritableEvent> BufferQueue::GetWritableBufferWaitEvent() const {
+    return buffer_wait_event;
+}
+
+Kernel::SharedPtr<Kernel::ReadableEvent> BufferQueue::GetBufferWaitEvent() const {
+    const auto& event{
+        Core::System::GetInstance().Kernel().FindNamedEvent("BufferQueue NativeHandle")};
+    return event->second;
+}
+
 } // namespace Service::NVFlinger
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index 8cff5eb717..8b2a2b7de6 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -10,12 +10,17 @@
 #include "common/common_funcs.h"
 #include "common/math_util.h"
 #include "common/swap.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/object.h"
 
 namespace CoreTiming {
 struct EventType;
 }
 
+namespace Kernel {
+class ReadableEvent;
+class WritableEvent;
+} // namespace Kernel
+
 namespace Service::NVFlinger {
 
 struct IGBPBuffer {
@@ -86,16 +91,16 @@ public:
         return id;
     }
 
-    Kernel::SharedPtr<Kernel::Event> GetBufferWaitEvent() const {
-        return buffer_wait_event;
-    }
+    Kernel::SharedPtr<Kernel::WritableEvent> GetWritableBufferWaitEvent() const;
+
+    Kernel::SharedPtr<Kernel::ReadableEvent> GetBufferWaitEvent() const;
 
 private:
     u32 id;
     u64 layer_id;
 
     std::vector<Buffer> queue;
-    Kernel::SharedPtr<Kernel::Event> buffer_wait_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> buffer_wait_event;
 };
 
 } // namespace Service::NVFlinger
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 214e6d1b35..2a329cb8e4 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -13,6 +13,9 @@
 #include "core/core.h"
 #include "core/core_timing.h"
 #include "core/core_timing_util.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
 #include "core/hle/service/nvdrv/nvdrv.h"
 #include "core/hle/service/nvflinger/buffer_queue.h"
@@ -83,9 +86,10 @@ u32 NVFlinger::GetBufferQueueId(u64 display_id, u64 layer_id) {
     return layer.buffer_queue->GetId();
 }
 
-Kernel::SharedPtr<Kernel::Event> NVFlinger::GetVsyncEvent(u64 display_id) {
-    const auto& display = GetDisplay(display_id);
-    return display.vsync_event;
+Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::GetVsyncEvent(u64 display_id) {
+    const auto& event{Core::System::GetInstance().Kernel().FindNamedEvent(
+        fmt::format("Display VSync Event {}", display_id))};
+    return event->second;
 }
 
 std::shared_ptr<BufferQueue> NVFlinger::GetBufferQueue(u32 id) const {
@@ -164,7 +168,8 @@ Layer::~Layer() = default;
 
 Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) {
     auto& kernel = Core::System::GetInstance().Kernel();
-    vsync_event = Kernel::Event::Create(kernel, Kernel::ResetType::Pulse, "Display VSync Event");
+    vsync_event = Kernel::WritableEvent::CreateRegisteredEventPair(
+        kernel, Kernel::ResetType::Pulse, fmt::format("Display VSync Event {}", id));
 }
 
 Display::~Display() = default;
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 3dc69e69b6..1a9e74f351 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -10,12 +10,17 @@
 #include <vector>
 
 #include "common/common_types.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/object.h"
 
 namespace CoreTiming {
 struct EventType;
 }
 
+namespace Kernel {
+class ReadableEvent;
+class WritableEvent;
+} // namespace Kernel
+
 namespace Service::Nvidia {
 class Module;
 }
@@ -40,7 +45,7 @@ struct Display {
     std::string name;
 
     std::vector<Layer> layers;
-    Kernel::SharedPtr<Kernel::Event> vsync_event;
+    Kernel::SharedPtr<Kernel::WritableEvent> vsync_event;
 };
 
 class NVFlinger final {
@@ -61,7 +66,7 @@ public:
     u32 GetBufferQueueId(u64 display_id, u64 layer_id);
 
     /// Gets the vsync event for the specified display.
-    Kernel::SharedPtr<Kernel::Event> GetVsyncEvent(u64 display_id);
+    Kernel::SharedPtr<Kernel::ReadableEvent> GetVsyncEvent(u64 display_id);
 
     /// Obtains a buffer queue identified by the id.
     std::shared_ptr<BufferQueue> GetBufferQueue(u32 id) const;
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 5120abfffe..47beaf8f6c 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -18,7 +18,8 @@
 #include "common/swap.h"
 #include "core/core_timing.h"
 #include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/event.h"
+#include "core/hle/kernel/readable_event.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/hle/service/nvdrv/nvdrv.h"
 #include "core/hle/service/nvflinger/buffer_queue.h"
 #include "core/hle/service/nvflinger/nvflinger.h"
@@ -547,7 +548,7 @@ private:
                         IPC::ResponseBuilder rb{ctx, 2};
                         rb.Push(RESULT_SUCCESS);
                     },
-                    buffer_queue->GetBufferWaitEvent());
+                    buffer_queue->GetWritableBufferWaitEvent(), buffer_queue->GetBufferWaitEvent());
             }
         } else if (transaction == TransactionId::RequestBuffer) {
             IGBPRequestBufferRequestParcel request{ctx.ReadBuffer()};
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 0c831c9f47..797be6c4ad 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -7,7 +7,6 @@
 
 #include "common/assert.h"
 #include "core/core.h"
-#include "core/hle/kernel/event.h"
 #include "core/hle/kernel/handle_table.h"
 #include "core/hle/kernel/mutex.h"
 #include "core/hle/kernel/process.h"
@@ -15,6 +14,7 @@
 #include "core/hle/kernel/thread.h"
 #include "core/hle/kernel/timer.h"
 #include "core/hle/kernel/wait_object.h"
+#include "core/hle/kernel/writable_event.h"
 #include "core/memory.h"
 
 WaitTreeItem::WaitTreeItem() = default;
@@ -154,7 +154,7 @@ QString WaitTreeWaitObject::GetText() const {
 std::unique_ptr<WaitTreeWaitObject> WaitTreeWaitObject::make(const Kernel::WaitObject& object) {
     switch (object.GetHandleType()) {
     case Kernel::HandleType::Event:
-        return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::Event&>(object));
+        return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::WritableEvent&>(object));
     case Kernel::HandleType::Timer:
         return std::make_unique<WaitTreeTimer>(static_cast<const Kernel::Timer&>(object));
     case Kernel::HandleType::Thread:
@@ -332,7 +332,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
     return list;
 }
 
-WaitTreeEvent::WaitTreeEvent(const Kernel::Event& object) : WaitTreeWaitObject(object) {}
+WaitTreeEvent::WaitTreeEvent(const Kernel::WritableEvent& object) : WaitTreeWaitObject(object) {}
 WaitTreeEvent::~WaitTreeEvent() = default;
 
 std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const {
@@ -340,7 +340,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeEvent::GetChildren() const {
 
     list.push_back(std::make_unique<WaitTreeText>(
         tr("reset type = %1")
-            .arg(GetResetTypeQString(static_cast<const Kernel::Event&>(object).GetResetType()))));
+            .arg(GetResetTypeQString(
+                static_cast<const Kernel::WritableEvent&>(object).GetResetType()))));
     return list;
 }
 
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h
index 331f898851..c0b6e0e7f7 100644
--- a/src/yuzu/debugger/wait_tree.h
+++ b/src/yuzu/debugger/wait_tree.h
@@ -18,7 +18,7 @@ class EmuThread;
 
 namespace Kernel {
 class WaitObject;
-class Event;
+class WritableEvent;
 class Thread;
 class Timer;
 } // namespace Kernel
@@ -144,7 +144,7 @@ public:
 class WaitTreeEvent : public WaitTreeWaitObject {
     Q_OBJECT
 public:
-    explicit WaitTreeEvent(const Kernel::Event& object);
+    explicit WaitTreeEvent(const Kernel::WritableEvent& object);
     ~WaitTreeEvent() override;
 
     std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;