From d92989e7879bb1f4e6788fcc96f02e357e5c38e0 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 26 Nov 2018 18:29:50 -0500 Subject: kernel/object: Add descriptions to ResetTypes --- src/core/hle/kernel/object.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index c9f4d0bb3..69082ce3e 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -33,9 +33,9 @@ enum class HandleType : u32 { }; enum class ResetType { - OneShot, - Sticky, - Pulse, + OneShot, ///< Reset automatically on object acquisition + Sticky, ///< Never reset automatically + Pulse, ///< Reset automatically on wakeup }; class Object : NonCopyable { -- cgit v1.2.3 From c7133838161ce0c17276ef96c0decfb855510165 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 26 Nov 2018 18:31:22 -0500 Subject: kernel: Divide Event into ReadableEvent and WritableEvent More hardware accurate. On the actual system, there is a differentiation between the signaler and signalee, they form a client/server relationship much like ServerPort and ClientPort. --- src/core/hle/kernel/event.cpp | 53 ---------------------- src/core/hle/kernel/event.h | 60 ------------------------- src/core/hle/kernel/readable_event.cpp | 48 ++++++++++++++++++++ src/core/hle/kernel/readable_event.h | 56 +++++++++++++++++++++++ src/core/hle/kernel/writable_event.cpp | 81 ++++++++++++++++++++++++++++++++++ src/core/hle/kernel/writable_event.h | 75 +++++++++++++++++++++++++++++++ 6 files changed, 260 insertions(+), 113 deletions(-) delete mode 100644 src/core/hle/kernel/event.cpp delete mode 100644 src/core/hle/kernel/event.h create mode 100644 src/core/hle/kernel/readable_event.cpp create mode 100644 src/core/hle/kernel/readable_event.h create mode 100644 src/core/hle/kernel/writable_event.cpp create mode 100644 src/core/hle/kernel/writable_event.h (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp deleted file mode 100644 index 8967e602e..000000000 --- a/src/core/hle/kernel/event.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include -#include "common/assert.h" -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/object.h" -#include "core/hle/kernel/thread.h" - -namespace Kernel { - -Event::Event(KernelCore& kernel) : WaitObject{kernel} {} -Event::~Event() = default; - -SharedPtr Event::Create(KernelCore& kernel, ResetType reset_type, std::string name) { - SharedPtr evt(new Event(kernel)); - - evt->signaled = false; - evt->reset_type = reset_type; - evt->name = std::move(name); - - return evt; -} - -bool Event::ShouldWait(Thread* thread) const { - return !signaled; -} - -void Event::Acquire(Thread* thread) { - ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); - - if (reset_type == ResetType::OneShot) - signaled = false; -} - -void Event::Signal() { - signaled = true; - WakeupAllWaitingThreads(); -} - -void Event::Clear() { - signaled = false; -} - -void Event::WakeupAllWaitingThreads() { - WaitObject::WakeupAllWaitingThreads(); - - if (reset_type == ResetType::Pulse) - signaled = false; -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h deleted file mode 100644 index 27d6126b0..000000000 --- a/src/core/hle/kernel/event.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include "common/common_types.h" -#include "core/hle/kernel/object.h" -#include "core/hle/kernel/wait_object.h" - -namespace Kernel { - -class KernelCore; - -class Event final : public WaitObject { -public: - /** - * Creates an event - * @param kernel The kernel instance to create this event under. - * @param reset_type ResetType describing how to create event - * @param name Optional name of event - */ - static SharedPtr Create(KernelCore& kernel, ResetType reset_type, - std::string name = "Unknown"); - - std::string GetTypeName() const override { - return "Event"; - } - std::string GetName() const override { - return name; - } - - static const HandleType HANDLE_TYPE = HandleType::Event; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - - ResetType GetResetType() const { - return reset_type; - } - - bool ShouldWait(Thread* thread) const override; - void Acquire(Thread* thread) override; - - void WakeupAllWaitingThreads() override; - - void Signal(); - void Clear(); - -private: - explicit Event(KernelCore& kernel); - ~Event() override; - - ResetType reset_type; ///< Current ResetType - - bool signaled; ///< Whether the event has already been signaled - std::string name; ///< Name of event (optional) -}; - -} // namespace Kernel diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp new file mode 100644 index 000000000..164cffbdb --- /dev/null +++ b/src/core/hle/kernel/readable_event.cpp @@ -0,0 +1,48 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include "common/assert.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/readable_event.h" +#include "core/hle/kernel/thread.h" +#include "core/hle/kernel/writable_event.h" + +namespace Kernel { + +ReadableEvent::ReadableEvent(KernelCore& kernel) : WaitObject{kernel} {} +ReadableEvent::~ReadableEvent() = default; + +bool ReadableEvent::ShouldWait(Thread* thread) const { + return !writable_event->IsSignaled(); +} + +void ReadableEvent::Acquire(Thread* thread) { + ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); + + writable_event->ResetOnAcquire(); +} + +void ReadableEvent::AddWaitingThread(SharedPtr thread) { + writable_event->AddWaitingThread(thread); +} + +void ReadableEvent::RemoveWaitingThread(Thread* thread) { + writable_event->RemoveWaitingThread(thread); +} + +void ReadableEvent::Signal() { + writable_event->Signal(); +} + +void ReadableEvent::Clear() { + writable_event->Clear(); +} + +void ReadableEvent::WakeupAllWaitingThreads() { + writable_event->WakeupAllWaitingThreads(); + writable_event->ResetOnWakeup(); +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h new file mode 100644 index 000000000..020ef4ebc --- /dev/null +++ b/src/core/hle/kernel/readable_event.h @@ -0,0 +1,56 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/wait_object.h" + +namespace Kernel { + +class KernelCore; +class WritableEvent; + +class ReadableEvent final : public WaitObject { + friend class WritableEvent; + +public: + ~ReadableEvent() override; + + std::string GetTypeName() const override { + return "ReadableEvent"; + } + std::string GetName() const override { + return name; + } + + static const HandleType HANDLE_TYPE = HandleType::Event; + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } + + bool ShouldWait(Thread* thread) const override; + void Acquire(Thread* thread) override; + + void WakeupAllWaitingThreads() override; + + void AddWaitingThread(SharedPtr thread) override; + void RemoveWaitingThread(Thread* thread) override; + + void Signal(); + void Clear(); + + SharedPtr PromoteToWritable() const { + return writable_event; + } + +private: + explicit ReadableEvent(KernelCore& kernel); + + SharedPtr writable_event; ///< WritableEvent associated with this ReadableEvent + + std::string name; ///< Name of event (optional) +}; + +} // namespace Kernel diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp new file mode 100644 index 000000000..4eb387ac0 --- /dev/null +++ b/src/core/hle/kernel/writable_event.cpp @@ -0,0 +1,81 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include "common/assert.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/readable_event.h" +#include "core/hle/kernel/thread.h" +#include "core/hle/kernel/writable_event.h" + +namespace Kernel { + +WritableEvent::WritableEvent(KernelCore& kernel) : WaitObject{kernel} {} +WritableEvent::~WritableEvent() = default; + +std::tuple, SharedPtr> WritableEvent::CreateEventPair( + KernelCore& kernel, ResetType reset_type, std::string name) { + SharedPtr writable_event(new WritableEvent(kernel)); + SharedPtr readable_event(new ReadableEvent(kernel)); + + writable_event->name = name + ":Writable"; + writable_event->signaled = false; + writable_event->reset_type = reset_type; + readable_event->name = name + ":Readable"; + readable_event->writable_event = writable_event; + + return std::make_tuple(std::move(writable_event), std::move(readable_event)); +} + +SharedPtr WritableEvent::CreateRegisteredEventPair(KernelCore& kernel, + ResetType reset_type, + std::string name) { + auto [writable_event, readable_event] = CreateEventPair(kernel, reset_type, name); + kernel.AddNamedEvent(name, std::move(readable_event)); + return std::move(writable_event); +} + +bool WritableEvent::ShouldWait(Thread* thread) const { + return !signaled; +} + +void WritableEvent::Acquire(Thread* thread) { + ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); + + if (reset_type == ResetType::OneShot) + signaled = false; +} + +void WritableEvent::Signal() { + signaled = true; + WakeupAllWaitingThreads(); +} + +void WritableEvent::Clear() { + signaled = false; +} + +void WritableEvent::ResetOnAcquire() { + if (reset_type == ResetType::OneShot) + Clear(); +} + +void WritableEvent::ResetOnWakeup() { + if (reset_type == ResetType::Pulse) + Clear(); +} + +bool WritableEvent::IsSignaled() const { + return signaled; +} + +void WritableEvent::WakeupAllWaitingThreads() { + WaitObject::WakeupAllWaitingThreads(); + + if (reset_type == ResetType::Pulse) + signaled = false; +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/writable_event.h b/src/core/hle/kernel/writable_event.h new file mode 100644 index 000000000..c0fe42302 --- /dev/null +++ b/src/core/hle/kernel/writable_event.h @@ -0,0 +1,75 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "common/common_types.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/wait_object.h" + +namespace Kernel { + +class KernelCore; +class ReadableEvent; + +class WritableEvent final : public WaitObject { +public: + ~WritableEvent() override; + + /** + * Creates an event + * @param kernel The kernel instance to create this event under. + * @param reset_type ResetType describing how to create event + * @param name Optional name of event + */ + static std::tuple, SharedPtr> CreateEventPair( + KernelCore& kernel, ResetType reset_type, std::string name = "Unknown"); + + /** + * Creates an event and registers it in the kernel's named event table + * @param kernel The kernel instance to create this event under. + * @param reset_type ResetType describing how to create event + * @param name name of event + */ + static SharedPtr CreateRegisteredEventPair(KernelCore& kernel, + ResetType reset_type, + std::string name); + + std::string GetTypeName() const override { + return "WritableEvent"; + } + std::string GetName() const override { + return name; + } + + static const HandleType HANDLE_TYPE = HandleType::Event; + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } + + ResetType GetResetType() const { + return reset_type; + } + + bool ShouldWait(Thread* thread) const override; + void Acquire(Thread* thread) override; + + void WakeupAllWaitingThreads() override; + + void Signal(); + void Clear(); + void ResetOnAcquire(); + void ResetOnWakeup(); + bool IsSignaled() const; + +private: + explicit WritableEvent(KernelCore& kernel); + + ResetType reset_type; ///< Current ResetType + + bool signaled; ///< Whether the event has already been signaled + std::string name; ///< Name of event (optional) +}; + +} // namespace Kernel -- cgit v1.2.3 From c61d2a28413bd149d58b1173fa89a250ddce03c4 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 26 Nov 2018 18:32:13 -0500 Subject: kernel: Add named event table Used to store ReadableEvents of all events on the system. --- src/core/hle/kernel/kernel.cpp | 19 +++++++++++++++++++ src/core/hle/kernel/kernel.h | 11 +++++++++++ 2 files changed, 30 insertions(+) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index e441c5bc6..9cd714586 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -17,9 +17,11 @@ #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.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/thread.h" #include "core/hle/kernel/timer.h" +#include "core/hle/kernel/writable_event.h" #include "core/hle/lock.h" #include "core/hle/result.h" @@ -175,6 +177,10 @@ struct KernelCore::Impl { // allowing us to simply use a pool index or similar. Kernel::HandleTable thread_wakeup_callback_handle_table; + /// Map of named events managed by the kernel, which are retrieved when HLE services need to + /// return an event to the system. + NamedEventTable named_events; + /// Map of named ports managed by the kernel, which can be retrieved using /// the ConnectToPort SVC. NamedPortTable named_ports; @@ -221,6 +227,19 @@ const Process* KernelCore::CurrentProcess() const { return impl->current_process; } +void KernelCore::AddNamedEvent(std::string name, SharedPtr event) { + impl->named_events.emplace(std::move(name), std::move(event)); +} + +KernelCore::NamedEventTable::iterator KernelCore::FindNamedEvent(const std::string& name) { + return impl->named_events.find(name); +} + +KernelCore::NamedEventTable::const_iterator KernelCore::FindNamedEvent( + const std::string& name) const { + return impl->named_events.find(name); +} + void KernelCore::AddNamedPort(std::string name, SharedPtr port) { impl->named_ports.emplace(std::move(name), std::move(port)); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index ea00c89f5..f12d061eb 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -20,6 +20,7 @@ namespace Kernel { class ClientPort; class HandleTable; class Process; +class ReadableEvent; class ResourceLimit; class Thread; class Timer; @@ -27,6 +28,7 @@ class Timer; /// Represents a single instance of the kernel. class KernelCore { private: + using NamedEventTable = std::unordered_map>; using NamedPortTable = std::unordered_map>; public: @@ -66,6 +68,15 @@ public: /// Retrieves a const pointer to the current process. const Process* CurrentProcess() const; + /// Adds an event to the named event table + void AddNamedEvent(std::string name, SharedPtr event); + + /// Finds an event within the named event table wit the given name. + NamedEventTable::iterator FindNamedEvent(const std::string& name); + + /// Finds an event within the named event table wit the given name. + NamedEventTable::const_iterator FindNamedEvent(const std::string& name) const; + /// Adds a port to the named port table void AddNamedPort(std::string name, SharedPtr port); -- cgit v1.2.3 From a56fc84e7a116681373ab9157193d2b8ae0f29af Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 26 Nov 2018 18:32:52 -0500 Subject: hle_ipc: Use event pair for SleepClientThread --- src/core/hle/kernel/hle_ipc.cpp | 27 +++++++++++++-------------- src/core/hle/kernel/hle_ipc.h | 14 +++++++++----- 2 files changed, 22 insertions(+), 19 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 68d5376cb..2ffdb2f5b 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -15,13 +15,14 @@ #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/handle_table.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" +#include "core/hle/kernel/readable_event.h" #include "core/hle/kernel/server_session.h" +#include "core/hle/kernel/writable_event.h" #include "core/memory.h" namespace Kernel { @@ -36,11 +37,9 @@ void SessionRequestHandler::ClientDisconnected(const SharedPtr& s boost::range::remove_erase(connected_sessions, server_session); } -SharedPtr HLERequestContext::SleepClientThread(SharedPtr thread, - const std::string& reason, u64 timeout, - WakeupCallback&& callback, - Kernel::SharedPtr event) { - +SharedPtr HLERequestContext::SleepClientThread( + SharedPtr thread, const std::string& reason, u64 timeout, WakeupCallback&& callback, + SharedPtr writable_event, SharedPtr readable_event) { // Put the client thread to sleep until the wait event is signaled or the timeout expires. thread->SetWakeupCallback([context = *this, callback]( ThreadWakeupReason reason, SharedPtr thread, @@ -51,23 +50,23 @@ SharedPtr HLERequestContext::SleepClientThread(SharedPtr thread, return true; }); - if (!event) { + auto& kernel = Core::System::GetInstance().Kernel(); + if (!writable_event || !readable_event) { // Create event if not provided - auto& kernel = Core::System::GetInstance().Kernel(); - event = - Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); + std::tie(writable_event, readable_event) = WritableEvent::CreateEventPair( + kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); } - event->Clear(); + writable_event->Clear(); thread->SetStatus(ThreadStatus::WaitHLEEvent); - thread->SetWaitObjects({event}); - event->AddWaitingThread(thread); + thread->SetWaitObjects({readable_event}); + readable_event->AddWaitingThread(thread); if (timeout > 0) { thread->WakeAfterDelay(timeout); } - return event; + return writable_event; } HLERequestContext::HLERequestContext(SharedPtr server_session) diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index a38e34b74..557940f11 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -24,10 +24,11 @@ class ServiceFrameworkBase; namespace Kernel { class Domain; -class Event; class HandleTable; class HLERequestContext; class Process; +class ReadableEvent; +class WritableEvent; /** * Interface implemented by HLE Session handlers. @@ -119,12 +120,15 @@ public: * @param callback Callback to be invoked when the thread is resumed. This callback must write * the entire command response once again, regardless of the state of it before this function * was called. - * @param event Event to use to wake up the thread. If unspecified, an event will be created. + * @param writable_event Event to use to wake up the thread. If unspecified, an event will be + * created. + * @param readable_event Event to be bound to the thread to wake up upon. * @returns Event that when signaled will resume the thread and call the callback function. */ - SharedPtr SleepClientThread(SharedPtr thread, const std::string& reason, - u64 timeout, WakeupCallback&& callback, - Kernel::SharedPtr event = nullptr); + SharedPtr SleepClientThread(SharedPtr thread, const std::string& reason, + u64 timeout, WakeupCallback&& callback, + SharedPtr writable_event = nullptr, + SharedPtr readable_event = nullptr); /// Populates this context with data from the requesting process/thread. ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, -- cgit v1.2.3 From ff610103b58b3e0dd39fafb539a1cc0bc0fae577 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 26 Nov 2018 18:34:07 -0500 Subject: core: Port all current usages of Event to Readable/WritableEvent --- src/core/hle/kernel/svc.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 5e9660a48..85a9c50fb 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(handle); + auto event = handle_table.Get(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 evt = handle_table.Get(handle); + SharedPtr evt = handle_table.Get(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; } -- cgit v1.2.3 From a342bcc9b130e9bd78720e09e04c92dcac8840d0 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 27 Nov 2018 09:18:29 -0500 Subject: kernel/event: Reference ReadableEvent from WritableEvent --- src/core/hle/kernel/hle_ipc.cpp | 6 ++-- src/core/hle/kernel/kernel.cpp | 17 ---------- src/core/hle/kernel/kernel.h | 11 ------- src/core/hle/kernel/readable_event.cpp | 24 ++++++-------- src/core/hle/kernel/readable_event.h | 17 +++++----- src/core/hle/kernel/svc.cpp | 4 +-- src/core/hle/kernel/writable_event.cpp | 57 +++++++--------------------------- src/core/hle/kernel/writable_event.h | 36 +++++++-------------- 8 files changed, 47 insertions(+), 125 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 2ffdb2f5b..21fda42d6 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -53,8 +53,10 @@ SharedPtr HLERequestContext::SleepClientThread( auto& kernel = Core::System::GetInstance().Kernel(); if (!writable_event || !readable_event) { // Create event if not provided - std::tie(writable_event, readable_event) = WritableEvent::CreateEventPair( - kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); + const auto pair = WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, + "HLE Pause Event: " + reason); + writable_event = pair.writable; + readable_event = pair.readable; } writable_event->Clear(); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 9cd714586..21d7f3483 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -177,10 +177,6 @@ struct KernelCore::Impl { // allowing us to simply use a pool index or similar. Kernel::HandleTable thread_wakeup_callback_handle_table; - /// Map of named events managed by the kernel, which are retrieved when HLE services need to - /// return an event to the system. - NamedEventTable named_events; - /// Map of named ports managed by the kernel, which can be retrieved using /// the ConnectToPort SVC. NamedPortTable named_ports; @@ -227,19 +223,6 @@ const Process* KernelCore::CurrentProcess() const { return impl->current_process; } -void KernelCore::AddNamedEvent(std::string name, SharedPtr event) { - impl->named_events.emplace(std::move(name), std::move(event)); -} - -KernelCore::NamedEventTable::iterator KernelCore::FindNamedEvent(const std::string& name) { - return impl->named_events.find(name); -} - -KernelCore::NamedEventTable::const_iterator KernelCore::FindNamedEvent( - const std::string& name) const { - return impl->named_events.find(name); -} - void KernelCore::AddNamedPort(std::string name, SharedPtr port) { impl->named_ports.emplace(std::move(name), std::move(port)); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index f12d061eb..ea00c89f5 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -20,7 +20,6 @@ namespace Kernel { class ClientPort; class HandleTable; class Process; -class ReadableEvent; class ResourceLimit; class Thread; class Timer; @@ -28,7 +27,6 @@ class Timer; /// Represents a single instance of the kernel. class KernelCore { private: - using NamedEventTable = std::unordered_map>; using NamedPortTable = std::unordered_map>; public: @@ -68,15 +66,6 @@ public: /// Retrieves a const pointer to the current process. const Process* CurrentProcess() const; - /// Adds an event to the named event table - void AddNamedEvent(std::string name, SharedPtr event); - - /// Finds an event within the named event table wit the given name. - NamedEventTable::iterator FindNamedEvent(const std::string& name); - - /// Finds an event within the named event table wit the given name. - NamedEventTable::const_iterator FindNamedEvent(const std::string& name) const; - /// Adds a port to the named port table void AddNamedPort(std::string name, SharedPtr port); diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp index 164cffbdb..92e16b4e6 100644 --- a/src/core/hle/kernel/readable_event.cpp +++ b/src/core/hle/kernel/readable_event.cpp @@ -15,34 +15,30 @@ ReadableEvent::ReadableEvent(KernelCore& kernel) : WaitObject{kernel} {} ReadableEvent::~ReadableEvent() = default; bool ReadableEvent::ShouldWait(Thread* thread) const { - return !writable_event->IsSignaled(); + return !signaled; } void ReadableEvent::Acquire(Thread* thread) { ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); - writable_event->ResetOnAcquire(); -} - -void ReadableEvent::AddWaitingThread(SharedPtr thread) { - writable_event->AddWaitingThread(thread); -} - -void ReadableEvent::RemoveWaitingThread(Thread* thread) { - writable_event->RemoveWaitingThread(thread); + if (reset_type == ResetType::OneShot) + signaled = false; } void ReadableEvent::Signal() { - writable_event->Signal(); + signaled = true; + WakeupAllWaitingThreads(); } void ReadableEvent::Clear() { - writable_event->Clear(); + signaled = false; } void ReadableEvent::WakeupAllWaitingThreads() { - writable_event->WakeupAllWaitingThreads(); - writable_event->ResetOnWakeup(); + WaitObject::WakeupAllWaitingThreads(); + + if (reset_type == ResetType::Pulse) + signaled = false; } } // namespace Kernel diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h index 020ef4ebc..b1f1f4871 100644 --- a/src/core/hle/kernel/readable_event.h +++ b/src/core/hle/kernel/readable_event.h @@ -25,6 +25,10 @@ public: return name; } + ResetType GetResetType() const { + return reset_type; + } + static const HandleType HANDLE_TYPE = HandleType::Event; HandleType GetHandleType() const override { return HANDLE_TYPE; @@ -35,20 +39,15 @@ public: void WakeupAllWaitingThreads() override; - void AddWaitingThread(SharedPtr thread) override; - void RemoveWaitingThread(Thread* thread) override; - - void Signal(); void Clear(); - SharedPtr PromoteToWritable() const { - return writable_event; - } - private: explicit ReadableEvent(KernelCore& kernel); - SharedPtr writable_event; ///< WritableEvent associated with this ReadableEvent + void Signal(); + + ResetType reset_type; + bool signaled; std::string name; ///< Name of event (optional) }; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 85a9c50fb..abc48ee54 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1366,7 +1366,7 @@ static ResultCode ResetSignal(Handle handle) { ASSERT(event != nullptr); - event->PromoteToWritable()->Clear(); + event->Clear(); return RESULT_SUCCESS; } @@ -1531,7 +1531,7 @@ static ResultCode ClearEvent(Handle handle) { return ERR_INVALID_HANDLE; } - evt->PromoteToWritable()->Clear(); + evt->Clear(); return RESULT_SUCCESS; } diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp index 4eb387ac0..27d7ff734 100644 --- a/src/core/hle/kernel/writable_event.cpp +++ b/src/core/hle/kernel/writable_event.cpp @@ -12,70 +12,37 @@ namespace Kernel { -WritableEvent::WritableEvent(KernelCore& kernel) : WaitObject{kernel} {} +WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {} WritableEvent::~WritableEvent() = default; -std::tuple, SharedPtr> WritableEvent::CreateEventPair( - KernelCore& kernel, ResetType reset_type, std::string name) { +EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_type, + std::string name) { SharedPtr writable_event(new WritableEvent(kernel)); SharedPtr readable_event(new ReadableEvent(kernel)); writable_event->name = name + ":Writable"; - writable_event->signaled = false; - writable_event->reset_type = reset_type; + writable_event->readable = readable_event; readable_event->name = name + ":Readable"; - readable_event->writable_event = writable_event; + readable_event->signaled = false; + readable_event->reset_type = reset_type; - return std::make_tuple(std::move(writable_event), std::move(readable_event)); + return {std::move(readable_event), std::move(writable_event)}; } -SharedPtr WritableEvent::CreateRegisteredEventPair(KernelCore& kernel, - ResetType reset_type, - std::string name) { - auto [writable_event, readable_event] = CreateEventPair(kernel, reset_type, name); - kernel.AddNamedEvent(name, std::move(readable_event)); - return std::move(writable_event); -} - -bool WritableEvent::ShouldWait(Thread* thread) const { - return !signaled; -} - -void WritableEvent::Acquire(Thread* thread) { - ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); - - if (reset_type == ResetType::OneShot) - signaled = false; +ResetType WritableEvent::GetResetType() const { + return readable->reset_type; } void WritableEvent::Signal() { - signaled = true; - WakeupAllWaitingThreads(); + readable->Signal(); } void WritableEvent::Clear() { - signaled = false; -} - -void WritableEvent::ResetOnAcquire() { - if (reset_type == ResetType::OneShot) - Clear(); -} - -void WritableEvent::ResetOnWakeup() { - if (reset_type == ResetType::Pulse) - Clear(); + readable->Clear(); } bool WritableEvent::IsSignaled() const { - return signaled; -} - -void WritableEvent::WakeupAllWaitingThreads() { - WaitObject::WakeupAllWaitingThreads(); - - if (reset_type == ResetType::Pulse) - signaled = false; + return readable->signaled; } } // namespace Kernel diff --git a/src/core/hle/kernel/writable_event.h b/src/core/hle/kernel/writable_event.h index c0fe42302..4357d1b9f 100644 --- a/src/core/hle/kernel/writable_event.h +++ b/src/core/hle/kernel/writable_event.h @@ -12,8 +12,14 @@ namespace Kernel { class KernelCore; class ReadableEvent; +class WritableEvent; -class WritableEvent final : public WaitObject { +struct EventPair { + SharedPtr readable; + SharedPtr writable; +}; + +class WritableEvent final : public Object { public: ~WritableEvent() override; @@ -23,18 +29,8 @@ public: * @param reset_type ResetType describing how to create event * @param name Optional name of event */ - static std::tuple, SharedPtr> CreateEventPair( - KernelCore& kernel, ResetType reset_type, std::string name = "Unknown"); - - /** - * Creates an event and registers it in the kernel's named event table - * @param kernel The kernel instance to create this event under. - * @param reset_type ResetType describing how to create event - * @param name name of event - */ - static SharedPtr CreateRegisteredEventPair(KernelCore& kernel, - ResetType reset_type, - std::string name); + static EventPair CreateEventPair(KernelCore& kernel, ResetType reset_type, + std::string name = "Unknown"); std::string GetTypeName() const override { return "WritableEvent"; @@ -48,27 +44,17 @@ public: return HANDLE_TYPE; } - ResetType GetResetType() const { - return reset_type; - } - - bool ShouldWait(Thread* thread) const override; - void Acquire(Thread* thread) override; - - void WakeupAllWaitingThreads() override; + ResetType GetResetType() const; void Signal(); void Clear(); - void ResetOnAcquire(); - void ResetOnWakeup(); bool IsSignaled() const; private: explicit WritableEvent(KernelCore& kernel); - ResetType reset_type; ///< Current ResetType + SharedPtr readable; - bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) }; -- cgit v1.2.3 From 170d7078507745fee4c8952aa5888108b2b76b91 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Thu, 29 Nov 2018 09:14:12 -0500 Subject: hle_ipc: Refactor SleepClientThread to avoid ReadableEvent --- src/core/hle/kernel/hle_ipc.cpp | 6 +++--- src/core/hle/kernel/hle_ipc.h | 4 +--- src/core/hle/kernel/kernel.cpp | 2 -- src/core/hle/kernel/writable_event.cpp | 4 ++++ src/core/hle/kernel/writable_event.h | 2 ++ 5 files changed, 10 insertions(+), 8 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 21fda42d6..61ce7d7e4 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -39,7 +39,7 @@ void SessionRequestHandler::ClientDisconnected(const SharedPtr& s SharedPtr HLERequestContext::SleepClientThread( SharedPtr thread, const std::string& reason, u64 timeout, WakeupCallback&& callback, - SharedPtr writable_event, SharedPtr readable_event) { + SharedPtr writable_event) { // Put the client thread to sleep until the wait event is signaled or the timeout expires. thread->SetWakeupCallback([context = *this, callback]( ThreadWakeupReason reason, SharedPtr thread, @@ -51,14 +51,14 @@ SharedPtr HLERequestContext::SleepClientThread( }); auto& kernel = Core::System::GetInstance().Kernel(); - if (!writable_event || !readable_event) { + if (!writable_event) { // Create event if not provided const auto pair = WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); writable_event = pair.writable; - readable_event = pair.readable; } + const auto readable_event{writable_event->GetReadableEvent()}; writable_event->Clear(); thread->SetStatus(ThreadStatus::WaitHLEEvent); thread->SetWaitObjects({readable_event}); diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 557940f11..e5c0610cd 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -122,13 +122,11 @@ public: * was called. * @param writable_event Event to use to wake up the thread. If unspecified, an event will be * created. - * @param readable_event Event to be bound to the thread to wake up upon. * @returns Event that when signaled will resume the thread and call the callback function. */ SharedPtr SleepClientThread(SharedPtr thread, const std::string& reason, u64 timeout, WakeupCallback&& callback, - SharedPtr writable_event = nullptr, - SharedPtr readable_event = nullptr); + SharedPtr writable_event = nullptr); /// Populates this context with data from the requesting process/thread. ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 21d7f3483..e441c5bc6 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -17,11 +17,9 @@ #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/kernel.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/thread.h" #include "core/hle/kernel/timer.h" -#include "core/hle/kernel/writable_event.h" #include "core/hle/lock.h" #include "core/hle/result.h" diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp index 27d7ff734..a58ea6ec8 100644 --- a/src/core/hle/kernel/writable_event.cpp +++ b/src/core/hle/kernel/writable_event.cpp @@ -29,6 +29,10 @@ EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_typ return {std::move(readable_event), std::move(writable_event)}; } +SharedPtr WritableEvent::GetReadableEvent() const { + return readable; +} + ResetType WritableEvent::GetResetType() const { return readable->reset_type; } diff --git a/src/core/hle/kernel/writable_event.h b/src/core/hle/kernel/writable_event.h index 4357d1b9f..fc57d18d7 100644 --- a/src/core/hle/kernel/writable_event.h +++ b/src/core/hle/kernel/writable_event.h @@ -44,6 +44,8 @@ public: return HANDLE_TYPE; } + SharedPtr GetReadableEvent() const; + ResetType GetResetType() const; void Signal(); -- cgit v1.2.3