diff --git a/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.cpp b/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.cpp index 3390170db..73ec1b35d 100644 --- a/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.cpp +++ b/libraries/libstratosphere/source/gpio/driver/impl/gpio_driver_core.cpp @@ -26,18 +26,42 @@ namespace ams::gpio::driver::impl { alignas(os::MemoryPageSize) u8 g_interrupt_thread_stack[InterruptThreadStackSize]; gpio::driver::IGpioDriver::List &GetGpioDriverList() { - static gpio::driver::IGpioDriver::List s_gpio_driver_list; + static constinit gpio::driver::IGpioDriver::List s_gpio_driver_list; return s_gpio_driver_list; } ddsf::EventHandlerManager &GetInterruptHandlerManager() { - static ddsf::EventHandlerManager s_interrupt_handler_manager; - return s_interrupt_handler_manager; + static constinit util::TypedStorage s_interrupt_handler_manager; + static constinit bool s_initialized = false; + static constinit os::SdkMutex s_mutex; + + if (AMS_UNLIKELY(!s_initialized)) { + std::scoped_lock lk(s_mutex); + + if (AMS_LIKELY(!s_initialized)) { + util::ConstructAt(s_interrupt_handler_manager); + s_initialized = true; + } + } + + return util::GetReference(s_interrupt_handler_manager); } ddsf::DeviceCodeEntryManager &GetDeviceCodeEntryManager() { - static ddsf::DeviceCodeEntryManager s_device_code_entry_manager(ddsf::GetDeviceCodeEntryHolderMemoryResource()); - return s_device_code_entry_manager; + static constinit util::TypedStorage s_device_code_entry_manager; + static constinit bool s_initialized = false; + static constinit os::SdkMutex s_mutex; + + if (AMS_UNLIKELY(!s_initialized)) { + std::scoped_lock lk(s_mutex); + + if (AMS_LIKELY(!s_initialized)) { + util::ConstructAt(s_device_code_entry_manager, ddsf::GetDeviceCodeEntryHolderMemoryResource()); + s_initialized = true; + } + } + + return util::GetReference(s_device_code_entry_manager); } void InterruptThreadFunction(void *arg) { diff --git a/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/i2c_driver_api.cpp b/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/i2c_driver_api.cpp index ed42c141a..fee708243 100644 --- a/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/i2c_driver_api.cpp +++ b/libraries/libstratosphere/source/i2c/driver/board/nintendo/nx/i2c_driver_api.cpp @@ -98,11 +98,13 @@ namespace ams::i2c::driver::board::nintendo::nx { } void Initialize() { - /* TODO: Should these be moved into getters? They're only used here, and they never destruct. */ - static impl::I2cBusAccessorManager s_bus_accessor_manager(ddsf::GetMemoryResource()); - static impl::I2cDevicePropertyManager s_device_manager(ddsf::GetMemoryResource()); + static constinit util::TypedStorage s_bus_accessor_manager; + static constinit util::TypedStorage s_device_manager; - return Initialize(s_bus_accessor_manager, s_device_manager); + util::ConstructAt(s_bus_accessor_manager, ddsf::GetMemoryResource()); + util::ConstructAt(s_device_manager, ddsf::GetMemoryResource()); + + return Initialize(util::GetReference(s_bus_accessor_manager), util::GetReference(s_device_manager)); } } diff --git a/libraries/libstratosphere/source/i2c/driver/impl/i2c_driver_core.cpp b/libraries/libstratosphere/source/i2c/driver/impl/i2c_driver_core.cpp index 9efeb6cbf..97893f202 100644 --- a/libraries/libstratosphere/source/i2c/driver/impl/i2c_driver_core.cpp +++ b/libraries/libstratosphere/source/i2c/driver/impl/i2c_driver_core.cpp @@ -24,13 +24,25 @@ namespace ams::i2c::driver::impl { constinit int g_init_count = 0; i2c::driver::II2cDriver::List &GetI2cDriverList() { - static i2c::driver::II2cDriver::List s_driver_list; + static constinit i2c::driver::II2cDriver::List s_driver_list; return s_driver_list; } ddsf::DeviceCodeEntryManager &GetDeviceCodeEntryManager() { - static ddsf::DeviceCodeEntryManager s_device_code_entry_manager(ddsf::GetDeviceCodeEntryHolderMemoryResource()); - return s_device_code_entry_manager; + static constinit util::TypedStorage s_device_code_entry_manager; + static constinit bool s_initialized = false; + static constinit os::SdkMutex s_mutex; + + if (AMS_UNLIKELY(!s_initialized)) { + std::scoped_lock lk(s_mutex); + + if (AMS_LIKELY(!s_initialized)) { + util::ConstructAt(s_device_code_entry_manager, ddsf::GetDeviceCodeEntryHolderMemoryResource()); + s_initialized = true; + } + } + + return util::GetReference(s_device_code_entry_manager); } } diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_battery_driver.cpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_battery_driver.cpp index 609076a2d..875af198f 100644 --- a/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_battery_driver.cpp +++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_battery_driver.cpp @@ -25,9 +25,20 @@ namespace ams::powctl::impl::board::nintendo::nx { constinit util::optional g_battery_device; + constinit util::TypedStorage g_max17050_driver; + constinit bool g_constructed_max17050_driver; + constinit os::SdkMutex g_max17050_driver_mutex; + Max17050Driver &GetMax17050Driver() { - static Max17050Driver s_max17050_driver; - return s_max17050_driver; + if (AMS_UNLIKELY(!g_constructed_max17050_driver)) { + std::scoped_lock lk(g_max17050_driver_mutex); + + if (AMS_LIKELY(!g_constructed_max17050_driver)) { + util::ConstructAt(g_max17050_driver); + } + } + + return util::GetReference(g_max17050_driver); } constexpr inline const double SenseResistorValue = 0.005; diff --git a/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_charger_driver.cpp b/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_charger_driver.cpp index 417c3ae58..ca8461447 100644 --- a/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_charger_driver.cpp +++ b/libraries/libstratosphere/source/powctl/impl/board/nintendo/nx/powctl_charger_driver.cpp @@ -25,9 +25,20 @@ namespace ams::powctl::impl::board::nintendo::nx { constinit util::optional g_charger_device; + constinit util::TypedStorage g_bq24193_driver; + constinit bool g_constructed_bq24193_driver; + constinit os::SdkMutex g_bq24193_driver_mutex; + Bq24193Driver &GetBq24193Driver() { - static Bq24193Driver s_bq24193_driver; - return s_bq24193_driver; + if (AMS_UNLIKELY(!g_constructed_bq24193_driver)) { + std::scoped_lock lk(g_bq24193_driver_mutex); + + if (AMS_LIKELY(!g_constructed_bq24193_driver)) { + util::ConstructAt(g_bq24193_driver); + } + } + + return util::GetReference(g_bq24193_driver); } } diff --git a/libraries/libstratosphere/source/powctl/impl/powctl_device_management.cpp b/libraries/libstratosphere/source/powctl/impl/powctl_device_management.cpp index ccb3698ee..e3364b68f 100644 --- a/libraries/libstratosphere/source/powctl/impl/powctl_device_management.cpp +++ b/libraries/libstratosphere/source/powctl/impl/powctl_device_management.cpp @@ -30,28 +30,50 @@ namespace ams::powctl::impl { constinit sf::UnitHeapMemoryResource g_unit_heap_memory_resource; IPowerControlDriver::List &GetDriverList() { - static IPowerControlDriver::List s_driver_list; + static constinit IPowerControlDriver::List s_driver_list; return s_driver_list; } ddsf::EventHandlerManager &GetInterruptHandlerManager() { - static ddsf::EventHandlerManager s_interrupt_handler_manager; - return s_interrupt_handler_manager; + static constinit util::TypedStorage s_interrupt_handler_manager; + static constinit bool s_initialized = false; + static constinit os::SdkMutex s_mutex; + + if (AMS_UNLIKELY(!s_initialized)) { + std::scoped_lock lk(s_mutex); + + if (AMS_LIKELY(!s_initialized)) { + util::ConstructAt(s_interrupt_handler_manager); + s_initialized = true; + } + } + + return util::GetReference(s_interrupt_handler_manager); } ddsf::DeviceCodeEntryManager &GetDeviceCodeEntryManager() { - static ddsf::DeviceCodeEntryManager s_device_code_entry_manager = [] { - /* Initialize the entry code heap. */ - g_unit_heap_handle = lmem::CreateUnitHeap(g_unit_heap_memory, sizeof(g_unit_heap_memory), sizeof(ddsf::DeviceCodeEntryHolder), lmem::CreateOption_ThreadSafe); + static constinit util::TypedStorage s_device_code_entry_manager; + static constinit bool s_initialized = false; + static constinit os::SdkMutex s_mutex; - /* Initialize the entry code memory resource. */ - g_unit_heap_memory_resource.Attach(g_unit_heap_handle); + if (AMS_UNLIKELY(!s_initialized)) { + std::scoped_lock lk(s_mutex); - /* Make the entry manager using the newly initialized memory resource. */ - return ddsf::DeviceCodeEntryManager(std::addressof(g_unit_heap_memory_resource)); - }(); + if (AMS_LIKELY(!s_initialized)) { + /* Initialize the entry code heap. */ + g_unit_heap_handle = lmem::CreateUnitHeap(g_unit_heap_memory, sizeof(g_unit_heap_memory), sizeof(ddsf::DeviceCodeEntryHolder), lmem::CreateOption_ThreadSafe); - return s_device_code_entry_manager; + /* Initialize the entry code memory resource. */ + g_unit_heap_memory_resource.Attach(g_unit_heap_handle); + + /* Make the entry manager using the newly initialized memory resource. */ + util::ConstructAt(s_device_code_entry_manager, std::addressof(g_unit_heap_memory_resource)); + + s_initialized = true; + } + } + + return util::GetReference(s_device_code_entry_manager); } void InterruptThreadFunction(void *arg) { diff --git a/libraries/libstratosphere/source/pwm/driver/impl/pwm_driver_core.cpp b/libraries/libstratosphere/source/pwm/driver/impl/pwm_driver_core.cpp index b6ceae71a..224991684 100644 --- a/libraries/libstratosphere/source/pwm/driver/impl/pwm_driver_core.cpp +++ b/libraries/libstratosphere/source/pwm/driver/impl/pwm_driver_core.cpp @@ -24,13 +24,25 @@ namespace ams::pwm::driver::impl { constinit int g_init_count = 0; pwm::driver::IPwmDriver::List &GetPwmDriverList() { - static pwm::driver::IPwmDriver::List s_driver_list; + static constinit pwm::driver::IPwmDriver::List s_driver_list; return s_driver_list; } ddsf::DeviceCodeEntryManager &GetDeviceCodeEntryManager() { - static ddsf::DeviceCodeEntryManager s_device_code_entry_manager(ddsf::GetDeviceCodeEntryHolderMemoryResource()); - return s_device_code_entry_manager; + static constinit util::TypedStorage s_device_code_entry_manager; + static constinit bool s_initialized = false; + static constinit os::SdkMutex s_mutex; + + if (AMS_UNLIKELY(!s_initialized)) { + std::scoped_lock lk(s_mutex); + + if (AMS_LIKELY(!s_initialized)) { + util::ConstructAt(s_device_code_entry_manager, ddsf::GetDeviceCodeEntryHolderMemoryResource()); + s_initialized = true; + } + } + + return util::GetReference(s_device_code_entry_manager); } }