From ff3c7c068b926399513bf7328c22e224ab0b53d6 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 31 Jan 2021 01:38:57 -0800 Subject: hle: kernel: Reimplement KReadableEvent and KWritableEvent. --- src/core/hle/kernel/k_readable_event.cpp | 44 +++++++++++++----------- src/core/hle/kernel/k_readable_event.h | 42 +++++++++------------- src/core/hle/kernel/k_synchronization_object.cpp | 3 ++ src/core/hle/kernel/k_synchronization_object.h | 1 + src/core/hle/kernel/k_writable_event.cpp | 34 ++++++------------ src/core/hle/kernel/k_writable_event.h | 40 +++++++-------------- src/core/hle/kernel/object.cpp | 6 +++- src/core/hle/kernel/object.h | 7 ++-- src/core/hle/kernel/svc.cpp | 9 ++--- 9 files changed, 82 insertions(+), 104 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp index e9e191bc6..0fa895c56 100644 --- a/src/core/hle/kernel/k_readable_event.cpp +++ b/src/core/hle/kernel/k_readable_event.cpp @@ -1,9 +1,10 @@ -// Copyright 2014 Citra Emulator Project +// Copyright 2021 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #include #include "common/assert.h" +#include "common/common_funcs.h" #include "common/logging/log.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/k_readable_event.h" @@ -11,40 +12,43 @@ #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) : KSynchronizationObject{kernel} {} +KReadableEvent::KReadableEvent(KernelCore& kernel, std::string&& name) + : KSynchronizationObject{kernel, std::move(name)} {} KReadableEvent::~KReadableEvent() = default; -void KReadableEvent::Signal() { - if (is_signaled) { - return; - } - - is_signaled = true; - NotifyAvailable(); -} - bool KReadableEvent::IsSignaled() const { ASSERT(kernel.GlobalSchedulerContext().IsLocked()); return is_signaled; } -void KReadableEvent::Clear() { - is_signaled = false; -} +ResultCode KReadableEvent::Signal() { + KScopedSchedulerLock lk{kernel}; -ResultCode KReadableEvent::Reset() { - KScopedSchedulerLock lock(kernel); if (!is_signaled) { - LOG_TRACE(Kernel, "Handle is not signaled! object_id={}, object_type={}, object_name={}", - GetObjectId(), GetTypeName(), GetName()); - return ERR_INVALID_STATE; + is_signaled = true; + NotifyAvailable(); } - Clear(); + return RESULT_SUCCESS; +} + +ResultCode KReadableEvent::Clear() { + Reset(); + + return RESULT_SUCCESS; +} + +ResultCode KReadableEvent::Reset() { + KScopedSchedulerLock lk{kernel}; + + R_UNLESS_NOLOG(is_signaled, Svc::ResultInvalidState); + + is_signaled = false; return RESULT_SUCCESS; } diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h index 39eedc411..e6f0fd900 100644 --- a/src/core/hle/kernel/k_readable_event.h +++ b/src/core/hle/kernel/k_readable_event.h @@ -1,4 +1,4 @@ -// Copyright 2014 Citra Emulator Project +// Copyright 2021 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. @@ -6,25 +6,20 @@ #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/object.h" - -union ResultCode; +#include "core/hle/result.h" namespace Kernel { class KernelCore; -class KWritableEvent; +class KEvent; class KReadableEvent final : public KSynchronizationObject { - friend class KWritableEvent; - public: + explicit KReadableEvent(KernelCore& kernel, std::string&& name); ~KReadableEvent() override; std::string GetTypeName() const override { - return "ReadableEvent"; - } - std::string GetName() const override { - return name; + return "KReadableEvent"; } static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; @@ -32,28 +27,25 @@ public: return HANDLE_TYPE; } - /// Unconditionally clears the readable event's state. - void Clear(); - - /// Clears the readable event's state if and only if it - /// has already been signaled. - /// - /// @pre The event must be in a signaled state. If this event - /// is in an unsignaled state and this function is called, - /// then ERR_INVALID_STATE will be returned. - ResultCode Reset(); + KEvent* GetParent() const { + return parent; + } - void Signal(); + void Initialize(KEvent* parent_) { + is_signaled = false; + parent = parent_; + } bool IsSignaled() const override; - void Finalize() override {} -private: - explicit KReadableEvent(KernelCore& kernel); + ResultCode Signal(); + ResultCode Clear(); + ResultCode Reset(); +private: bool is_signaled{}; - std::string name; ///< Name of event (optional) + KEvent* parent{}; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp index a3b34f82f..140cc46a7 100644 --- a/src/core/hle/kernel/k_synchronization_object.cpp +++ b/src/core/hle/kernel/k_synchronization_object.cpp @@ -132,6 +132,9 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : Object{kernel} {} +KSynchronizationObject::KSynchronizationObject(KernelCore& kernel, std::string&& name) + : Object{kernel, std::move(name)} {} + KSynchronizationObject::~KSynchronizationObject() = default; void KSynchronizationObject::NotifyAvailable(ResultCode result) { diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h index f65c71c28..5803718fd 100644 --- a/src/core/hle/kernel/k_synchronization_object.h +++ b/src/core/hle/kernel/k_synchronization_object.h @@ -33,6 +33,7 @@ public: protected: explicit KSynchronizationObject(KernelCore& kernel); + explicit KSynchronizationObject(KernelCore& kernel, std::string&& name); virtual ~KSynchronizationObject(); void NotifyAvailable(ResultCode result); diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp index d2857b4c3..25c52edb2 100644 --- a/src/core/hle/kernel/k_writable_event.cpp +++ b/src/core/hle/kernel/k_writable_event.cpp @@ -1,41 +1,27 @@ -// Copyright 2014 Citra Emulator Project +// Copyright 2021 yuzu emulator team // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include -#include "common/assert.h" +#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" -#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_writable_event.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/object.h" namespace Kernel { -KWritableEvent::KWritableEvent(KernelCore& kernel) : Object{kernel} {} +KWritableEvent::KWritableEvent(KernelCore& kernel, std::string&& name) + : Object{kernel, std::move(name)} {} KWritableEvent::~KWritableEvent() = default; -EventPair KWritableEvent::CreateEventPair(KernelCore& kernel, std::string name) { - std::shared_ptr writable_event(new KWritableEvent(kernel)); - std::shared_ptr readable_event(new KReadableEvent(kernel)); - - writable_event->name = name + ":Writable"; - writable_event->readable = readable_event; - readable_event->name = name + ":Readable"; - - return {std::move(readable_event), std::move(writable_event)}; -} - -std::shared_ptr KWritableEvent::GetReadableEvent() const { - return readable; +void KWritableEvent::Initialize(KEvent* parent_) { + parent = parent_; } -void KWritableEvent::Signal() { - readable->Signal(); +ResultCode KWritableEvent::Signal() { + return parent->GetReadableEvent()->Signal(); } -void KWritableEvent::Clear() { - readable->Clear(); +ResultCode KWritableEvent::Clear() { + return parent->GetReadableEvent()->Clear(); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h index ad5514b52..518f5448d 100644 --- a/src/core/hle/kernel/k_writable_event.h +++ b/src/core/hle/kernel/k_writable_event.h @@ -4,37 +4,21 @@ #pragma once -#include - #include "core/hle/kernel/object.h" +#include "core/hle/result.h" namespace Kernel { class KernelCore; -class KReadableEvent; -class KWritableEvent; - -struct EventPair { - std::shared_ptr readable; - std::shared_ptr writable; -}; +class KEvent; class KWritableEvent final : public Object { public: + explicit KWritableEvent(KernelCore& kernel, std::string&& name); ~KWritableEvent() override; - /** - * Creates an event - * @param kernel The kernel instance to create this event under. - * @param name Optional name of event - */ - static EventPair CreateEventPair(KernelCore& kernel, std::string name = "Unknown"); - std::string GetTypeName() const override { - return "WritableEvent"; - } - std::string GetName() const override { - return name; + return "KWritableEvent"; } static constexpr HandleType HANDLE_TYPE = HandleType::WritableEvent; @@ -42,19 +26,19 @@ public: return HANDLE_TYPE; } - std::shared_ptr GetReadableEvent() const; - - void Signal(); - void Clear(); + void Initialize(KEvent* parent_); void Finalize() override {} -private: - explicit KWritableEvent(KernelCore& kernel); + ResultCode Signal(); + ResultCode Clear(); - std::shared_ptr readable; + KEvent* GetParent() const { + return parent; + } - std::string name; ///< Name of event (optional) +private: + KEvent* parent{}; }; } // namespace Kernel diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index 2c571792b..d7f40c403 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp @@ -8,7 +8,10 @@ namespace Kernel { -Object::Object(KernelCore& kernel) : kernel{kernel}, object_id{kernel.CreateNewObjectID()} {} +Object::Object(KernelCore& kernel_) + : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{"[UNKNOWN KERNEL OBJECT]"} {} +Object::Object(KernelCore& kernel_, std::string&& name_) + : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{std::move(name_)} {} Object::~Object() = default; bool Object::IsWaitable() const { @@ -21,6 +24,7 @@ bool Object::IsWaitable() const { return true; case HandleType::Unknown: + case HandleType::Event: case HandleType::WritableEvent: case HandleType::SharedMemory: case HandleType::TransferMemory: diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index be7fcb5fb..501e58b33 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -18,6 +18,7 @@ using Handle = u32; enum class HandleType : u32 { Unknown, + Event, WritableEvent, ReadableEvent, SharedMemory, @@ -34,7 +35,8 @@ enum class HandleType : u32 { class Object : NonCopyable, public std::enable_shared_from_this { public: - explicit Object(KernelCore& kernel); + explicit Object(KernelCore& kernel_); + explicit Object(KernelCore& kernel_, std::string&& name_); virtual ~Object(); /// Returns a unique identifier for the object. For debugging purposes only. @@ -46,7 +48,7 @@ public: return "[BAD KERNEL OBJECT TYPE]"; } virtual std::string GetName() const { - return "[UNKNOWN KERNEL OBJECT]"; + return name; } virtual HandleType GetHandleType() const = 0; @@ -69,6 +71,7 @@ protected: private: std::atomic object_id{0}; + std::string name; }; template diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index f94eecbb8..9d036f45d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -26,6 +26,7 @@ #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_address_arbiter.h" #include "core/hle/kernel/k_condition_variable.h" +#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_scheduler.h" @@ -1870,18 +1871,18 @@ static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle LOG_DEBUG(Kernel_SVC, "called"); auto& kernel = system.Kernel(); - const auto [readable_event, writable_event] = - KWritableEvent::CreateEventPair(kernel, "CreateEvent"); + const auto event = KEvent::Create(kernel, "CreateEvent"); + event->Initialize(); HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); - const auto write_create_result = handle_table.Create(writable_event); + const auto write_create_result = handle_table.Create(event->GetWritableEvent()); if (write_create_result.Failed()) { return write_create_result.Code(); } *write_handle = *write_create_result; - const auto read_create_result = handle_table.Create(readable_event); + const auto read_create_result = handle_table.Create(event->GetReadableEvent()); if (read_create_result.Failed()) { handle_table.Close(*write_create_result); return read_create_result.Code(); -- cgit v1.2.3