From 26c02e2019bfb5700722d31adaae62d8fcc7e714 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sat, 16 Oct 2021 16:13:10 -0700 Subject: [PATCH] kern/util: update structure layouts to match Nintendo (saves 0x10 per KThread/KSession) --- .../include/mesosphere/kern_k_auto_object.hpp | 3 ++- .../libmesosphere/include/mesosphere/kern_k_session.hpp | 6 +++--- .../libmesosphere/include/mesosphere/kern_k_thread.hpp | 5 ++--- libraries/libmesosphere/source/kern_k_thread.cpp | 3 --- libraries/libvapours/include/vapours/freebsd/tree.hpp | 2 ++ .../vapours/util/util_intrusive_red_black_tree.hpp | 8 ++++++-- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp index dcbd1ddd9..07075ecc4 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_auto_object.hpp @@ -71,10 +71,11 @@ namespace ams::kern { private: KAutoObject *m_next_closed_object; std::atomic m_ref_count; + u32 m_reserved; public: static KAutoObject *Create(KAutoObject *ptr); public: - constexpr ALWAYS_INLINE explicit KAutoObject() : m_next_closed_object(nullptr), m_ref_count(0) { MESOSPHERE_ASSERT_THIS(); } + constexpr ALWAYS_INLINE explicit KAutoObject() : m_next_closed_object(nullptr), m_ref_count(0), m_reserved(0) { MESOSPHERE_ASSERT_THIS(); } /* Destroy is responsible for destroying the auto object's resources when ref_count hits zero. */ virtual void Destroy() { MESOSPHERE_ASSERT_THIS(); } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_session.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_session.hpp index 8d02289c1..a1bc97def 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_session.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_session.hpp @@ -35,13 +35,13 @@ namespace ams::kern { ServerClosed = 3, }; private: + std::atomic::type> m_atomic_state; + bool m_initialized; KServerSession m_server; KClientSession m_client; - std::atomic::type> m_atomic_state; KClientPort *m_port; uintptr_t m_name; KProcess *m_process; - bool m_initialized; private: ALWAYS_INLINE void SetState(State state) { m_atomic_state = static_cast(state); @@ -52,7 +52,7 @@ namespace ams::kern { } public: constexpr KSession() - : m_server(), m_client(), m_atomic_state(static_cast::type>(State::Invalid)), m_port(), m_name(), m_process(), m_initialized() + : m_atomic_state(static_cast::type>(State::Invalid)), m_initialized(), m_server(), m_client(), m_port(), m_name(), m_process() { /* ... */ } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp index 9147394be..0008938bc 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp @@ -177,9 +177,8 @@ namespace ams::kern { static_assert(ams::util::HasRedBlackKeyType); static_assert(std::same_as, ConditionVariableComparator::RedBlackKeyType>); private: - static inline std::atomic s_next_thread_id = 0; + static constinit inline std::atomic s_next_thread_id = 0; private: - alignas(16) KThreadContext m_thread_context{}; util::IntrusiveListNode m_process_list_node{}; util::IntrusiveRedBlackTreeNode m_condvar_arbiter_tree_node{}; s32 m_priority{}; @@ -189,6 +188,7 @@ namespace ams::kern { ConditionVariableThreadTree *m_condvar_tree{}; uintptr_t m_condvar_key{}; + alignas(16) KThreadContext m_thread_context{}; u64 m_virtual_affinity_mask{}; KAffinityMask m_physical_affinity_mask{}; u64 m_thread_id{}; @@ -204,7 +204,6 @@ namespace ams::kern { s64 m_schedule_count{}; s64 m_last_scheduled_tick{}; QueueEntry m_per_core_priority_queue_entry[cpu::NumCores]{}; - KLightLock *m_waiting_lock{}; KThreadQueue *m_wait_queue{}; WaiterList m_waiter_list{}; WaiterList m_pinned_waiter_list{}; diff --git a/libraries/libmesosphere/source/kern_k_thread.cpp b/libraries/libmesosphere/source/kern_k_thread.cpp index 49519dd2b..e0e7e5d6a 100644 --- a/libraries/libmesosphere/source/kern_k_thread.cpp +++ b/libraries/libmesosphere/source/kern_k_thread.cpp @@ -148,9 +148,6 @@ namespace ams::kern { m_priority = prio; m_base_priority = prio; - /* Set waiting lock to null. */ - m_waiting_lock = nullptr; - /* Initialize wait queue/sync index. */ m_synced_index = -1; m_wait_queue = nullptr; diff --git a/libraries/libvapours/include/vapours/freebsd/tree.hpp b/libraries/libvapours/include/vapours/freebsd/tree.hpp index 7fb838f11..7d2a893e0 100644 --- a/libraries/libvapours/include/vapours/freebsd/tree.hpp +++ b/libraries/libvapours/include/vapours/freebsd/tree.hpp @@ -53,6 +53,7 @@ namespace ams::freebsd { RB_RED = 1, }; + #pragma pack(push, 4) template class RBEntry { private: @@ -82,6 +83,7 @@ namespace ams::freebsd { constexpr ALWAYS_INLINE void SetColor(RBColor c) { m_rbe_color = c; } }; + #pragma pack(pop) template struct CheckRBEntry { static constexpr bool value = false; }; template struct CheckRBEntry> { static constexpr bool value = true; }; diff --git a/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp b/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp index b9338034d..e82e880fd 100644 --- a/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp +++ b/libraries/libvapours/include/vapours/util/util_intrusive_red_black_tree.hpp @@ -31,6 +31,7 @@ namespace ams::util { } + #pragma pack(push, 4) struct IntrusiveRedBlackTreeNode { NON_COPYABLE(IntrusiveRedBlackTreeNode); public: @@ -45,6 +46,8 @@ namespace ams::util { constexpr ALWAYS_INLINE void SetRBEntry(const RBEntry &entry) { m_entry = entry; } }; + static_assert(sizeof(IntrusiveRedBlackTreeNode) == 3 * sizeof(void *) + std::max(sizeof(freebsd::RBColor), 4)); + #pragma pack(pop) template class IntrusiveRedBlackTree; @@ -501,6 +504,7 @@ namespace ams::util { private: static constexpr TypedStorage DerivedStorage = {}; static_assert(GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage)); + static_assert(util::IsAligned(util::impl::OffsetOf, alignof(void *))); }; template> @@ -515,7 +519,7 @@ namespace ams::util { static constexpr bool IsValid() { TypedStorage DerivedStorage = {}; - return GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage); + return GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage) && util::IsAligned(util::impl::OffsetOf, alignof(void *)); } private: template @@ -541,7 +545,7 @@ namespace ams::util { }; template - class IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode { + class alignas(void *) IntrusiveRedBlackTreeBaseNode : public IntrusiveRedBlackTreeNode { public: constexpr ALWAYS_INLINE Derived *GetPrev() { return static_cast< Derived *>(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); } constexpr ALWAYS_INLINE const Derived *GetPrev() const { return static_cast(impl::IntrusiveRedBlackTreeImpl::GetPrev(this)); }