From ced1312dc7626c836216abab43bc53101673d50c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 31 Dec 2020 00:29:06 -0800 Subject: [PATCH] sm: implement accurate request deferral semantics --- .../sf/hipc/sf_hipc_server_manager.hpp | 8 +-- .../hipc/sf_hipc_server_session_manager.hpp | 1 - .../source/sf/hipc/sf_hipc_server_manager.cpp | 50 +------------------ 3 files changed, 2 insertions(+), 57 deletions(-) diff --git a/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp b/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp index bb002012..3104b512 100644 --- a/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp +++ b/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp @@ -128,10 +128,6 @@ namespace ams::sf::hipc { os::Mutex waitlist_mutex; os::WaitableManagerType waitlist; - - os::Mutex deferred_session_mutex; - using DeferredSessionList = typename util::IntrusiveListMemberTraits<&ServerSession::deferred_list_node>::ListType; - DeferredSessionList deferred_session_list; private: virtual void RegisterSessionToWaitList(ServerSession *session) override final; void RegisterToWaitList(os::WaitableHolderType *holder); @@ -143,8 +139,6 @@ namespace ams::sf::hipc { Result ProcessForMitmServer(os::WaitableHolderType *holder); Result ProcessForSession(os::WaitableHolderType *holder); - void ProcessDeferredSessions(); - template void RegisterServerImpl(Handle port_handle, sm::ServiceName service_name, bool managed, cmif::ServiceObjectHolder &&static_holder) { /* Allocate server memory. */ @@ -176,7 +170,7 @@ namespace ams::sf::hipc { ServerManagerBase(DomainEntryStorage *entry_storage, size_t entry_count) : ServerDomainSessionManager(entry_storage, entry_count), request_stop_event(os::EventClearMode_ManualClear), notify_event(os::EventClearMode_ManualClear), - waitable_selection_mutex(false), waitlist_mutex(false), deferred_session_mutex(false) + waitable_selection_mutex(false), waitlist_mutex(false) { /* Link waitables. */ os::InitializeWaitableManager(std::addressof(this->waitable_manager)); diff --git a/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp b/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp index 117af73c..f2388181 100644 --- a/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp +++ b/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp @@ -45,7 +45,6 @@ namespace ams::sf::hipc { NON_COPYABLE(ServerSession); NON_MOVEABLE(ServerSession); private: - util::IntrusiveListNode deferred_list_node; cmif::ServiceObjectHolder srv_obj_holder; cmif::PointerAndSize pointer_buffer; cmif::PointerAndSize saved_message; diff --git a/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp b/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp index 37b78626..3fe56d97 100644 --- a/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp +++ b/libstratosphere/source/sf/hipc/sf_hipc_server_manager.cpp @@ -147,62 +147,14 @@ namespace ams::sf::hipc { return ResultSuccess(); } - void ServerManagerBase::ProcessDeferredSessions() { - /* Iterate over the list of deferred sessions, and see if we can't do anything. */ - std::scoped_lock lk(this->deferred_session_mutex); - - /* Undeferring a request may undefer another request. We'll continue looping until everything is stable. */ - bool needs_undefer_all = true; - while (needs_undefer_all) { - needs_undefer_all = false; - - auto it = this->deferred_session_list.begin(); - while (it != this->deferred_session_list.end()) { - ServerSession *session = static_cast(&*it); - R_TRY_CATCH(this->ProcessForSession(session)) { - R_CATCH(sf::ResultRequestDeferred) { - /* Session is still deferred, so let's continue. */ - it++; - continue; - } - R_CATCH(sf::impl::ResultRequestInvalidated) { - /* Session is no longer deferred! */ - it = this->deferred_session_list.erase(it); - needs_undefer_all = true; - continue; - } - } R_END_TRY_CATCH_WITH_ABORT_UNLESS; - - /* We succeeded! Remove from deferred list. */ - it = this->deferred_session_list.erase(it); - needs_undefer_all = true; - } - } - } - Result ServerManagerBase::Process(os::WaitableHolderType *holder) { switch (static_cast(os::GetWaitableHolderUserData(holder))) { case UserDataTag::Server: return this->ProcessForServer(holder); - break; case UserDataTag::MitmServer: return this->ProcessForMitmServer(holder); - break; case UserDataTag::Session: - /* Try to process for session. */ - R_TRY_CATCH(this->ProcessForSession(holder)) { - R_CATCH(sf::ResultRequestDeferred) { - /* The session was deferred, so push it onto the deferred session list. */ - std::scoped_lock lk(this->deferred_session_mutex); - this->deferred_session_list.push_back(*static_cast(holder)); - return ResultSuccess(); - } - } R_END_TRY_CATCH; - - /* We successfully invoked a command...so let's see if anything can be undeferred. */ - this->ProcessDeferredSessions(); - return ResultSuccess(); - break; + return this->ProcessForSession(holder); AMS_UNREACHABLE_DEFAULT_CASE(); } }