From 54dde406bce1175fd51f3b90f00c2b92cbe70c8c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 24 Oct 2021 20:41:38 -0700 Subject: [PATCH] kern: devirtualize KReadableEvent::Reset, KWorkerTask::DoWorkerTask --- .../mesosphere/kern_k_auto_object_container.hpp | 2 +- .../include/mesosphere/kern_k_interrupt_event.hpp | 11 ++++++++++- .../include/mesosphere/kern_k_process.hpp | 4 ++-- .../include/mesosphere/kern_k_readable_event.hpp | 15 +++++++++++++-- .../include/mesosphere/kern_k_thread.hpp | 6 +++--- .../include/mesosphere/kern_k_worker_task.hpp | 13 ++++++++++--- libraries/libmesosphere/source/kern_k_process.cpp | 2 +- .../source/kern_k_readable_event.cpp | 8 -------- libraries/libmesosphere/source/kern_k_thread.cpp | 2 +- .../source/kern_k_worker_task_manager.cpp | 11 +++++++++++ .../libmesosphere/source/svc/kern_svc_event.cpp | 6 +++++- .../source/svc/kern_svc_synchronization.cpp | 6 +++++- 12 files changed, 62 insertions(+), 24 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object_container.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object_container.hpp index 05a3de505..a534a3d0b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object_container.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object_container.hpp @@ -96,7 +96,7 @@ namespace ams::kern { size_t count = 0; for (const auto &obj : list) { - AMS_AUDIT(obj.DynamicCast() != nullptr); + MESOSPHERE_AUDIT(obj.DynamicCast() != nullptr); if (static_cast(obj).GetOwner() == owner) { ++count; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp index 7a8306908..23531d9c5 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_interrupt_event.hpp @@ -38,7 +38,16 @@ namespace ams::kern { Result Initialize(int32_t interrupt_name, ams::svc::InterruptType type); void Finalize(); - virtual Result Reset() override; + Result Reset(); + + Result Clear() { + MESOSPHERE_ASSERT_THIS(); + + /* Try to perform a reset, succeeding unconditionally. */ + this->Reset(); + + return ResultSuccess(); + } bool IsInitialized() const { return m_is_initialized; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp index 9680415eb..cc945906b 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_process.hpp @@ -34,7 +34,7 @@ namespace ams::kern { - class KProcess final : public KAutoObjectWithSlabHeapAndContainer, public KWorkerTask { + class KProcess final : public KAutoObjectWithSlabHeapAndContainer { MESOSPHERE_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject); public: enum State { @@ -399,7 +399,7 @@ namespace ams::kern { return m_is_signaled; } - virtual void DoWorkerTask() override; + void DoWorkerTaskImpl(); private: void ChangeState(State new_state) { if (m_state != new_state) { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_readable_event.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_readable_event.hpp index 12c83b8e6..08f04fa17 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_readable_event.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_readable_event.hpp @@ -36,11 +36,22 @@ namespace ams::kern { constexpr KEvent *GetParent() const { return m_parent; } Result Signal(); - Result Clear(); + Result Reset(); + + Result Clear() { + MESOSPHERE_ASSERT_THIS(); + + /* Try to perform a reset, succeeding unconditionally. */ + this->Reset(); + + return ResultSuccess(); + } virtual bool IsSignaled() const override; virtual void Destroy() override; - virtual Result Reset(); + + /* NOTE: This is a virtual function in Nintendo's kernel. */ + /* virtual Result Reset(); */ }; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp index 930017f00..6ab5b1392 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp @@ -32,7 +32,7 @@ namespace ams::kern { using KThreadFunction = void (*)(uintptr_t); - class KThread final : public KAutoObjectWithSlabHeapAndContainer, public util::IntrusiveListBaseNode, public KTimerTask, public KWorkerTask { + class KThread final : public KAutoObjectWithSlabHeapAndContainer, public util::IntrusiveListBaseNode, public KTimerTask { MESOSPHERE_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject); private: friend class KProcess; @@ -235,7 +235,7 @@ namespace ams::kern { bool m_resource_limit_release_hint; public: constexpr explicit KThread(util::ConstantInitializeTag) - : KAutoObjectWithSlabHeapAndContainer(util::ConstantInitialize), KTimerTask(util::ConstantInitialize), + : KAutoObjectWithSlabHeapAndContainer(util::ConstantInitialize), KTimerTask(util::ConstantInitialize), m_process_list_node{}, m_condvar_arbiter_tree_node{util::ConstantInitialize}, m_priority{-1}, m_condvar_tree{}, m_condvar_key{}, m_thread_context{util::ConstantInitialize}, m_virtual_affinity_mask{}, m_physical_affinity_mask{}, m_thread_id{}, m_cpu_time{0}, m_address_key{Null}, m_parent{}, m_kernel_stack_top{}, m_light_ipc_data{}, m_tls_address{Null}, m_tls_heap_address{}, m_activity_pause_lock{}, m_sync_object_buffer{util::ConstantInitialize}, @@ -622,7 +622,7 @@ namespace ams::kern { virtual bool IsSignaled() const override; void OnTimer(); - virtual void DoWorkerTask() override; + void DoWorkerTaskImpl(); public: static constexpr bool IsConditionVariableThreadTreeValid() { return ConditionVariableThreadTreeTraits::IsValid(); diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_worker_task.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_worker_task.hpp index 568904865..7519e5891 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_worker_task.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_worker_task.hpp @@ -18,16 +18,23 @@ namespace ams::kern { - class KWorkerTask { + /* NOTE: We inherit KWorkerTask from KSynchronizationObject in order to devirtualize DoWorkerTask, which is exclusive to KThread/KProcess. */ + /* This should be reverted, if Nintendo adds new types of worker tasks in the future. */ + + /* Nintendo has class KWorkerTask { ... } with identical interface but DoWorkerTask() virtual. */ + + class KWorkerTask : public KSynchronizationObject { private: KWorkerTask *m_next_task; public: - constexpr ALWAYS_INLINE KWorkerTask() : m_next_task(nullptr) { /* ... */ } + constexpr ALWAYS_INLINE explicit KWorkerTask(util::ConstantInitializeTag) : KSynchronizationObject(util::ConstantInitialize), m_next_task(nullptr) { /* ... */ } + + ALWAYS_INLINE explicit KWorkerTask() : m_next_task(nullptr) { /* ... */ } constexpr ALWAYS_INLINE KWorkerTask *GetNextTask() const { return m_next_task; } constexpr ALWAYS_INLINE void SetNextTask(KWorkerTask *task) { m_next_task = task; } - virtual void DoWorkerTask() = 0; + void DoWorkerTask(); }; } diff --git a/libraries/libmesosphere/source/kern_k_process.cpp b/libraries/libmesosphere/source/kern_k_process.cpp index 89ec422c1..4bfa6a158 100644 --- a/libraries/libmesosphere/source/kern_k_process.cpp +++ b/libraries/libmesosphere/source/kern_k_process.cpp @@ -432,7 +432,7 @@ namespace ams::kern { return ResultSuccess(); } - void KProcess::DoWorkerTask() { + void KProcess::DoWorkerTaskImpl() { /* Terminate child threads. */ TerminateChildren(this, nullptr); diff --git a/libraries/libmesosphere/source/kern_k_readable_event.cpp b/libraries/libmesosphere/source/kern_k_readable_event.cpp index ab6554b9f..7160a1442 100644 --- a/libraries/libmesosphere/source/kern_k_readable_event.cpp +++ b/libraries/libmesosphere/source/kern_k_readable_event.cpp @@ -59,14 +59,6 @@ namespace ams::kern { return ResultSuccess(); } - Result KReadableEvent::Clear() { - MESOSPHERE_ASSERT_THIS(); - - this->Reset(); - - return ResultSuccess(); - } - Result KReadableEvent::Reset() { MESOSPHERE_ASSERT_THIS(); diff --git a/libraries/libmesosphere/source/kern_k_thread.cpp b/libraries/libmesosphere/source/kern_k_thread.cpp index 548eb1c41..c88cfef7d 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -406,7 +406,7 @@ namespace ams::kern { this->Close(); } - void KThread::DoWorkerTask() { + void KThread::DoWorkerTaskImpl() { /* Finish the termination that was begun by Exit(). */ this->FinishTermination(); } diff --git a/libraries/libmesosphere/source/kern_k_worker_task_manager.cpp b/libraries/libmesosphere/source/kern_k_worker_task_manager.cpp index f91f33ab9..f639e7764 100644 --- a/libraries/libmesosphere/source/kern_k_worker_task_manager.cpp +++ b/libraries/libmesosphere/source/kern_k_worker_task_manager.cpp @@ -41,6 +41,17 @@ namespace ams::kern { } + void KWorkerTask::DoWorkerTask() { + if (auto * const thread = this->DynamicCast(); thread != nullptr) { + return thread->DoWorkerTaskImpl(); + } else { + auto * const process = this->DynamicCast(); + MESOSPHERE_ABORT_UNLESS(process != nullptr); + + return process->DoWorkerTaskImpl(); + } + } + void KWorkerTaskManager::Initialize(s32 priority) { /* Reserve a thread from the system limit. */ MESOSPHERE_ABORT_UNLESS(Kernel::GetSystemResourceLimit().Reserve(ams::svc::LimitableResource_ThreadCountMax, 1)); diff --git a/libraries/libmesosphere/source/svc/kern_svc_event.cpp b/libraries/libmesosphere/source/svc/kern_svc_event.cpp index c73d95933..76ff263ea 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_event.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_event.cpp @@ -48,7 +48,11 @@ namespace ams::kern::svc { { KScopedAutoObject readable_event = handle_table.GetObject(event_handle); if (readable_event.IsNotNull()) { - return readable_event->Clear(); + if (auto * const interrupt_event = readable_event->DynamicCast(); interrupt_event != nullptr) { + return interrupt_event->Clear(); + } else { + return readable_event->Clear(); + } } } diff --git a/libraries/libmesosphere/source/svc/kern_svc_synchronization.cpp b/libraries/libmesosphere/source/svc/kern_svc_synchronization.cpp index 45d3bfb0d..3da7bcd14 100644 --- a/libraries/libmesosphere/source/svc/kern_svc_synchronization.cpp +++ b/libraries/libmesosphere/source/svc/kern_svc_synchronization.cpp @@ -35,7 +35,11 @@ namespace ams::kern::svc { { KScopedAutoObject readable_event = handle_table.GetObject(handle); if (readable_event.IsNotNull()) { - return readable_event->Reset(); + if (auto * const interrupt_event = readable_event->DynamicCast(); interrupt_event != nullptr) { + return interrupt_event->Reset(); + } else { + return readable_event->Reset(); + } } }