summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2021-04-10 11:34:26 +0200
committerbunnei <bunneidev@gmail.com>2021-05-06 01:40:51 +0200
commit2e8d6fe9a0c07538397682e1cb25992bfd15676d (patch)
tree444ee462a197818e0114150a03c0a5898cadaa19 /src/core/hle/kernel
parenthle: ipc_helpers: Add methods for copy/move references. (diff)
downloadyuzu-2e8d6fe9a0c07538397682e1cb25992bfd15676d.tar
yuzu-2e8d6fe9a0c07538397682e1cb25992bfd15676d.tar.gz
yuzu-2e8d6fe9a0c07538397682e1cb25992bfd15676d.tar.bz2
yuzu-2e8d6fe9a0c07538397682e1cb25992bfd15676d.tar.lz
yuzu-2e8d6fe9a0c07538397682e1cb25992bfd15676d.tar.xz
yuzu-2e8d6fe9a0c07538397682e1cb25992bfd15676d.tar.zst
yuzu-2e8d6fe9a0c07538397682e1cb25992bfd15676d.zip
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/handle_table.cpp4
-rw-r--r--src/core/hle/kernel/k_event.cpp17
-rw-r--r--src/core/hle/kernel/k_event.h33
-rw-r--r--src/core/hle/kernel/k_readable_event.cpp15
-rw-r--r--src/core/hle/kernel/k_readable_event.h41
-rw-r--r--src/core/hle/kernel/k_writable_event.cpp18
-rw-r--r--src/core/hle/kernel/k_writable_event.h34
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/svc.cpp70
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();