hle: kernel: Migrate KReadableEvent and KWritableEvent to KAutoObject.

This commit is contained in:
bunnei 2021-04-10 02:34:26 -07:00
parent eba3bb9d21
commit 2e8d6fe9a0
35 changed files with 219 additions and 204 deletions

View file

@ -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);

View file

@ -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();

View file

@ -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,12 +29,27 @@ 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);
virtual Process* GetOwner() const override {
return owner;
}
KReadableEvent& GetReadableEvent() {
return readable_event;
}
KWritableEvent& GetWritableEvent() {
return writable_event;
}
// DEPRECATED
std::string GetTypeName() const override {
return "KEvent";
}
@ -42,25 +59,9 @@ public:
return HANDLE_TYPE;
}
KReadableEvent* GetReadableEvent() {
return readable_event.get();
}
std::shared_ptr<KWritableEvent>& GetWritableEvent() {
return writable_event;
}
const std::shared_ptr<KReadableEvent>& GetReadableEvent() const {
return readable_event;
}
const std::shared_ptr<KWritableEvent>& GetWritableEvent() const {
return writable_event;
}
private:
std::shared_ptr<KReadableEvent> readable_event;
std::shared_ptr<KWritableEvent> writable_event;
KReadableEvent readable_event;
KWritableEvent writable_event;
Process* owner{};
bool initialized{};
};

View file

@ -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};

View file

@ -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,11 +15,32 @@ 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;
void Initialize(KEvent* parent_, std::string&& name_) {
is_signaled = false;
parent = parent_;
name = std::move(name_);
}
constexpr KEvent* GetParent() const {
return parent;
}
virtual bool IsSignaled() const override;
virtual void Destroy() override;
ResultCode Signal();
ResultCode Clear();
ResultCode Reset();
// DEPRECATED
std::string GetTypeName() const override {
return "KReadableEvent";
}
@ -27,22 +50,6 @@ public:
return HANDLE_TYPE;
}
KEvent* GetParent() const {
return parent;
}
void Initialize(KEvent* parent_) {
is_signaled = false;
parent = parent_;
}
bool IsSignaled() const override;
void Finalize() override {}
ResultCode Signal();
ResultCode Clear();
ResultCode Reset();
private:
bool is_signaled{};
KEvent* parent{};

View file

@ -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

View file

@ -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{};
};

View file

@ -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;

View file

@ -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");
// 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;
// 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.
auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*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(*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();