diff options
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r-- | src/core/hle/kernel/handle_table.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/k_event.cpp | 17 | ||||
-rw-r--r-- | src/core/hle/kernel/k_event.h | 33 | ||||
-rw-r--r-- | src/core/hle/kernel/k_readable_event.cpp | 15 | ||||
-rw-r--r-- | src/core/hle/kernel/k_readable_event.h | 41 | ||||
-rw-r--r-- | src/core/hle/kernel/k_writable_event.cpp | 18 | ||||
-rw-r--r-- | src/core/hle/kernel/k_writable_event.h | 34 | ||||
-rw-r--r-- | src/core/hle/kernel/kernel.h | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 70 |
9 files changed, 129 insertions, 107 deletions
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 58c49460f..cc3210ef2 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -54,7 +54,9 @@ ResultVal<Handle> HandleTable::Create(Object* obj) { case HandleType::SharedMemory: case HandleType::Thread: case HandleType::Event: - case HandleType::Process: { + case HandleType::Process: + case HandleType::ReadableEvent: + case HandleType::WritableEvent: { Handle handle{}; Add(&handle, reinterpret_cast<KAutoObject*>(obj), {}); return MakeResult<Handle>(handle); diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp index 4020e5325..fdec0c36f 100644 --- a/src/core/hle/kernel/k_event.cpp +++ b/src/core/hle/kernel/k_event.cpp @@ -3,14 +3,13 @@ // Refer to the license.txt file included. #include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_resource_limit.h" -#include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/process.h" namespace Kernel { -KEvent::KEvent(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {} +KEvent::KEvent(KernelCore& kernel) + : KAutoObjectWithSlabHeapAndContainer{kernel}, readable_event{kernel}, writable_event{kernel} {} KEvent::~KEvent() = default; @@ -21,17 +20,13 @@ void KEvent::Initialize(std::string&& name_) { // writable events are closed this object will be destroyed. Open(); - //// Create our sub events. - //KAutoObject::Create(readable_event.get()); - //KAutoObject::Create(writable_event.get()); - // Create our sub events. - readable_event = std::make_shared<KReadableEvent>(kernel, name_ + ":Readable"); - writable_event = std::make_shared<KWritableEvent>(kernel, name_ + ":Writable"); + KAutoObject::Create(std::addressof(readable_event)); + KAutoObject::Create(std::addressof(writable_event)); // Initialize our sub sessions. - readable_event->Initialize(this); - writable_event->Initialize(this); + readable_event.Initialize(this, name_ + ":Readable"); + writable_event.Initialize(this, name_ + ":Writable"); // Set our owner process. owner = kernel.CurrentProcess(); diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h index 97ec0ea9c..2c48a0499 100644 --- a/src/core/hle/kernel/k_event.h +++ b/src/core/hle/kernel/k_event.h @@ -4,6 +4,8 @@ #pragma once +#include "core/hle/kernel/k_readable_event.h" +#include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/slab_helpers.h" namespace Kernel { @@ -27,40 +29,39 @@ public: virtual bool IsInitialized() const override { return initialized; } + virtual uintptr_t GetPostDestroyArgument() const override { return reinterpret_cast<uintptr_t>(owner); } static void PostDestroy(uintptr_t arg); - std::string GetTypeName() const override { - return "KEvent"; + virtual Process* GetOwner() const override { + return owner; } - static constexpr HandleType HANDLE_TYPE = HandleType::Event; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - - KReadableEvent* GetReadableEvent() { - return readable_event.get(); + KReadableEvent& GetReadableEvent() { + return readable_event; } - std::shared_ptr<KWritableEvent>& GetWritableEvent() { + KWritableEvent& GetWritableEvent() { return writable_event; } - const std::shared_ptr<KReadableEvent>& GetReadableEvent() const { - return readable_event; + // DEPRECATED + + std::string GetTypeName() const override { + return "KEvent"; } - const std::shared_ptr<KWritableEvent>& GetWritableEvent() const { - return writable_event; + static constexpr HandleType HANDLE_TYPE = HandleType::Event; + HandleType GetHandleType() const override { + return HANDLE_TYPE; } private: - std::shared_ptr<KReadableEvent> readable_event; - std::shared_ptr<KWritableEvent> writable_event; + KReadableEvent readable_event; + KWritableEvent writable_event; Process* owner{}; bool initialized{}; }; diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp index 4b4d34857..8fef4bb00 100644 --- a/src/core/hle/kernel/k_readable_event.cpp +++ b/src/core/hle/kernel/k_readable_event.cpp @@ -2,21 +2,18 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <algorithm> #include "common/assert.h" -#include "common/common_funcs.h" -#include "common/logging/log.h" +#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/object.h" #include "core/hle/kernel/svc_results.h" namespace Kernel { -KReadableEvent::KReadableEvent(KernelCore& kernel, std::string&& name) - : KSynchronizationObject{kernel, std::move(name)} {} +KReadableEvent::KReadableEvent(KernelCore& kernel) : KSynchronizationObject{kernel} {} + KReadableEvent::~KReadableEvent() = default; bool KReadableEvent::IsSignaled() const { @@ -25,6 +22,12 @@ bool KReadableEvent::IsSignaled() const { return is_signaled; } +void KReadableEvent::Destroy() { + if (parent) { + parent->Close(); + } +} + ResultCode KReadableEvent::Signal() { KScopedSchedulerLock lk{kernel}; diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h index e6f0fd900..4c22f0584 100644 --- a/src/core/hle/kernel/k_readable_event.h +++ b/src/core/hle/kernel/k_readable_event.h @@ -4,8 +4,10 @@ #pragma once +#include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/object.h" +#include "core/hle/kernel/slab_helpers.h" #include "core/hle/result.h" namespace Kernel { @@ -13,36 +15,41 @@ namespace Kernel { class KernelCore; class KEvent; -class KReadableEvent final : public KSynchronizationObject { +class KReadableEvent : public KSynchronizationObject { + KERNEL_AUTOOBJECT_TRAITS(KReadableEvent, KSynchronizationObject); + public: - explicit KReadableEvent(KernelCore& kernel, std::string&& name); + explicit KReadableEvent(KernelCore& kernel); ~KReadableEvent() override; - std::string GetTypeName() const override { - return "KReadableEvent"; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; - HandleType GetHandleType() const override { - return HANDLE_TYPE; + void Initialize(KEvent* parent_, std::string&& name_) { + is_signaled = false; + parent = parent_; + name = std::move(name_); } - KEvent* GetParent() const { + constexpr KEvent* GetParent() const { return parent; } - void Initialize(KEvent* parent_) { - is_signaled = false; - parent = parent_; - } - - bool IsSignaled() const override; - void Finalize() override {} + virtual bool IsSignaled() const override; + virtual void Destroy() override; ResultCode Signal(); ResultCode Clear(); ResultCode Reset(); + // DEPRECATED + + std::string GetTypeName() const override { + return "KReadableEvent"; + } + + static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } + private: bool is_signaled{}; KEvent* parent{}; diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp index 25c52edb2..a430e0661 100644 --- a/src/core/hle/kernel/k_writable_event.cpp +++ b/src/core/hle/kernel/k_writable_event.cpp @@ -8,20 +8,28 @@ namespace Kernel { -KWritableEvent::KWritableEvent(KernelCore& kernel, std::string&& name) - : Object{kernel, std::move(name)} {} +KWritableEvent::KWritableEvent(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {} + KWritableEvent::~KWritableEvent() = default; -void KWritableEvent::Initialize(KEvent* parent_) { +void KWritableEvent::Initialize(KEvent* parent_, std::string&& name_) { parent = parent_; + name = std::move(name_); + parent->GetReadableEvent().Open(); } ResultCode KWritableEvent::Signal() { - return parent->GetReadableEvent()->Signal(); + return parent->GetReadableEvent().Signal(); } ResultCode KWritableEvent::Clear() { - return parent->GetReadableEvent()->Clear(); + return parent->GetReadableEvent().Clear(); +} + +void KWritableEvent::Destroy() { + // Close our references. + parent->GetReadableEvent().Close(); + parent->Close(); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h index 518f5448d..7cf43f77e 100644 --- a/src/core/hle/kernel/k_writable_event.h +++ b/src/core/hle/kernel/k_writable_event.h @@ -4,7 +4,9 @@ #pragma once +#include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/object.h" +#include "core/hle/kernel/slab_helpers.h" #include "core/hle/result.h" namespace Kernel { @@ -12,11 +14,28 @@ namespace Kernel { class KernelCore; class KEvent; -class KWritableEvent final : public Object { +class KWritableEvent final + : public KAutoObjectWithSlabHeapAndContainer<KWritableEvent, KAutoObjectWithList> { + KERNEL_AUTOOBJECT_TRAITS(KWritableEvent, KAutoObject); + public: - explicit KWritableEvent(KernelCore& kernel, std::string&& name); + explicit KWritableEvent(KernelCore& kernel); ~KWritableEvent() override; + virtual void Destroy() override; + + static void PostDestroy([[maybe_unused]] uintptr_t arg) {} + + void Initialize(KEvent* parent_, std::string&& name_); + ResultCode Signal(); + ResultCode Clear(); + + constexpr KEvent* GetParent() const { + return parent; + } + + // DEPRECATED + std::string GetTypeName() const override { return "KWritableEvent"; } @@ -26,17 +45,6 @@ public: return HANDLE_TYPE; } - void Initialize(KEvent* parent_); - - void Finalize() override {} - - ResultCode Signal(); - ResultCode Clear(); - - KEvent* GetParent() const { - return parent; - } - private: KEvent* parent{}; }; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index e494fe9f3..850436eb3 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -40,6 +40,7 @@ class KResourceLimit; class KScheduler; class KSharedMemory; class KThread; +class KWritableEvent; class PhysicalCore; class Process; class ServiceThread; @@ -269,6 +270,8 @@ public: return slab_heap_container->shared_memory; } else if constexpr (std::is_same_v<T, KLinkedListNode>) { return slab_heap_container->linked_list_node; + } else if constexpr (std::is_same_v<T, KWritableEvent>) { + return slab_heap_container->writeable_event; } } @@ -308,6 +311,7 @@ private: KSlabHeap<KEvent> event; KSlabHeap<KSharedMemory> shared_memory; KSlabHeap<KLinkedListNode> linked_list_node; + KSlabHeap<KWritableEvent> writeable_event; }; std::unique_ptr<SlabHeapContainer> slab_heap_container; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 8050359be..c6334f91c 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1745,16 +1745,16 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) { // Try to reset as readable event. { - auto readable_event = handle_table.Get<KReadableEvent>(handle); - if (readable_event) { + KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(handle); + if (readable_event.IsNotNull()) { return readable_event->Reset(); } } // Try to reset as process. { - auto process = handle_table.Get<Process>(handle); - if (process) { + KScopedAutoObject process = handle_table.GetObject<Process>(handle); + if (process.IsNotNull()) { return process->Reset(); } } @@ -1885,27 +1885,12 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle static ResultCode SignalEvent(Core::System& system, Handle event_handle) { LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); - auto& kernel = system.Kernel(); // Get the current handle table. - const HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); - - // Reserve a new event from the process resource limit. - KScopedResourceReservation event_reservation(kernel.CurrentProcess(), - LimitableResource::Events); - if (!event_reservation.Succeeded()) { - LOG_ERROR(Kernel, "Could not reserve a new event"); - return ResultResourceLimitedExceeded; - } + const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); // Get the writable event. - auto writable_event = handle_table.Get<KWritableEvent>(event_handle); - if (!writable_event) { - LOG_ERROR(Kernel_SVC, "Invalid event handle provided (handle={:08X})", event_handle); - return ResultInvalidHandle; - } - - // Commit the successfuly reservation. - event_reservation.Commit(); + KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); + R_UNLESS(writable_event.IsNotNull(), ResultInvalidHandle); return writable_event->Signal(); } @@ -1922,16 +1907,16 @@ static ResultCode ClearEvent(Core::System& system, Handle event_handle) { // Try to clear the writable event. { - auto writable_event = handle_table.Get<KWritableEvent>(event_handle); - if (writable_event) { + KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); + if (writable_event.IsNotNull()) { return writable_event->Clear(); } } // Try to clear the readable event. { - auto readable_event = handle_table.Get<KReadableEvent>(event_handle); - if (readable_event) { + KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle); + if (readable_event.IsNotNull()) { return readable_event->Clear(); } } @@ -1950,7 +1935,12 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o // Get the kernel reference and handle table. auto& kernel = system.Kernel(); - HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); + auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); + + // Reserve a new event from the process resource limit + KScopedResourceReservation event_reservation(kernel.CurrentProcess(), + LimitableResource::Events); + R_UNLESS(event_reservation.Succeeded(), ResultResourceLimitedExceeded); // Create a new event. KEvent* event = KEvent::Create(kernel); @@ -1959,22 +1949,26 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o // Initialize the event. event->Initialize("CreateEvent"); + // Commit the thread reservation. + event_reservation.Commit(); + + // Ensure that we clean up the event (and its only references are handle table) on function end. + SCOPE_EXIT({ + event->GetWritableEvent().Close(); + event->GetReadableEvent().Close(); + }); + + // Register the event. + KEvent::Register(kernel, event); + // Add the writable event to the handle table. - const auto write_create_result = handle_table.Create(event->GetWritableEvent().get()); - if (write_create_result.Failed()) { - return write_create_result.Code(); - } - *out_write = *write_create_result; + R_TRY(handle_table.Add(out_write, std::addressof(event->GetWritableEvent()))); // Add the writable event to the handle table. - auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*write_create_result); }); + auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*out_write); }); // Add the readable event to the handle table. - const auto read_create_result = handle_table.Create(event->GetReadableEvent()); - if (read_create_result.Failed()) { - return read_create_result.Code(); - } - *out_read = *read_create_result; + R_TRY(handle_table.Add(out_read, std::addressof(event->GetReadableEvent()))); // We succeeded. handle_guard.Cancel(); |