From 02b126c2be644cf29206d97ba9e1a396dad0599c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 12 Apr 2022 16:47:36 -0700 Subject: [PATCH] os: refactor multi wait apis to better match Nintendo's latest implementation --- .../os/impl/os_multiple_wait_holder_base.hpp | 38 ++-- .../os/impl/os_multiple_wait_holder_impl.hpp | 14 +- .../impl/os_multiple_wait_holder_of_event.hpp | 16 +- ...ple_wait_holder_of_inter_process_event.hpp | 7 +- ...ultiple_wait_holder_of_interrupt_event.cpp | 5 +- ...ultiple_wait_holder_of_interrupt_event.hpp | 4 +- ..._multiple_wait_holder_of_message_queue.hpp | 71 +++--- ...multiple_wait_holder_of_native_handle.hpp} | 9 +- .../os_multiple_wait_holder_of_semaphore.hpp | 10 +- .../os_multiple_wait_holder_of_thread.hpp | 10 +- ...os_multiple_wait_holder_of_timer_event.hpp | 33 +-- .../source/os/impl/os_multiple_wait_impl.cpp | 202 +++++++++++------- .../source/os/impl/os_multiple_wait_impl.hpp | 47 ++-- .../os/impl/os_multiple_wait_object_list.hpp | 12 +- .../source/os/impl/os_thread_manager.cpp | 2 +- .../source/os/impl/os_timer_event_helper.cpp | 2 +- .../source/os/impl/os_timer_event_helper.hpp | 2 +- .../libstratosphere/source/os/os_event.cpp | 2 +- .../source/os/os_message_queue.cpp | 22 +- .../source/os/os_multiple_wait.cpp | 22 +- .../source/os/os_sdk_reply_and_receive.cpp | 2 +- .../source/os/os_semaphore.cpp | 4 +- .../source/os/os_timer_event.cpp | 16 +- 23 files changed, 309 insertions(+), 243 deletions(-) rename libraries/libstratosphere/source/os/impl/{os_multiple_wait_holder_of_handle.hpp => os_multiple_wait_holder_of_native_handle.hpp} (75%) diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_base.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_base.hpp index 1e3df3d9c..9e2bdee11 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_base.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_base.hpp @@ -30,46 +30,50 @@ namespace ams::os::impl { public: /* Gets whether the held object is currently signaled. */ virtual TriBool IsSignaled() const = 0; + /* Adds to multi wait's object list, returns is signaled. */ - virtual TriBool LinkToObjectList() = 0; + virtual TriBool AddToObjectList() = 0; + /* Removes from the multi wait's object list. */ - virtual void UnlinkFromObjectList() = 0; - /* Gets handle to output, returns os::InvalidNativeHandle on failure. */ - virtual NativeHandle GetHandle() const = 0; + virtual void RemoveFromObjectList() = 0; + + /* Gets whether waitable has a native handle, writes to output if it does. */ + virtual bool GetNativeHandle(os::NativeHandle *) const = 0; + /* Gets the amount of time remaining until this wakes up. */ - virtual TimeSpan GetAbsoluteWakeupTime() const { + virtual TimeSpan GetAbsoluteTimeToWakeup() const { return TimeSpan::FromNanoSeconds(std::numeric_limits::max()); } /* Interface with multi wait. */ - void SetMultiWait(MultiWaitImpl *m) { + ALWAYS_INLINE void SetMultiWait(MultiWaitImpl *m) { m_multi_wait = m; } - MultiWaitImpl *GetMultiWait() const { + ALWAYS_INLINE MultiWaitImpl *GetMultiWait() const { return m_multi_wait; } - bool IsLinked() const { - return m_multi_wait != nullptr; - } + ALWAYS_INLINE bool IsLinked() const { return m_multi_wait != nullptr; } + ALWAYS_INLINE bool IsNotLinked() const { return m_multi_wait == nullptr; } }; - class MultiWaitHolderOfUserObject : public MultiWaitHolderBase { + class MultiWaitHolderOfUserWaitObject : public MultiWaitHolderBase { public: /* All user objects have no handle to wait on. */ - virtual NativeHandle GetHandle() const override final { - return os::InvalidNativeHandle; + virtual bool GetNativeHandle(os::NativeHandle *) const override final { + return false; } }; - class MultiWaitHolderOfKernelObject : public MultiWaitHolderBase { + class MultiWaitHolderOfNativeWaitObject : public MultiWaitHolderBase { public: - /* All kernel objects have native handles, and thus don't have object list semantics. */ - virtual TriBool LinkToObjectList() override final { + /* All native objects have native handles, and thus don't have object list semantics. */ + virtual TriBool AddToObjectList() override final { return TriBool::Undefined; } - virtual void UnlinkFromObjectList() override final { + + virtual void RemoveFromObjectList() override final { /* ... */ } }; diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_impl.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_impl.hpp index a2eb40464..eb863e07d 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_impl.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_impl.hpp @@ -14,7 +14,7 @@ * along with this program. If not, see . */ #pragma once -#include "os_multiple_wait_holder_of_handle.hpp" +#include "os_multiple_wait_holder_of_native_handle.hpp" #include "os_multiple_wait_holder_of_event.hpp" #include "os_multiple_wait_holder_of_inter_process_event.hpp" #include "os_multiple_wait_holder_of_interrupt_event.hpp" @@ -27,30 +27,30 @@ namespace ams::os::impl { struct MultiWaitHolderImpl { union { - util::TypedStorage holder_of_handle_storage; + util::TypedStorage holder_of_native_handle_storage; util::TypedStorage holder_of_event_storage; util::TypedStorage holder_of_inter_process_event_storage; util::TypedStorage holder_of_interrupt_event_storage; util::TypedStorage holder_of_timer_event_storage; util::TypedStorage holder_of_thread_storage; util::TypedStorage holder_of_semaphore_storage; - util::TypedStorage holder_of_mq_for_not_full_storage; - util::TypedStorage holder_of_mq_for_not_empty_storage; + util::TypedStorage holder_of_mq_not_full_storage; + util::TypedStorage holder_of_mq_not_empty_storage; }; }; #define CHECK_HOLDER(T) \ static_assert(std::is_base_of<::ams::os::impl::MultiWaitHolderBase, T>::value && std::is_trivially_destructible::value, #T) - CHECK_HOLDER(MultiWaitHolderOfHandle); + CHECK_HOLDER(MultiWaitHolderOfNativeHandle); CHECK_HOLDER(MultiWaitHolderOfEvent); CHECK_HOLDER(MultiWaitHolderOfInterProcessEvent); CHECK_HOLDER(MultiWaitHolderOfInterruptEvent); CHECK_HOLDER(MultiWaitHolderOfTimerEvent); CHECK_HOLDER(MultiWaitHolderOfThread); CHECK_HOLDER(MultiWaitHolderOfSemaphore); - CHECK_HOLDER(MultiWaitHolderOfMessageQueueForNotFull); - CHECK_HOLDER(MultiWaitHolderOfMessageQueueForNotEmpty); + CHECK_HOLDER(MultiWaitHolderOfMessageQueueNotFull); + CHECK_HOLDER(MultiWaitHolderOfMessageQueueNotEmpty); #undef CHECK_HOLDER diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_event.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_event.hpp index 584453c56..b1099f18b 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_event.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_event.hpp @@ -19,11 +19,11 @@ namespace ams::os::impl { - class MultiWaitHolderOfEvent : public MultiWaitHolderOfUserObject { + class MultiWaitHolderOfEvent : public MultiWaitHolderOfUserWaitObject { private: EventType *m_event; private: - TriBool IsSignaledImpl() const { + ALWAYS_INLINE TriBool IsSignaledUnsafe() const { return m_event->signaled ? TriBool::True : TriBool::False; } public: @@ -32,20 +32,20 @@ namespace ams::os::impl { /* IsSignaled, Link, Unlink implemented. */ virtual TriBool IsSignaled() const override { std::scoped_lock lk(GetReference(m_event->cs_event)); - return this->IsSignaledImpl(); + return this->IsSignaledUnsafe(); } - virtual TriBool LinkToObjectList() override { + virtual TriBool AddToObjectList() override { std::scoped_lock lk(GetReference(m_event->cs_event)); - GetReference(m_event->multi_wait_object_list_storage).LinkMultiWaitHolder(*this); - return this->IsSignaledImpl(); + GetReference(m_event->multi_wait_object_list_storage).PushBackToList(*this); + return this->IsSignaledUnsafe(); } - virtual void UnlinkFromObjectList() override { + virtual void RemoveFromObjectList() override { std::scoped_lock lk(GetReference(m_event->cs_event)); - GetReference(m_event->multi_wait_object_list_storage).UnlinkMultiWaitHolder(*this); + GetReference(m_event->multi_wait_object_list_storage).EraseFromList(*this); } }; diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_inter_process_event.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_inter_process_event.hpp index 945c0f4b1..ab44f6b13 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_inter_process_event.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_inter_process_event.hpp @@ -19,7 +19,7 @@ namespace ams::os::impl { - class MultiWaitHolderOfInterProcessEvent : public MultiWaitHolderOfKernelObject { + class MultiWaitHolderOfInterProcessEvent : public MultiWaitHolderOfNativeWaitObject { private: InterProcessEventType *m_event; public: @@ -30,8 +30,9 @@ namespace ams::os::impl { return TriBool::Undefined; } - virtual NativeHandle GetHandle() const override { - return m_event->readable_handle; + virtual bool GetNativeHandle(os::NativeHandle *out) const override { + *out = m_event->readable_handle; + return true; } }; diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_interrupt_event.cpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_interrupt_event.cpp index 24a68b518..8f7b4371e 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_interrupt_event.cpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_interrupt_event.cpp @@ -19,8 +19,9 @@ namespace ams::os::impl { - NativeHandle MultiWaitHolderOfInterruptEvent::GetHandle() const { - return GetReference(m_event->impl).GetHandle(); + bool MultiWaitHolderOfInterruptEvent::GetNativeHandle(os::NativeHandle *out) const { + *out = GetReference(m_event->impl).GetHandle(); + return true; } } diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_interrupt_event.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_interrupt_event.hpp index 5964317e0..13a92e506 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_interrupt_event.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_interrupt_event.hpp @@ -18,7 +18,7 @@ namespace ams::os::impl { - class MultiWaitHolderOfInterruptEvent : public MultiWaitHolderOfKernelObject { + class MultiWaitHolderOfInterruptEvent : public MultiWaitHolderOfNativeWaitObject { private: InterruptEventType *m_event; public: @@ -29,7 +29,7 @@ namespace ams::os::impl { return TriBool::Undefined; } - virtual NativeHandle GetHandle() const override; + virtual bool GetNativeHandle(os::NativeHandle *out) const override; }; } diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_message_queue.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_message_queue.hpp index f30a83d41..826026b7a 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_message_queue.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_message_queue.hpp @@ -19,57 +19,64 @@ namespace ams::os::impl { - template - class MultiWaitHolderOfMessageQueue : public MultiWaitHolderOfUserObject { - static_assert(WaitType == MessageQueueWaitType::ForNotEmpty || WaitType == MessageQueueWaitType::ForNotFull); + class MultiWaitHolderOfMessageQueueNotEmpty : public MultiWaitHolderOfUserWaitObject { private: MessageQueueType *m_mq; private: - constexpr inline TriBool IsSignaledImpl() const { - if constexpr (WaitType == MessageQueueWaitType::ForNotEmpty) { - /* ForNotEmpty. */ - return m_mq->count > 0 ? TriBool::True : TriBool::False; - } else if constexpr (WaitType == MessageQueueWaitType::ForNotFull) { - /* ForNotFull */ - return m_mq->count < m_mq->capacity ? TriBool::True : TriBool::False; - } else { - static_assert(WaitType != WaitType); - } - } - - constexpr inline MultiWaitObjectList &GetObjectList() const { - if constexpr (WaitType == MessageQueueWaitType::ForNotEmpty) { - return GetReference(m_mq->waitlist_not_empty); - } else if constexpr (WaitType == MessageQueueWaitType::ForNotFull) { - return GetReference(m_mq->waitlist_not_full); - } else { - static_assert(WaitType != WaitType); - } + ALWAYS_INLINE TriBool IsSignaledUnsafe() const { + return m_mq->count > 0 ? TriBool::True : TriBool::False; } public: - explicit MultiWaitHolderOfMessageQueue(MessageQueueType *mq) : m_mq(mq) { /* ... */ } + explicit MultiWaitHolderOfMessageQueueNotEmpty(MessageQueueType *mq) : m_mq(mq) { /* ... */ } /* IsSignaled, Link, Unlink implemented. */ virtual TriBool IsSignaled() const override { std::scoped_lock lk(GetReference(m_mq->cs_queue)); - return this->IsSignaledImpl(); + return this->IsSignaledUnsafe(); } - virtual TriBool LinkToObjectList() override { + virtual TriBool AddToObjectList() override { std::scoped_lock lk(GetReference(m_mq->cs_queue)); - this->GetObjectList().LinkMultiWaitHolder(*this); - return this->IsSignaledImpl(); + GetReference(m_mq->waitlist_not_empty).PushBackToList(*this); + return this->IsSignaledUnsafe(); } - virtual void UnlinkFromObjectList() override { + virtual void RemoveFromObjectList() override { std::scoped_lock lk(GetReference(m_mq->cs_queue)); - this->GetObjectList().UnlinkMultiWaitHolder(*this); + GetReference(m_mq->waitlist_not_empty).EraseFromList(*this); } }; - using MultiWaitHolderOfMessageQueueForNotEmpty = MultiWaitHolderOfMessageQueue; - using MultiWaitHolderOfMessageQueueForNotFull = MultiWaitHolderOfMessageQueue; + class MultiWaitHolderOfMessageQueueNotFull : public MultiWaitHolderOfUserWaitObject { + private: + MessageQueueType *m_mq; + private: + ALWAYS_INLINE TriBool IsSignaledUnsafe() const { + return m_mq->count < m_mq->capacity ? TriBool::True : TriBool::False; + } + public: + explicit MultiWaitHolderOfMessageQueueNotFull(MessageQueueType *mq) : m_mq(mq) { /* ... */ } + + /* IsSignaled, Link, Unlink implemented. */ + virtual TriBool IsSignaled() const override { + std::scoped_lock lk(GetReference(m_mq->cs_queue)); + return this->IsSignaledUnsafe(); + } + + virtual TriBool AddToObjectList() override { + std::scoped_lock lk(GetReference(m_mq->cs_queue)); + + GetReference(m_mq->waitlist_not_full).PushBackToList(*this); + return this->IsSignaledUnsafe(); + } + + virtual void RemoveFromObjectList() override { + std::scoped_lock lk(GetReference(m_mq->cs_queue)); + + GetReference(m_mq->waitlist_not_full).EraseFromList(*this); + } + }; } diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_handle.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_native_handle.hpp similarity index 75% rename from libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_handle.hpp rename to libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_native_handle.hpp index 2765392c1..8c76babe0 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_handle.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_native_handle.hpp @@ -18,19 +18,20 @@ namespace ams::os::impl { - class MultiWaitHolderOfHandle : public MultiWaitHolderOfKernelObject { + class MultiWaitHolderOfNativeHandle : public MultiWaitHolderOfNativeWaitObject { private: NativeHandle m_handle; public: - explicit MultiWaitHolderOfHandle(NativeHandle h) : m_handle(h) { /* ... */ } + explicit MultiWaitHolderOfNativeHandle(NativeHandle h) : m_handle(h) { /* ... */ } /* IsSignaled, GetHandle both implemented. */ virtual TriBool IsSignaled() const override { return TriBool::Undefined; } - virtual NativeHandle GetHandle() const override { - return m_handle; + virtual bool GetNativeHandle(os::NativeHandle *out) const override { + *out = m_handle; + return true; } }; diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_semaphore.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_semaphore.hpp index 1a09a2d63..31ed60148 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_semaphore.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_semaphore.hpp @@ -19,7 +19,7 @@ namespace ams::os::impl { - class MultiWaitHolderOfSemaphore : public MultiWaitHolderOfUserObject { + class MultiWaitHolderOfSemaphore : public MultiWaitHolderOfUserWaitObject { private: SemaphoreType *m_semaphore; private: @@ -35,17 +35,17 @@ namespace ams::os::impl { return this->IsSignaledImpl(); } - virtual TriBool LinkToObjectList() override { + virtual TriBool AddToObjectList() override { std::scoped_lock lk(GetReference(m_semaphore->cs_sema)); - GetReference(m_semaphore->waitlist).LinkMultiWaitHolder(*this); + GetReference(m_semaphore->waitlist).PushBackToList(*this); return this->IsSignaledImpl(); } - virtual void UnlinkFromObjectList() override { + virtual void RemoveFromObjectList() override { std::scoped_lock lk(GetReference(m_semaphore->cs_sema)); - GetReference(m_semaphore->waitlist).UnlinkMultiWaitHolder(*this); + GetReference(m_semaphore->waitlist).EraseFromList(*this); } }; diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_thread.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_thread.hpp index 97a744f03..5ba44682f 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_thread.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_thread.hpp @@ -18,7 +18,7 @@ namespace ams::os::impl { - class MultiWaitHolderOfThread : public MultiWaitHolderOfUserObject { + class MultiWaitHolderOfThread : public MultiWaitHolderOfUserWaitObject { private: ThreadType *m_thread; private: @@ -34,17 +34,17 @@ namespace ams::os::impl { return this->IsSignaledImpl(); } - virtual TriBool LinkToObjectList() override { + virtual TriBool AddToObjectList() override { std::scoped_lock lk(GetReference(m_thread->cs_thread)); - GetReference(m_thread->waitlist).LinkMultiWaitHolder(*this); + GetReference(m_thread->waitlist).PushBackToList(*this); return this->IsSignaledImpl(); } - virtual void UnlinkFromObjectList() override { + virtual void RemoveFromObjectList() override { std::scoped_lock lk(GetReference(m_thread->cs_thread)); - GetReference(m_thread->waitlist).UnlinkMultiWaitHolder(*this); + GetReference(m_thread->waitlist).EraseFromList(*this); } }; diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_timer_event.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_timer_event.hpp index 56f7a76bf..517089191 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_timer_event.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_holder_of_timer_event.hpp @@ -21,13 +21,15 @@ namespace ams::os::impl { - class MultiWaitHolderOfTimerEvent : public MultiWaitHolderOfUserObject { + class MultiWaitHolderOfTimerEvent : public MultiWaitHolderOfUserWaitObject { private: TimerEventType *m_event; private: - TriBool IsSignaledImpl() const { - TimeSpan cur_time = this->GetMultiWait()->GetCurrentTime(); - UpdateSignalStateAndRecalculateNextTimeToWakeupUnsafe(m_event, cur_time); + TriBool IsSignaledUnsafe() const { + TimeSpan cur_time = this->GetMultiWait()->GetCurrTime(); + + os::impl::UpdateSignalStateAndRecalcNextTimeToWakeupUnsafe(m_event, cur_time); + return m_event->signaled ? TriBool::True : TriBool::False; } public: @@ -36,31 +38,30 @@ namespace ams::os::impl { /* IsSignaled, Link, Unlink implemented. */ virtual TriBool IsSignaled() const override { std::scoped_lock lk(GetReference(m_event->cs_timer_event)); - return this->IsSignaledImpl(); + + return this->IsSignaledUnsafe(); } - virtual TriBool LinkToObjectList() override { + virtual TriBool AddToObjectList() override { std::scoped_lock lk(GetReference(m_event->cs_timer_event)); - GetReference(m_event->multi_wait_object_list_storage).LinkMultiWaitHolder(*this); - return this->IsSignaledImpl(); + GetReference(m_event->multi_wait_object_list_storage).PushBackToList(*this); + + return this->IsSignaledUnsafe(); } - virtual void UnlinkFromObjectList() override { + virtual void RemoveFromObjectList() override { std::scoped_lock lk(GetReference(m_event->cs_timer_event)); - GetReference(m_event->multi_wait_object_list_storage).UnlinkMultiWaitHolder(*this); + GetReference(m_event->multi_wait_object_list_storage).EraseFromList(*this); } /* Gets the amount of time remaining until this wakes up. */ - virtual TimeSpan GetAbsoluteWakeupTime() const override { + virtual TimeSpan GetAbsoluteTimeToWakeup() const override { std::scoped_lock lk(GetReference(m_event->cs_timer_event)); - if (m_event->timer_state == TimerEventType::TimerState_Stop) { - return TimeSpan::FromNanoSeconds(std::numeric_limits::max()); - } - - return GetReference(m_event->next_time_to_wakeup); + return m_event->timer_state != TimerEventType::TimerState_Stop ? GetReference(m_event->next_time_to_wakeup) + : TimeSpan::FromNanoSeconds(std::numeric_limits::max()); } }; diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.cpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.cpp index 41b8640c9..ef2921597 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.cpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.cpp @@ -20,149 +20,194 @@ namespace ams::os::impl { - Result MultiWaitImpl::WaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, NativeHandle reply_target) { + template + Result MultiWaitImpl::WaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, NativeHandle reply_target) { /* Prepare for processing. */ m_signaled_holder = nullptr; m_target_impl.SetCurrentThreadHandleForCancelWait(); - MultiWaitHolderBase *holder = this->LinkHoldersToObjectList(); - /* When we're done, cleanup and set output. */ - ON_SCOPE_EXIT { - /* Unlink holders from the current object list. */ - this->UnlinkHoldersFromObjectList(); - - /* Clear cancel wait. */ - m_target_impl.ClearCurrentThreadHandleForCancelWait(); - - /* Set output holder. */ - *out = holder; - }; + /* Add each holder to the object list, and try to find one that's signaled. */ + MultiWaitHolderBase *signaled_holder = this->AddToEachObjectListAndCheckObjectState(); /* Check if we've been signaled. */ { std::scoped_lock lk(m_cs_wait); if (m_signaled_holder != nullptr) { - holder = m_signaled_holder; + signaled_holder = m_signaled_holder; } } /* Process object array. */ - if (holder != nullptr) { - R_SUCCEED_IF(!(reply && reply_target != os::InvalidNativeHandle)); - - ON_RESULT_FAILURE { holder = nullptr; }; - - s32 index; - R_RETURN(m_target_impl.TimedReplyAndReceive(std::addressof(index), nullptr, 0, 0, reply_target, TimeSpan::FromNanoSeconds(0))) + if (signaled_holder != nullptr) { + /* If we have a signaled holder and we're allowed to reply, try to do so. */ + if constexpr (AllowReply) { + /* Try to reply to the reply target. */ + if (reply_target != os::InvalidNativeHandle) { + s32 index; + R_TRY(m_target_impl.TimedReplyAndReceive(std::addressof(index), nullptr, 0, 0, reply_target, TimeSpan::FromNanoSeconds(0))); + } + } } else { - R_RETURN(this->WaitAnyHandleImpl(std::addressof(holder), infinite, timeout, reply, reply_target)); + /* If there's no signaled holder, wait for one to be signaled. */ + R_TRY(this->InternalWaitAnyImpl(std::addressof(signaled_holder), infinite, timeout, reply_target)); } + + /* Remove each holder from the current object list. */ + this->RemoveFromEachObjectList(); + + /* Clear cancel wait. */ + m_target_impl.ClearCurrentThreadHandleForCancelWait(); + + /* Set output holder. */ + *out = signaled_holder; + R_SUCCEED(); } - Result MultiWaitImpl::WaitAnyHandleImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, NativeHandle reply_target) { + template + Result MultiWaitImpl::InternalWaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, NativeHandle reply_target) { + /* Build the objects array. */ NativeHandle object_handles[MaximumHandleCount]; MultiWaitHolderBase *objects[MaximumHandleCount]; - const s32 count = this->BuildHandleArray(object_handles, objects, MaximumHandleCount); - const TimeSpan end_time = infinite ? TimeSpan::FromNanoSeconds(std::numeric_limits::max()) : GetCurrentTick().ToTimeSpan() + timeout; + const s32 count = this->ConstructObjectsArray(object_handles, objects, MaximumHandleCount); + /* Determine the appropriate end time for our wait. */ + const TimeSpan end_time = infinite ? TimeSpan::FromNanoSeconds(std::numeric_limits::max()) : os::impl::GetCurrentTick().ToTimeSpan() + timeout; + + /* Loop, waiting until we're done. */ while (true) { - m_current_time = GetCurrentTick().ToTimeSpan(); + /* Update the current time for our loop. */ + m_current_time = os::impl::GetCurrentTick().ToTimeSpan(); + /* Determine which object has the minimum wakeup time. */ TimeSpan min_timeout = 0; - MultiWaitHolderBase *min_timeout_object = this->RecalculateNextTimeout(std::addressof(min_timeout), end_time); + MultiWaitHolderBase *min_timeout_object = this->RecalcMultiWaitTimeout(std::addressof(min_timeout), end_time); - s32 index = WaitInvalid; + /* Perform the wait using native apis. */ + s32 index = WaitInvalid; Result wait_result = ResultSuccess(); - if (reply) { - if (infinite && min_timeout_object == nullptr) { + if (infinite && min_timeout_object == nullptr) { + /* If we're performing an infinite wait, just do the appropriate wait or reply/receive. */ + if constexpr (AllowReply) { wait_result = m_target_impl.ReplyAndReceive(std::addressof(index), object_handles, MaximumHandleCount, count, reply_target); } else { - wait_result = m_target_impl.TimedReplyAndReceive(std::addressof(index), object_handles, MaximumHandleCount, count, reply_target, min_timeout); + wait_result = m_target_impl.WaitAny(std::addressof(index), object_handles, MaximumHandleCount, count); } - } else if (infinite && min_timeout_object == nullptr) { - wait_result = m_target_impl.WaitAny(std::addressof(index), object_handles, MaximumHandleCount, count); } else { - if (count == 0 && min_timeout == 0) { - index = WaitTimedOut; + /* We need to do our wait with a timeout. */ + if constexpr (AllowReply) { + wait_result = m_target_impl.TimedReplyAndReceive(std::addressof(index), object_handles, MaximumHandleCount, count, reply_target, min_timeout); } else { - wait_result = m_target_impl.TimedWaitAny(std::addressof(index), object_handles, MaximumHandleCount, count, min_timeout); - AMS_ABORT_UNLESS(index != WaitInvalid); + if (count != 0 || min_timeout != 0) { + wait_result = m_target_impl.TimedWaitAny(std::addressof(index), object_handles, MaximumHandleCount, count, min_timeout); + } else { + index = WaitTimedOut; + } } } - if (index == WaitInvalid) { - *out = nullptr; - R_RETURN(wait_result); - } - + /* Process the result of our wait. */ switch (index) { - case WaitTimedOut: - if (min_timeout_object) { - m_current_time = GetCurrentTick().ToTimeSpan(); - if (min_timeout_object->IsSignaled() == TriBool::True) { - std::scoped_lock lk(m_cs_wait); - m_signaled_holder = min_timeout_object; - *out = min_timeout_object; - R_RETURN(wait_result); - } - } else { + case WaitInvalid: + /* If an invalid wait was performed, just return no signaled holder. */ + { *out = nullptr; R_RETURN(wait_result); } break; case WaitCancelled: + /* If the wait was canceled, it might be because a non-native waitable was signaled. Check and return it, if this is the case. */ { std::scoped_lock lk(m_cs_wait); + if (m_signaled_holder) { *out = m_signaled_holder; R_RETURN(wait_result); } } break; + case WaitTimedOut: + /* If we timed out, this might have been because a timer is now signaled. */ + if (min_timeout_object != nullptr) { + /* Update our current time. */ + m_current_time = GetCurrentTick().ToTimeSpan(); + + /* Check if the minimum timeout object is now signaled. */ + if (min_timeout_object->IsSignaled() == TriBool::True) { + std::scoped_lock lk(m_cs_wait); + + /* Set our signaled holder (and the output) as the newly signaled minimum timeout object. */ + m_signaled_holder = min_timeout_object; + *out = min_timeout_object; + R_RETURN(wait_result); + } + } else { + /* If we have no minimum timeout object but we timed out, just return no signaled holder. */ + *out = nullptr; + R_RETURN(wait_result); + } + break; default: /* 0 - 0x3F, valid. */ { - if constexpr (MaximumHandleCount > 0) { - AMS_ASSERT(0 <= index && index < static_cast(MaximumHandleCount)); + /* Sanity check that the returned index is within the range of our objects array. */ + AMS_ASSERT(0 <= index && index < count); - std::scoped_lock lk(m_cs_wait); - m_signaled_holder = objects[index]; - *out = objects[index]; - R_RETURN(wait_result); - } else { - AMS_ABORT_UNLESS(MaximumHandleCount > 0); - } + std::scoped_lock lk(m_cs_wait); + + /* Set our signaled holder (and the output) as the newly signaled object. */ + m_signaled_holder = objects[index]; + *out = objects[index]; + R_RETURN(wait_result); } break; } - reply_target = os::InvalidNativeHandle; + /* We're going to be looping again; prevent ourselves from replying to the same object twice. */ + if constexpr (AllowReply) { + reply_target = os::InvalidNativeHandle; + } } } - s32 MultiWaitImpl::BuildHandleArray(NativeHandle out_handles[], MultiWaitHolderBase *out_objects[], s32 num) { + MultiWaitHolderBase *MultiWaitImpl::WaitAnyImpl(bool infinite, TimeSpan timeout) { + MultiWaitHolderBase *holder = nullptr; + + const Result wait_result = this->WaitAnyImpl(std::addressof(holder), infinite, timeout, os::InvalidNativeHandle); + R_ASSERT(wait_result); + AMS_UNUSED(wait_result); + + return holder; + } + + Result MultiWaitImpl::ReplyAndReceive(MultiWaitHolderBase **out, NativeHandle reply_target) { + R_RETURN(this->WaitAnyImpl(out, true, TimeSpan::FromNanoSeconds(std::numeric_limits::max()), reply_target)); + } + + s32 MultiWaitImpl::ConstructObjectsArray(NativeHandle out_handles[], MultiWaitHolderBase *out_objects[], s32 num) { + /* Add all objects with a native handle to the output array. */ s32 count = 0; for (MultiWaitHolderBase &holder_base : m_multi_wait_list) { - if (auto handle = holder_base.GetHandle(); handle != os::InvalidNativeHandle) { + os::NativeHandle handle = os::InvalidNativeHandle; + if (holder_base.GetNativeHandle(std::addressof(handle))) { AMS_ABORT_UNLESS(count < num); out_handles[count] = handle; out_objects[count] = std::addressof(holder_base); - count++; + + ++count; } } return count; } - MultiWaitHolderBase *MultiWaitImpl::LinkHoldersToObjectList() { + MultiWaitHolderBase *MultiWaitImpl::AddToEachObjectListAndCheckObjectState() { + /* Add each holder to the current object list, checking for the first signaled object. */ MultiWaitHolderBase *signaled_holder = nullptr; for (MultiWaitHolderBase &holder_base : m_multi_wait_list) { - TriBool is_signaled = holder_base.LinkToObjectList(); - - if (signaled_holder == nullptr && is_signaled == TriBool::True) { + if (const TriBool is_signaled = holder_base.AddToObjectList(); signaled_holder == nullptr && is_signaled == TriBool::True) { signaled_holder = std::addressof(holder_base); } } @@ -170,36 +215,43 @@ namespace ams::os::impl { return signaled_holder; } - void MultiWaitImpl::UnlinkHoldersFromObjectList() { + void MultiWaitImpl::RemoveFromEachObjectList() { + /* Remove each holder from the current object list. */ for (MultiWaitHolderBase &holder_base : m_multi_wait_list) { - holder_base.UnlinkFromObjectList(); + holder_base.RemoveFromObjectList(); } } - MultiWaitHolderBase *MultiWaitImpl::RecalculateNextTimeout(TimeSpan *out_min_timeout, TimeSpan end_time) { + MultiWaitHolderBase *MultiWaitImpl::RecalcMultiWaitTimeout(TimeSpan *out_min_timeout, TimeSpan end_time) { + /* Find the holder with the minimum end time. */ MultiWaitHolderBase *min_timeout_holder = nullptr; TimeSpan min_time = end_time; for (MultiWaitHolderBase &holder_base : m_multi_wait_list) { - if (const TimeSpan cur_time = holder_base.GetAbsoluteWakeupTime(); cur_time < min_time) { + if (const TimeSpan cur_time = holder_base.GetAbsoluteTimeToWakeup(); cur_time < min_time) { min_timeout_holder = std::addressof(holder_base); - min_time = cur_time; + min_time = cur_time; } } + /* If the minimum time is under the current time, we can't wait; otherwise, get the time to the minimum end time. */ if (min_time < m_current_time) { *out_min_timeout = 0; } else { *out_min_timeout = min_time - m_current_time; } + return min_timeout_holder; } - void MultiWaitImpl::SignalAndWakeupThread(MultiWaitHolderBase *holder_base) { + void MultiWaitImpl::NotifyAndWakeupThread(MultiWaitHolderBase *holder_base) { std::scoped_lock lk(m_cs_wait); + /* If we don't have a signaled holder, set our signaled holder. */ if (m_signaled_holder == nullptr) { m_signaled_holder = holder_base; + + /* Cancel any ongoing waits. */ m_target_impl.CancelWait(); } } diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.hpp index 079eb685e..0007ab76c 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_impl.hpp @@ -44,24 +44,20 @@ namespace ams::os::impl { InternalCriticalSection m_cs_wait; MultiWaitTargetImpl m_target_impl; private: - Result WaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, NativeHandle reply_target); - Result WaitAnyHandleImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, bool reply, NativeHandle reply_target); - s32 BuildHandleArray(NativeHandle out_handles[], MultiWaitHolderBase *out_objects[], s32 num); + template + Result WaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, NativeHandle reply_target); - MultiWaitHolderBase *LinkHoldersToObjectList(); - void UnlinkHoldersFromObjectList(); + template + Result InternalWaitAnyImpl(MultiWaitHolderBase **out, bool infinite, TimeSpan timeout, NativeHandle reply_target); - MultiWaitHolderBase *RecalculateNextTimeout(TimeSpan *out_min_timeout, TimeSpan end_time); + s32 ConstructObjectsArray(NativeHandle out_handles[], MultiWaitHolderBase *out_objects[], s32 num); - MultiWaitHolderBase *WaitAnyImpl(bool infinite, TimeSpan timeout) { - MultiWaitHolderBase *holder = nullptr; + MultiWaitHolderBase *AddToEachObjectListAndCheckObjectState(); + void RemoveFromEachObjectList(); - const Result wait_result = this->WaitAnyImpl(std::addressof(holder), infinite, timeout, false, os::InvalidNativeHandle); - R_ASSERT(wait_result); - AMS_UNUSED(wait_result); + MultiWaitHolderBase *RecalcMultiWaitTimeout(TimeSpan *out_min_timeout, TimeSpan end_time); - return holder; - } + MultiWaitHolderBase *WaitAnyImpl(bool infinite, TimeSpan timeout); public: /* Wait. */ MultiWaitHolderBase *WaitAny() { @@ -76,44 +72,47 @@ namespace ams::os::impl { return this->WaitAnyImpl(false, ts); } - Result ReplyAndReceive(MultiWaitHolderBase **out, NativeHandle reply_target) { - R_RETURN(this->WaitAnyImpl(out, true, TimeSpan::FromNanoSeconds(std::numeric_limits::max()), true, reply_target)); - } + Result ReplyAndReceive(MultiWaitHolderBase **out, NativeHandle reply_target); /* List management. */ - bool IsEmpty() const { + bool IsListEmpty() const { return m_multi_wait_list.empty(); } - void LinkMultiWaitHolder(MultiWaitHolderBase &holder_base) { + bool IsListNotEmpty() const { + return !m_multi_wait_list.empty(); + } + + void PushBackToList(MultiWaitHolderBase &holder_base) { m_multi_wait_list.push_back(holder_base); } - void UnlinkMultiWaitHolder(MultiWaitHolderBase &holder_base) { + void EraseFromList(MultiWaitHolderBase &holder_base) { m_multi_wait_list.erase(m_multi_wait_list.iterator_to(holder_base)); } - void UnlinkAll() { - while (!this->IsEmpty()) { + void EraseAllFromList() { + while (!m_multi_wait_list.empty()) { m_multi_wait_list.front().SetMultiWait(nullptr); m_multi_wait_list.pop_front(); } } - void MoveAllFrom(MultiWaitImpl &other) { + void MoveAllFromOther(MultiWaitImpl &other) { /* Set ourselves as multi wait for all of the other's holders. */ for (auto &w : other.m_multi_wait_list) { w.SetMultiWait(this); } + m_multi_wait_list.splice(m_multi_wait_list.end(), other.m_multi_wait_list); } /* Other. */ - TimeSpan GetCurrentTime() const { + TimeSpan GetCurrTime() const { return m_current_time; } - void SignalAndWakeupThread(MultiWaitHolderBase *holder_base); + void NotifyAndWakeupThread(MultiWaitHolderBase *holder_base); }; } diff --git a/libraries/libstratosphere/source/os/impl/os_multiple_wait_object_list.hpp b/libraries/libstratosphere/source/os/impl/os_multiple_wait_object_list.hpp index 7284f5863..04c90f0d7 100644 --- a/libraries/libstratosphere/source/os/impl/os_multiple_wait_object_list.hpp +++ b/libraries/libstratosphere/source/os/impl/os_multiple_wait_object_list.hpp @@ -25,15 +25,15 @@ namespace ams::os::impl { private: ListType m_object_list; public: - void SignalAllThreads() { + void WakeupAllMultiWaitThreadsUnsafe() { for (MultiWaitHolderBase &holder_base : m_object_list) { - holder_base.GetMultiWait()->SignalAndWakeupThread(std::addressof(holder_base)); + holder_base.GetMultiWait()->NotifyAndWakeupThread(std::addressof(holder_base)); } } - void BroadcastAllThreads() { + void BroadcastToUpdateObjectStateUnsafe() { for (MultiWaitHolderBase &holder_base : m_object_list) { - holder_base.GetMultiWait()->SignalAndWakeupThread(nullptr); + holder_base.GetMultiWait()->NotifyAndWakeupThread(nullptr); } } @@ -41,11 +41,11 @@ namespace ams::os::impl { return m_object_list.empty(); } - void LinkMultiWaitHolder(MultiWaitHolderBase &holder_base) { + void PushBackToList(MultiWaitHolderBase &holder_base) { m_object_list.push_back(holder_base); } - void UnlinkMultiWaitHolder(MultiWaitHolderBase &holder_base) { + void EraseFromList(MultiWaitHolderBase &holder_base) { m_object_list.erase(m_object_list.iterator_to(holder_base)); } }; diff --git a/libraries/libstratosphere/source/os/impl/os_thread_manager.cpp b/libraries/libstratosphere/source/os/impl/os_thread_manager.cpp index f374dee8e..9e48402e8 100644 --- a/libraries/libstratosphere/source/os/impl/os_thread_manager.cpp +++ b/libraries/libstratosphere/source/os/impl/os_thread_manager.cpp @@ -111,7 +111,7 @@ namespace ams::os::impl { thread->state = ThreadType::State_Terminated; GetReference(thread->cv_thread).Broadcast(); - GetReference(thread->waitlist).SignalAllThreads(); + GetReference(thread->waitlist).WakeupAllMultiWaitThreadsUnsafe(); } void ThreadManager::CleanupThread() { diff --git a/libraries/libstratosphere/source/os/impl/os_timer_event_helper.cpp b/libraries/libstratosphere/source/os/impl/os_timer_event_helper.cpp index 954e03236..e484a4c02 100644 --- a/libraries/libstratosphere/source/os/impl/os_timer_event_helper.cpp +++ b/libraries/libstratosphere/source/os/impl/os_timer_event_helper.cpp @@ -34,7 +34,7 @@ namespace ams::os::impl { event->timer_state = TimerEventType::TimerState_Stop; } - bool UpdateSignalStateAndRecalculateNextTimeToWakeupUnsafe(TimerEventType *event, TimeSpan cur_time) { + bool UpdateSignalStateAndRecalcNextTimeToWakeupUnsafe(TimerEventType *event, TimeSpan cur_time) { TimeSpan next_time = GetReference(event->next_time_to_wakeup); switch (event->timer_state) { diff --git a/libraries/libstratosphere/source/os/impl/os_timer_event_helper.hpp b/libraries/libstratosphere/source/os/impl/os_timer_event_helper.hpp index 081d67f0a..cd799d673 100644 --- a/libraries/libstratosphere/source/os/impl/os_timer_event_helper.hpp +++ b/libraries/libstratosphere/source/os/impl/os_timer_event_helper.hpp @@ -24,7 +24,7 @@ namespace ams::os { TimeSpan SaturatedAdd(TimeSpan t1, TimeSpan t2); void StopTimerUnsafe(TimerEventType *event); - bool UpdateSignalStateAndRecalculateNextTimeToWakeupUnsafe(TimerEventType *event, TimeSpan cur_time); + bool UpdateSignalStateAndRecalcNextTimeToWakeupUnsafe(TimerEventType *event, TimeSpan cur_time); } diff --git a/libraries/libstratosphere/source/os/os_event.cpp b/libraries/libstratosphere/source/os/os_event.cpp index 4662f235f..bf2c7479d 100644 --- a/libraries/libstratosphere/source/os/os_event.cpp +++ b/libraries/libstratosphere/source/os/os_event.cpp @@ -89,7 +89,7 @@ namespace ams::os { } /* Wake up whatever manager, if any. */ - GetReference(event->multi_wait_object_list_storage).SignalAllThreads(); + GetReference(event->multi_wait_object_list_storage).WakeupAllMultiWaitThreadsUnsafe(); } void WaitEvent(EventType *event) { diff --git a/libraries/libstratosphere/source/os/os_message_queue.cpp b/libraries/libstratosphere/source/os/os_message_queue.cpp index 71206809d..6373b6749 100644 --- a/libraries/libstratosphere/source/os/os_message_queue.cpp +++ b/libraries/libstratosphere/source/os/os_message_queue.cpp @@ -84,7 +84,7 @@ namespace ams::os { /* Send, signal. */ MessageQueueHelper::EnqueueUnsafe(mq, data); GetReference(mq->cv_not_empty).Broadcast(); - GetReference(mq->waitlist_not_empty).SignalAllThreads(); + GetReference(mq->waitlist_not_empty).WakeupAllMultiWaitThreadsUnsafe(); } } @@ -102,7 +102,7 @@ namespace ams::os { /* Send, signal. */ MessageQueueHelper::EnqueueUnsafe(mq, data); GetReference(mq->cv_not_empty).Broadcast(); - GetReference(mq->waitlist_not_empty).SignalAllThreads(); + GetReference(mq->waitlist_not_empty).WakeupAllMultiWaitThreadsUnsafe(); } return true; @@ -127,7 +127,7 @@ namespace ams::os { /* Send, signal. */ MessageQueueHelper::EnqueueUnsafe(mq, data); GetReference(mq->cv_not_empty).Broadcast(); - GetReference(mq->waitlist_not_empty).SignalAllThreads(); + GetReference(mq->waitlist_not_empty).WakeupAllMultiWaitThreadsUnsafe(); } return true; @@ -148,7 +148,7 @@ namespace ams::os { /* Send, signal. */ MessageQueueHelper::JamUnsafe(mq, data); GetReference(mq->cv_not_empty).Broadcast(); - GetReference(mq->waitlist_not_empty).SignalAllThreads(); + GetReference(mq->waitlist_not_empty).WakeupAllMultiWaitThreadsUnsafe(); } } @@ -166,7 +166,7 @@ namespace ams::os { /* Send, signal. */ MessageQueueHelper::JamUnsafe(mq, data); GetReference(mq->cv_not_empty).Broadcast(); - GetReference(mq->waitlist_not_empty).SignalAllThreads(); + GetReference(mq->waitlist_not_empty).WakeupAllMultiWaitThreadsUnsafe(); } return true; @@ -191,7 +191,7 @@ namespace ams::os { /* Send, signal. */ MessageQueueHelper::JamUnsafe(mq, data); GetReference(mq->cv_not_empty).Broadcast(); - GetReference(mq->waitlist_not_empty).SignalAllThreads(); + GetReference(mq->waitlist_not_empty).WakeupAllMultiWaitThreadsUnsafe(); } return true; @@ -212,7 +212,7 @@ namespace ams::os { /* Receive, signal. */ *out = MessageQueueHelper::DequeueUnsafe(mq); GetReference(mq->cv_not_full).Broadcast(); - GetReference(mq->waitlist_not_full).SignalAllThreads(); + GetReference(mq->waitlist_not_full).WakeupAllMultiWaitThreadsUnsafe(); } } @@ -230,7 +230,7 @@ namespace ams::os { /* Receive, signal. */ *out = MessageQueueHelper::DequeueUnsafe(mq); GetReference(mq->cv_not_full).Broadcast(); - GetReference(mq->waitlist_not_full).SignalAllThreads(); + GetReference(mq->waitlist_not_full).WakeupAllMultiWaitThreadsUnsafe(); } return true; @@ -255,7 +255,7 @@ namespace ams::os { /* Receive, signal. */ *out = MessageQueueHelper::DequeueUnsafe(mq); GetReference(mq->cv_not_full).Broadcast(); - GetReference(mq->waitlist_not_full).SignalAllThreads(); + GetReference(mq->waitlist_not_full).WakeupAllMultiWaitThreadsUnsafe(); } return true; @@ -324,10 +324,10 @@ namespace ams::os { switch (type) { case MessageQueueWaitType::ForNotFull: - util::ConstructAt(GetReference(multi_wait_holder->impl_storage).holder_of_mq_for_not_full_storage, mq); + util::ConstructAt(GetReference(multi_wait_holder->impl_storage).holder_of_mq_not_full_storage, mq); break; case MessageQueueWaitType::ForNotEmpty: - util::ConstructAt(GetReference(multi_wait_holder->impl_storage).holder_of_mq_for_not_empty_storage, mq); + util::ConstructAt(GetReference(multi_wait_holder->impl_storage).holder_of_mq_not_empty_storage, mq); break; AMS_UNREACHABLE_DEFAULT_CASE(); } diff --git a/libraries/libstratosphere/source/os/os_multiple_wait.cpp b/libraries/libstratosphere/source/os/os_multiple_wait.cpp index 97db6db2b..d0be10124 100644 --- a/libraries/libstratosphere/source/os/os_multiple_wait.cpp +++ b/libraries/libstratosphere/source/os/os_multiple_wait.cpp @@ -44,7 +44,7 @@ namespace ams::os { auto &impl = GetMultiWaitImpl(multi_wait); AMS_ASSERT(multi_wait->state == MultiWaitType::State_Initialized); - AMS_ASSERT(impl.IsEmpty()); + AMS_ASSERT(impl.IsListEmpty()); AMS_UNUSED(impl); /* Mark not initialized. */ @@ -58,7 +58,7 @@ namespace ams::os { auto &impl = GetMultiWaitImpl(multi_wait); AMS_ASSERT(multi_wait->state == MultiWaitType::State_Initialized); - AMS_ASSERT(!impl.IsEmpty()); + AMS_ASSERT(impl.IsListNotEmpty()); auto *holder = CastToMultiWaitHolder(impl.WaitAny()); AMS_ASSERT(holder != nullptr); @@ -69,7 +69,7 @@ namespace ams::os { auto &impl = GetMultiWaitImpl(multi_wait); AMS_ASSERT(multi_wait->state == MultiWaitType::State_Initialized); - AMS_ASSERT(!impl.IsEmpty()); + AMS_ASSERT(impl.IsListNotEmpty()); auto *holder = CastToMultiWaitHolder(impl.TryWaitAny()); return holder; @@ -79,7 +79,7 @@ namespace ams::os { auto &impl = GetMultiWaitImpl(multi_wait); AMS_ASSERT(multi_wait->state == MultiWaitType::State_Initialized); - AMS_ASSERT(!impl.IsEmpty()); + AMS_ASSERT(impl.IsListNotEmpty()); AMS_ASSERT(timeout.GetNanoSeconds() >= 0); auto *holder = CastToMultiWaitHolder(impl.TimedWaitAny(timeout)); @@ -89,7 +89,7 @@ namespace ams::os { void FinalizeMultiWaitHolder(MultiWaitHolderType *holder) { auto *holder_base = reinterpret_cast(GetPointer(holder->impl_storage)); - AMS_ASSERT(!holder_base->IsLinked()); + AMS_ASSERT(holder_base->IsNotLinked()); /* Destroy. */ static_assert(std::is_trivially_destructible::value); @@ -102,9 +102,9 @@ namespace ams::os { auto *holder_base = reinterpret_cast(GetPointer(holder->impl_storage)); AMS_ASSERT(multi_wait->state == MultiWaitType::State_Initialized); - AMS_ASSERT(!holder_base->IsLinked()); + AMS_ASSERT(holder_base->IsNotLinked()); - impl.LinkMultiWaitHolder(*holder_base); + impl.PushBackToList(*holder_base); holder_base->SetMultiWait(std::addressof(impl)); } @@ -114,7 +114,7 @@ namespace ams::os { /* Don't allow unlinking of an unlinked holder. */ AMS_ABORT_UNLESS(holder_base->IsLinked()); - holder_base->GetMultiWait()->UnlinkMultiWaitHolder(*holder_base); + holder_base->GetMultiWait()->EraseFromList(*holder_base); holder_base->SetMultiWait(nullptr); } @@ -123,7 +123,7 @@ namespace ams::os { AMS_ASSERT(multi_wait->state == MultiWaitType::State_Initialized); - return impl.UnlinkAll(); + return impl.EraseAllFromList(); } void MoveAllMultiWaitHolder(MultiWaitType *_dst, MultiWaitType *_src) { @@ -133,7 +133,7 @@ namespace ams::os { AMS_ASSERT(_dst->state == MultiWaitType::State_Initialized); AMS_ASSERT(_src->state == MultiWaitType::State_Initialized); - return dst.MoveAllFrom(src); + return dst.MoveAllFromOther(src); } void SetMultiWaitHolderUserData(MultiWaitHolderType *holder, uintptr_t user_data) { @@ -147,7 +147,7 @@ namespace ams::os { void InitializeMultiWaitHolder(MultiWaitHolderType *holder, NativeHandle handle) { AMS_ASSERT(handle != os::InvalidNativeHandle); - util::ConstructAt(GetReference(holder->impl_storage).holder_of_handle_storage, handle); + util::ConstructAt(GetReference(holder->impl_storage).holder_of_native_handle_storage, handle); holder->user_data = 0; } diff --git a/libraries/libstratosphere/source/os/os_sdk_reply_and_receive.cpp b/libraries/libstratosphere/source/os/os_sdk_reply_and_receive.cpp index 288879d27..58187e63d 100644 --- a/libraries/libstratosphere/source/os/os_sdk_reply_and_receive.cpp +++ b/libraries/libstratosphere/source/os/os_sdk_reply_and_receive.cpp @@ -36,7 +36,7 @@ namespace ams::os { auto &impl = GetMultiWaitImpl(multi_wait); AMS_ASSERT(multi_wait->state == MultiWaitType::State_Initialized); - AMS_ASSERT(!impl.IsEmpty()); + AMS_ASSERT(impl.IsListNotEmpty()); impl::MultiWaitHolderBase *holder_base; ON_SCOPE_EXIT { *out = CastToMultiWaitHolder(holder_base); }; diff --git a/libraries/libstratosphere/source/os/os_semaphore.cpp b/libraries/libstratosphere/source/os/os_semaphore.cpp index 2031d8241..be470cf62 100644 --- a/libraries/libstratosphere/source/os/os_semaphore.cpp +++ b/libraries/libstratosphere/source/os/os_semaphore.cpp @@ -117,7 +117,7 @@ namespace ams::os { ++sema->count; GetReference(sema->cv_not_zero).Signal(); - GetReference(sema->waitlist).SignalAllThreads(); + GetReference(sema->waitlist).WakeupAllMultiWaitThreadsUnsafe(); } } @@ -132,7 +132,7 @@ namespace ams::os { sema->count += count; GetReference(sema->cv_not_zero).Broadcast(); - GetReference(sema->waitlist).SignalAllThreads(); + GetReference(sema->waitlist).WakeupAllMultiWaitThreadsUnsafe(); } } diff --git a/libraries/libstratosphere/source/os/os_timer_event.cpp b/libraries/libstratosphere/source/os/os_timer_event.cpp index 256293b5e..6f941856d 100644 --- a/libraries/libstratosphere/source/os/os_timer_event.cpp +++ b/libraries/libstratosphere/source/os/os_timer_event.cpp @@ -49,7 +49,7 @@ namespace ams::os { } /* Wake up whatever manager, if any. */ - GetReference(event->multi_wait_object_list_storage).SignalAllThreads(); + GetReference(event->multi_wait_object_list_storage).WakeupAllMultiWaitThreadsUnsafe(); } } @@ -110,7 +110,7 @@ namespace ams::os { GetReference(event->cv_signaled).Broadcast(); /* Wake up whatever manager, if any. */ - GetReference(event->multi_wait_object_list_storage).SignalAllThreads(); + GetReference(event->multi_wait_object_list_storage).WakeupAllMultiWaitThreadsUnsafe(); } } @@ -137,7 +137,7 @@ namespace ams::os { GetReference(event->cv_signaled).Broadcast(); /* Wake up whatever manager, if any. */ - GetReference(event->multi_wait_object_list_storage).SignalAllThreads(); + GetReference(event->multi_wait_object_list_storage).WakeupAllMultiWaitThreadsUnsafe(); } } @@ -154,7 +154,7 @@ namespace ams::os { GetReference(event->cv_signaled).Broadcast(); /* Wake up whatever manager, if any. */ - GetReference(event->multi_wait_object_list_storage).SignalAllThreads(); + GetReference(event->multi_wait_object_list_storage).WakeupAllMultiWaitThreadsUnsafe(); } } @@ -172,7 +172,7 @@ namespace ams::os { /* Update. */ auto cur_time = impl::GetCurrentTick().ToTimeSpan(); - if (impl::UpdateSignalStateAndRecalculateNextTimeToWakeupUnsafe(event, cur_time)) { + if (impl::UpdateSignalStateAndRecalcNextTimeToWakeupUnsafe(event, cur_time)) { SignalTimerEventImplUnsafe(event); break; } @@ -201,7 +201,7 @@ namespace ams::os { /* Update. */ auto cur_time = impl::GetCurrentTick().ToTimeSpan(); - if (impl::UpdateSignalStateAndRecalculateNextTimeToWakeupUnsafe(event, cur_time)) { + if (impl::UpdateSignalStateAndRecalcNextTimeToWakeupUnsafe(event, cur_time)) { SignalTimerEventImplUnsafe(event); } @@ -228,7 +228,7 @@ namespace ams::os { /* Update. */ auto cur_time = impl::GetCurrentTick().ToTimeSpan(); - impl::UpdateSignalStateAndRecalculateNextTimeToWakeupUnsafe(event, cur_time); + impl::UpdateSignalStateAndRecalcNextTimeToWakeupUnsafe(event, cur_time); /* Signal. */ SignalTimerEventImplUnsafe(event); @@ -243,7 +243,7 @@ namespace ams::os { /* Update. */ auto cur_time = impl::GetCurrentTick().ToTimeSpan(); - if (impl::UpdateSignalStateAndRecalculateNextTimeToWakeupUnsafe(event, cur_time)) { + if (impl::UpdateSignalStateAndRecalcNextTimeToWakeupUnsafe(event, cur_time)) { SignalTimerEventImplUnsafe(event); }