diff --git a/libstratosphere/include/stratosphere/sm.hpp b/libstratosphere/include/stratosphere/sm.hpp index 9e93cf0d..df44d699 100644 --- a/libstratosphere/include/stratosphere/sm.hpp +++ b/libstratosphere/include/stratosphere/sm.hpp @@ -19,7 +19,6 @@ #include #include #include -#include #include diff --git a/libstratosphere/include/stratosphere/sm/sm_api.hpp b/libstratosphere/include/stratosphere/sm/sm_api.hpp index 76dbf6e3..e14a417c 100644 --- a/libstratosphere/include/stratosphere/sm/sm_api.hpp +++ b/libstratosphere/include/stratosphere/sm/sm_api.hpp @@ -20,6 +20,10 @@ namespace ams::sm { + /* Initialization. */ + Result Initialize(); + Result Finalize(); + /* Ordinary SM API. */ Result GetService(Service *out, ServiceName name); Result RegisterService(Handle *out, ServiceName name, size_t max_sessions, bool is_light); @@ -29,17 +33,4 @@ namespace ams::sm { Result HasService(bool *out, ServiceName name); Result WaitService(ServiceName name); - /* Scoped session access. */ - namespace impl { - - void DoWithSessionImpl(void (*Invoker)(void *), void *Function); - - } - - template - NX_CONSTEXPR void DoWithSession(F f) { - auto invoker = +[](void *func) { (*(F *)func)(); }; - impl::DoWithSessionImpl(invoker, &f); - } - } diff --git a/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp b/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp deleted file mode 100644 index 952f44b2..00000000 --- a/libstratosphere/include/stratosphere/sm/sm_scoped_holder.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2018-2020 Atmosphère-NX - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include "sm_api.hpp" - -namespace ams::sm { - - /* Utility, for scoped access to libnx services. */ - template - class ScopedServiceHolder { - NON_COPYABLE(ScopedServiceHolder); - private: - Result result; - bool has_initialized; - public: - ScopedServiceHolder(bool initialize = true) : result(ResultSuccess()), has_initialized(false) { - if (initialize) { - this->Initialize(); - } - } - - ~ScopedServiceHolder() { - if (this->has_initialized) { - this->Finalize(); - } - } - - ScopedServiceHolder(ScopedServiceHolder&& rhs) { - this->result = rhs.result; - this->has_initialized = rhs.has_initialized; - rhs.result = ResultSuccess(); - rhs.has_initialized = false; - } - - ScopedServiceHolder &operator=(ScopedServiceHolder&& rhs) { - rhs.Swap(*this); - return *this; - } - - void Swap(ScopedServiceHolder &rhs) { - std::swap(this->result, rhs.result); - std::swap(this->has_initialized, rhs.has_initialized); - } - - explicit operator bool() const { - return this->has_initialized; - } - - Result Initialize() { - AMS_ABORT_UNLESS(!this->has_initialized); - - sm::DoWithSession([&]() { - if constexpr (std::is_same::value) { - Initializer(); - this->result = ResultSuccess(); - } else { - this->result = Initializer(); - } - }); - - this->has_initialized = R_SUCCEEDED(this->result); - return this->result; - } - - void Finalize() { - AMS_ABORT_UNLESS(this->has_initialized); - Finalizer(); - this->has_initialized = false; - } - - Result GetResult() const { - return this->result; - } - }; - -} diff --git a/libstratosphere/source/boot2/boot2_api.cpp b/libstratosphere/source/boot2/boot2_api.cpp index 30b93416..1605d3e9 100644 --- a/libstratosphere/source/boot2/boot2_api.cpp +++ b/libstratosphere/source/boot2/boot2_api.cpp @@ -387,8 +387,8 @@ namespace ams::boot2 { /* NOTE: Here we work around a race condition in the boot process by ensuring that settings initializes its db. */ { /* Connect to set:sys. */ - sm::ScopedServiceHolder<::setsysInitialize, ::setsysExit> setsys_holder; - AMS_ABORT_UNLESS(setsys_holder); + R_ABORT_UNLESS(::setsysInitialize()); + ON_SCOPE_EXIT { ::setsysExit(); }; /* Retrieve setting from the database. */ u8 force_maintenance = 0; @@ -424,9 +424,7 @@ namespace ams::boot2 { InitializeFsHeapForCleanup(); /* Temporarily initialize fs. */ - sm::DoWithSession([&] { - R_ABORT_UNLESS(fsInitialize()); - }); + R_ABORT_UNLESS(fsInitialize()); ON_SCOPE_EXIT { fsExit(); }; /* Wait for the sd card to be available. */ diff --git a/libstratosphere/source/crypto/crypto_csrng.os.horizon.cpp b/libstratosphere/source/crypto/crypto_csrng.os.horizon.cpp index 4ef1c0ce..93f16d05 100644 --- a/libstratosphere/source/crypto/crypto_csrng.os.horizon.cpp +++ b/libstratosphere/source/crypto/crypto_csrng.os.horizon.cpp @@ -19,29 +19,28 @@ namespace ams::crypto { namespace { - bool g_initialized; - os::Mutex g_lock(false); + constinit bool g_initialized = false; + constinit os::SdkMutex g_lock; void InitializeCsrng() { AMS_ASSERT(!g_initialized); - sm::DoWithSession([&]() { - R_ABORT_UNLESS(::csrngInitialize()); - }); + R_ABORT_UNLESS(sm::Initialize()); + R_ABORT_UNLESS(::csrngInitialize()); } } void GenerateCryptographicallyRandomBytes(void *dst, size_t dst_size) { - { + if (AMS_UNLIKELY(!g_initialized)) { std::scoped_lock lk(g_lock); - if (AMS_UNLIKELY(!g_initialized)) { + if (AMS_LIKELY(!g_initialized)) { InitializeCsrng(); g_initialized = true; } } - R_ABORT_UNLESS(csrngGetRandomBytes(dst, dst_size)); + R_ABORT_UNLESS(::csrngGetRandomBytes(dst, dst_size)); } } diff --git a/libstratosphere/source/gpio/driver/board/nintendo/nx/impl/gpio_initial_config.cpp b/libstratosphere/source/gpio/driver/board/nintendo/nx/impl/gpio_initial_config.cpp index a5a8a0e5..e6d8a92b 100644 --- a/libstratosphere/source/gpio/driver/board/nintendo/nx/impl/gpio_initial_config.cpp +++ b/libstratosphere/source/gpio/driver/board/nintendo/nx/impl/gpio_initial_config.cpp @@ -24,8 +24,8 @@ namespace ams::gpio::driver::board::nintendo::nx::impl { spl::HardwareType GetHardwareType() { /* Acquire access to spl: */ - sm::ScopedServiceHolder spl_holder; - AMS_ABORT_UNLESS(static_cast(spl_holder)); + spl::Initialize(); + ON_SCOPE_EXIT { spl::Finalize(); }; /* Get config. */ return ::ams::spl::GetHardwareType(); diff --git a/libstratosphere/source/hid/hid_api.cpp b/libstratosphere/source/hid/hid_api.cpp index ba07cde5..7196618b 100644 --- a/libstratosphere/source/hid/hid_api.cpp +++ b/libstratosphere/source/hid/hid_api.cpp @@ -40,12 +40,11 @@ namespace ams::hid { /* Helper. */ void InitializeHid() { - sm::DoWithSession([&]() { - R_ABORT_UNLESS(hidInitialize()); - hidInitializeNpad(); - R_ABORT_UNLESS(hidSetSupportedNpadIdType(NpadIdTypes, NumNpadIdTypes)); - R_ABORT_UNLESS(hidSetSupportedNpadStyleSet(HidNpadStyleSet_NpadStandard | HidNpadStyleTag_NpadSystemExt)); - }); + R_ABORT_UNLESS(sm::Initialize()); + R_ABORT_UNLESS(hidInitialize()); + hidInitializeNpad(); + R_ABORT_UNLESS(hidSetSupportedNpadIdType(NpadIdTypes, NumNpadIdTypes)); + R_ABORT_UNLESS(hidSetSupportedNpadStyleSet(HidNpadStyleSet_NpadStandard | HidNpadStyleTag_NpadSystemExt)); } Result EnsureHidInitialized() { diff --git a/libstratosphere/source/htcs/client/htcs_session.cpp b/libstratosphere/source/htcs/client/htcs_session.cpp index c41276bb..687da86d 100644 --- a/libstratosphere/source/htcs/client/htcs_session.cpp +++ b/libstratosphere/source/htcs/client/htcs_session.cpp @@ -229,10 +229,11 @@ namespace ams::htcs::client { } void InitializeSessionManager(tma::IHtcsManager **out_manager, tma::IHtcsManager **out_monitor, u32 num_sessions) { + /* Ensure we can contact the libnx wrapper. */ + R_ABORT_UNLESS(sm::Initialize()); + /* Initialize the libnx wrapper. */ - sm::DoWithSession([&] { - R_ABORT_UNLESS(::htcsInitialize(num_sessions)); - }); + R_ABORT_UNLESS(::htcsInitialize(num_sessions)); /* Create the output objects. */ *out_manager = ObjectFactory::CreateSharedEmplaced().Detach(); diff --git a/libstratosphere/source/sm/sm_api.cpp b/libstratosphere/source/sm/sm_api.cpp index ef7be4e5..104abb80 100644 --- a/libstratosphere/source/sm/sm_api.cpp +++ b/libstratosphere/source/sm/sm_api.cpp @@ -18,47 +18,52 @@ namespace ams::sm { + namespace { + + constinit int g_ref_count = 0; + constinit os::SdkMutex g_mutex; + + } + + /* Initialization. */ + Result Initialize() { + std::scoped_lock lk(g_mutex); + + if (g_ref_count > 0) { + ++g_ref_count; + } else { + R_TRY(::smInitialize()); + g_ref_count = 1; + } + + return ResultSuccess(); + } + + Result Finalize() { + /* NOTE: Nintendo does nothing here. */ + return ResultSuccess(); + } + /* Ordinary SM API. */ Result GetService(Service *out, ServiceName name) { - return impl::DoWithUserSession([&]() { - return smGetServiceWrapper(out, impl::ConvertName(name)); - }); + return smGetServiceWrapper(out, impl::ConvertName(name)); } Result RegisterService(Handle *out, ServiceName name, size_t max_sessions, bool is_light) { - return impl::DoWithUserSession([&]() { - return smRegisterService(out, impl::ConvertName(name), is_light, static_cast(max_sessions)); - }); + return smRegisterService(out, impl::ConvertName(name), is_light, static_cast(max_sessions)); } Result UnregisterService(ServiceName name) { - return impl::DoWithUserSession([&]() { - return smUnregisterService(impl::ConvertName(name)); - }); + return smUnregisterService(impl::ConvertName(name)); } /* Atmosphere extensions. */ Result HasService(bool *out, ServiceName name) { - return impl::DoWithUserSession([&]() { - return smAtmosphereHasService(out, impl::ConvertName(name)); - }); + return smAtmosphereHasService(out, impl::ConvertName(name)); } Result WaitService(ServiceName name) { - return impl::DoWithUserSession([&]() { - return smAtmosphereWaitService(impl::ConvertName(name)); - }); - } - - namespace impl { - - void DoWithSessionImpl(void (*Invoker)(void *), void *Function) { - impl::DoWithUserSession([&]() { - Invoker(Function); - return ResultSuccess(); - }); - } - + return smAtmosphereWaitService(impl::ConvertName(name)); } } diff --git a/libstratosphere/source/sm/sm_mitm_api.cpp b/libstratosphere/source/sm/sm_mitm_api.cpp index cdf07e7a..ca3edef7 100644 --- a/libstratosphere/source/sm/sm_mitm_api.cpp +++ b/libstratosphere/source/sm/sm_mitm_api.cpp @@ -26,21 +26,15 @@ namespace ams::sm::mitm { } Result UninstallMitm(ServiceName name) { - return impl::DoWithUserSession([&]() { - return smAtmosphereMitmUninstall(impl::ConvertName(name)); - }); + return smAtmosphereMitmUninstall(impl::ConvertName(name)); } Result DeclareFutureMitm(ServiceName name) { - return impl::DoWithUserSession([&]() { - return smAtmosphereMitmDeclareFuture(impl::ConvertName(name)); - }); + return smAtmosphereMitmDeclareFuture(impl::ConvertName(name)); } Result ClearFutureMitm(ServiceName name) { - return impl::DoWithUserSession([&]() { - return smAtmosphereMitmClearFuture(impl::ConvertName(name)); - }); + return smAtmosphereMitmClearFuture(impl::ConvertName(name)); } Result AcknowledgeSession(Service *out_service, MitmProcessInfo *out_info, ServiceName name) { @@ -50,15 +44,11 @@ namespace ams::sm::mitm { } Result HasMitm(bool *out, ServiceName name) { - return impl::DoWithUserSession([&]() { - return smAtmosphereHasMitm(out, impl::ConvertName(name)); - }); + return smAtmosphereHasMitm(out, impl::ConvertName(name)); } Result WaitMitm(ServiceName name) { - return impl::DoWithUserSession([&]() { - return smAtmosphereWaitMitm(impl::ConvertName(name)); - }); + return smAtmosphereWaitMitm(impl::ConvertName(name)); } } diff --git a/libstratosphere/source/sm/sm_utils.cpp b/libstratosphere/source/sm/sm_utils.cpp index 2cfefc23..f241e79e 100644 --- a/libstratosphere/source/sm/sm_utils.cpp +++ b/libstratosphere/source/sm/sm_utils.cpp @@ -21,17 +21,12 @@ namespace ams::sm::impl { namespace { /* Globals. */ - os::Mutex g_user_session_mutex(true); - os::Mutex g_mitm_ack_session_mutex(true); - os::Mutex g_per_thread_session_mutex(true); + constinit os::Mutex g_mitm_ack_session_mutex(true); + constinit os::Mutex g_per_thread_session_mutex(true); } /* Utilities. */ - os::Mutex &GetUserSessionMutex() { - return g_user_session_mutex; - } - os::Mutex &GetMitmAcknowledgementSessionMutex() { return g_mitm_ack_session_mutex; } diff --git a/libstratosphere/source/sm/sm_utils.hpp b/libstratosphere/source/sm/sm_utils.hpp index d869f9cd..f8926c61 100644 --- a/libstratosphere/source/sm/sm_utils.hpp +++ b/libstratosphere/source/sm/sm_utils.hpp @@ -21,24 +21,9 @@ namespace ams::sm::impl { /* Utilities. */ - os::Mutex &GetUserSessionMutex(); os::Mutex &GetMitmAcknowledgementSessionMutex(); os::Mutex &GetPerThreadSessionMutex(); - template - Result DoWithUserSession(F f) { - std::scoped_lock lk(GetUserSessionMutex()); - { - R_ABORT_UNLESS(smInitialize()); - ON_SCOPE_EXIT { - R_ABORT_UNLESS(smDetachClient()); - smExit(); - }; - - return f(); - } - } - template Result DoWithMitmAcknowledgementSession(F f) { std::scoped_lock lk(GetMitmAcknowledgementSessionMutex()); diff --git a/libstratosphere/source/socket/impl/socket_api.os.horizon.cpp b/libstratosphere/source/socket/impl/socket_api.os.horizon.cpp index 9efa5e3e..7b57a090 100644 --- a/libstratosphere/source/socket/impl/socket_api.os.horizon.cpp +++ b/libstratosphere/source/socket/impl/socket_api.os.horizon.cpp @@ -197,9 +197,8 @@ namespace ams::socket::impl { const auto service_type = config.IsSystemClient() ? (1 << 1) : (1 << 0); - sm::DoWithSession([&] { - R_ABORT_UNLESS(::bsdInitialize(std::addressof(libnx_config), static_cast(config.GetConcurrencyCountMax()), service_type)); - }); + R_ABORT_UNLESS(sm::Initialize()); + R_ABORT_UNLESS(::bsdInitialize(std::addressof(libnx_config), static_cast(config.GetConcurrencyCountMax()), service_type)); } /* Set the heap generation. */ diff --git a/libstratosphere/source/updater/updater_api.cpp b/libstratosphere/source/updater/updater_api.cpp index 00071b8e..cec4f92e 100644 --- a/libstratosphere/source/updater/updater_api.cpp +++ b/libstratosphere/source/updater/updater_api.cpp @@ -549,8 +549,8 @@ namespace ams::updater { } /* Get a session to ncm. */ - sm::ScopedServiceHolder ncm_holder; - R_ABORT_UNLESS(ncm_holder.GetResult()); + ncm::Initialize(); + ON_SCOPE_EXIT { ncm::Finalize(); }; /* Verify normal, verify safe as needed. */ if (verification_state.needs_verify_normal) { diff --git a/libvapours/source/sdmmc/impl/sdmmc_device_detector.cpp b/libvapours/source/sdmmc/impl/sdmmc_device_detector.cpp index 3529b85a..4deae159 100644 --- a/libvapours/source/sdmmc/impl/sdmmc_device_detector.cpp +++ b/libvapours/source/sdmmc/impl/sdmmc_device_detector.cpp @@ -58,7 +58,9 @@ namespace ams::sdmmc::impl { void DeviceDetector::DetectorThread() { /* Initialize the gpio session. */ - sm::DoWithSession([] { gpio::Initialize(); }); + gpio::Initialize(); + + /* Open and configure the pad session. */ gpio::OpenSession(std::addressof(this->gpio_pad_session), this->gpio_device_code); gpio::SetDirection(std::addressof(this->gpio_pad_session), gpio::Direction_Input); gpio::SetDebounceTime(std::addressof(this->gpio_pad_session), this->gpio_debounce_ms);