diff --git a/stratosphere/ams_mitm/source/amsmitm_main.cpp b/stratosphere/ams_mitm/source/amsmitm_main.cpp index 5d12ef9d5..b5afc65d5 100644 --- a/stratosphere/ams_mitm/source/amsmitm_main.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_main.cpp @@ -93,7 +93,7 @@ void __appExit(void) { int main(int argc, char **argv) { consoleDebugInit(debugDevice_SVC); - HosThread initializer_thread; + sts::os::Thread initializer_thread; LaunchAllMitmModules(); diff --git a/stratosphere/ams_mitm/source/amsmitm_modules.cpp b/stratosphere/ams_mitm/source/amsmitm_modules.cpp index 03c357b9c..3556729cb 100644 --- a/stratosphere/ams_mitm/source/amsmitm_modules.cpp +++ b/stratosphere/ams_mitm/source/amsmitm_modules.cpp @@ -27,7 +27,7 @@ #include "ns_mitm/nsmitm_main.hpp" #include "hid_mitm/hidmitm_main.hpp" -static HosThread g_module_threads[MitmModuleId_Count]; +static sts::os::Thread g_module_threads[MitmModuleId_Count]; static const struct { ThreadFunc main; diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp index eac720069..bc50a0892 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.cpp @@ -145,7 +145,7 @@ Result DirectorySaveDataFileSystem::GetFullPath(char *out, size_t out_size, cons } void DirectorySaveDataFileSystem::OnWritableFileClose() { - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); this->open_writable_files--; /* TODO: Abort if < 0? N does not. */ @@ -171,7 +171,7 @@ Result DirectorySaveDataFileSystem::CreateFileImpl(const FsPath &path, uint64_t FsPath full_path; R_TRY(GetFullPath(full_path, path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->CreateFile(full_path, size, flags); } @@ -179,7 +179,7 @@ Result DirectorySaveDataFileSystem::DeleteFileImpl(const FsPath &path) { FsPath full_path; R_TRY(GetFullPath(full_path, path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->DeleteFile(full_path); } @@ -187,7 +187,7 @@ Result DirectorySaveDataFileSystem::CreateDirectoryImpl(const FsPath &path) { FsPath full_path; R_TRY(GetFullPath(full_path, path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->CreateDirectory(full_path); } @@ -195,7 +195,7 @@ Result DirectorySaveDataFileSystem::DeleteDirectoryImpl(const FsPath &path) { FsPath full_path; R_TRY(GetFullPath(full_path, path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->DeleteDirectory(full_path); } @@ -203,7 +203,7 @@ Result DirectorySaveDataFileSystem::DeleteDirectoryRecursivelyImpl(const FsPath FsPath full_path; R_TRY(GetFullPath(full_path, path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->DeleteDirectoryRecursively(full_path); } @@ -212,7 +212,7 @@ Result DirectorySaveDataFileSystem::RenameFileImpl(const FsPath &old_path, const R_TRY(GetFullPath(full_old_path, old_path)); R_TRY(GetFullPath(full_new_path, new_path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->RenameFile(full_old_path, full_new_path); } @@ -221,7 +221,7 @@ Result DirectorySaveDataFileSystem::RenameDirectoryImpl(const FsPath &old_path, R_TRY(GetFullPath(full_old_path, old_path)); R_TRY(GetFullPath(full_new_path, new_path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->RenameDirectory(full_old_path, full_new_path); } @@ -229,7 +229,7 @@ Result DirectorySaveDataFileSystem::GetEntryTypeImpl(DirectoryEntryType *out, co FsPath full_path; R_TRY(GetFullPath(full_path, path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->GetEntryType(out, full_path); } @@ -237,7 +237,7 @@ Result DirectorySaveDataFileSystem::OpenFileImpl(std::unique_ptr &out_fil FsPath full_path; R_TRY(GetFullPath(full_path, path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); { /* Open the raw file. */ @@ -265,7 +265,7 @@ Result DirectorySaveDataFileSystem::OpenDirectoryImpl(std::unique_ptr lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->OpenDirectory(out_dir, full_path, mode); } @@ -278,7 +278,7 @@ Result DirectorySaveDataFileSystem::CommitImpl() { /* will be deleted if there is an error during synchronization. */ /* Instead, we will synchronize first, then delete committed, then rename. */ - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); /* Ensure we don't have any open writable files. */ if (this->open_writable_files != 0) { @@ -320,7 +320,7 @@ Result DirectorySaveDataFileSystem::CleanDirectoryRecursivelyImpl(const FsPath & FsPath full_path; R_TRY(GetFullPath(full_path, path)); - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); return this->fs->CleanDirectoryRecursively(full_path); } diff --git a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.hpp b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.hpp index 104ba12e7..3fa5c61b8 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.hpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fs_directory_savedata_filesystem.hpp @@ -37,7 +37,7 @@ class DirectorySaveDataFileSystem : public IFileSystem { std::unique_ptr unique_fs; std::unique_ptr proxy_save_fs; IFileSystem *fs; - HosMutex lock; + sts::os::Mutex lock; size_t open_writable_files = 0; public: diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.cpp index d3597ee94..dae04da02 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_boot0storage.cpp @@ -20,7 +20,7 @@ #include "fsmitm_boot0storage.hpp" -static HosMutex g_boot0_mutex; +static sts::os::Mutex g_boot0_mutex; static u8 g_boot0_bct_buffer[Boot0Storage::BctEndOffset]; bool Boot0Storage::CanModifyBctPubks() { @@ -37,13 +37,13 @@ bool Boot0Storage::CanModifyBctPubks() { } Result Boot0Storage::Read(void *_buffer, size_t size, u64 offset) { - std::scoped_lock lk{g_boot0_mutex}; + std::scoped_lock lk{g_boot0_mutex}; return Base::Read(_buffer, size, offset); } Result Boot0Storage::Write(void *_buffer, size_t size, u64 offset) { - std::scoped_lock lk{g_boot0_mutex}; + std::scoped_lock lk{g_boot0_mutex}; u8 *buffer = static_cast(_buffer); diff --git a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp index bd9898108..ea49b659b 100644 --- a/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp +++ b/stratosphere/ams_mitm/source/fs_mitm/fsmitm_service.cpp @@ -36,11 +36,11 @@ #include "../debug.hpp" -static HosMutex g_StorageCacheLock; +static sts::os::Mutex g_StorageCacheLock; static std::unordered_map> g_StorageCache; static bool StorageCacheGetEntry(sts::ncm::TitleId title_id, std::shared_ptr *out) { - std::scoped_lock lock(g_StorageCacheLock); + std::scoped_lock lock(g_StorageCacheLock); if (g_StorageCache.find(static_cast(title_id)) == g_StorageCache.end()) { return false; } @@ -54,7 +54,7 @@ static bool StorageCacheGetEntry(sts::ncm::TitleId title_id, std::shared_ptr *ptr) { - std::scoped_lock lock(g_StorageCacheLock); + std::scoped_lock lock(g_StorageCacheLock); /* Ensure we always use the cached copy if present. */ if (g_StorageCache.find(static_cast(title_id)) != g_StorageCache.end()) { diff --git a/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp b/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp index 2e1b95ce9..697a9d3ff 100644 --- a/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.cpp @@ -64,7 +64,7 @@ bool SetMitmService::IsValidRegionCode(u32 region_code) { } Result SetMitmService::EnsureLocale() { - std::scoped_lock lk(this->lock); + std::scoped_lock lk(this->lock); if (!this->got_locale) { std::memset(&this->locale, 0xCC, sizeof(this->locale)); diff --git a/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.hpp b/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.hpp index 1e114ef56..6f4b2a0e9 100644 --- a/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.hpp +++ b/stratosphere/ams_mitm/source/set_mitm/set_mitm_service.hpp @@ -31,7 +31,7 @@ class SetMitmService : public IMitmServiceObject { GetAvailableLanguageCodes = 1, }; private: - HosMutex lock; + sts::os::Mutex lock; OverrideLocale locale; bool got_locale; public: diff --git a/stratosphere/ams_mitm/source/set_mitm/setsys_firmware_version.cpp b/stratosphere/ams_mitm/source/set_mitm/setsys_firmware_version.cpp index 1f5e55ca2..88153fd52 100644 --- a/stratosphere/ams_mitm/source/set_mitm/setsys_firmware_version.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/setsys_firmware_version.cpp @@ -19,13 +19,13 @@ #include "setsys_firmware_version.hpp" -static HosMutex g_version_mutex; +static sts::os::Mutex g_version_mutex; static bool g_got_version = false; static SetSysFirmwareVersion g_ams_fw_version = {0}; static SetSysFirmwareVersion g_fw_version = {0}; void VersionManager::Initialize() { - std::scoped_lock lock(g_version_mutex); + std::scoped_lock lock(g_version_mutex); if (g_got_version) { return; diff --git a/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp b/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp index 4f2cff9f6..273c74604 100644 --- a/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp +++ b/stratosphere/ams_mitm/source/set_mitm/setsys_settings_items.cpp @@ -35,7 +35,7 @@ struct SettingsItemValue { std::map g_settings_items; static bool g_threw_fatal = false; -static HosThread g_fatal_thread; +static sts::os::Thread g_fatal_thread; static void FatalThreadFunc(void *arg) { svcSleepThread(5000000000ULL); diff --git a/stratosphere/ams_mitm/source/utils.cpp b/stratosphere/ams_mitm/source/utils.cpp index 6923673c9..0f53fe6b0 100644 --- a/stratosphere/ams_mitm/source/utils.cpp +++ b/stratosphere/ams_mitm/source/utils.cpp @@ -29,7 +29,9 @@ #include "bpc_mitm/bpcmitm_reboot_manager.hpp" static FsFileSystem g_sd_filesystem = {0}; -static HosSignal g_sd_signal, g_hid_signal; + +/* Non-autoclear events for SD/HID init. */ +static sts::os::Event g_sd_event(false), g_hid_event(false); static std::vector g_mitm_flagged_tids; static std::vector g_disable_mitm_flagged_tids; @@ -286,7 +288,7 @@ void Utils::InitializeThreadFunc(void *args) { SettingsItemManager::LoadConfiguration(); /* Signal to waiters that we are ready. */ - g_sd_signal.Signal(); + g_sd_event.Signal(); /* Initialize HID. */ while (!g_has_hid_session) { @@ -301,7 +303,7 @@ void Utils::InitializeThreadFunc(void *args) { } /* Signal to waiters that we are ready. */ - g_hid_signal.Signal(); + g_hid_event.Signal(); } bool Utils::IsSdInitialized() { @@ -309,7 +311,7 @@ bool Utils::IsSdInitialized() { } void Utils::WaitSdInitialized() { - g_sd_signal.Wait(); + g_sd_event.Wait(); } bool Utils::IsHidAvailable() { @@ -317,7 +319,7 @@ bool Utils::IsHidAvailable() { } void Utils::WaitHidAvailable() { - g_hid_signal.Wait(); + g_hid_event.Wait(); } Result Utils::OpenSdFile(const char *fn, int flags, FsFile *out) { diff --git a/stratosphere/boot/source/boot_display.cpp b/stratosphere/boot/source/boot_display.cpp index 86e74ab7a..d158bc5b5 100644 --- a/stratosphere/boot/source/boot_display.cpp +++ b/stratosphere/boot/source/boot_display.cpp @@ -168,7 +168,7 @@ namespace sts::boot { } void WaitDsiTrigger() { - TimeoutHelper timeout_helper(250'000'000ul); + os::TimeoutHelper timeout_helper(250'000'000ul); while (true) { if (timeout_helper.TimedOut()) { @@ -183,7 +183,7 @@ namespace sts::boot { } void WaitDsiHostControl() { - TimeoutHelper timeout_helper(150'000'000ul); + os::TimeoutHelper timeout_helper(150'000'000ul); while (true) { if (timeout_helper.TimedOut()) { diff --git a/stratosphere/boot/source/i2c/driver/i2c_api.cpp b/stratosphere/boot/source/i2c/driver/i2c_api.cpp index 84e49e9d5..37f866226 100644 --- a/stratosphere/boot/source/i2c/driver/i2c_api.cpp +++ b/stratosphere/boot/source/i2c/driver/i2c_api.cpp @@ -132,7 +132,7 @@ namespace sts::i2c::driver { std::abort(); } - std::scoped_lock lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx))); + std::scoped_lock lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx))); return GetResourceManager().GetSession(session.session_id).DoTransactionWithRetry(nullptr, src, size, option, impl::Command::Send); } @@ -142,7 +142,7 @@ namespace sts::i2c::driver { std::abort(); } - std::scoped_lock lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx))); + std::scoped_lock lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx))); return GetResourceManager().GetSession(session.session_id).DoTransactionWithRetry(dst, nullptr, size, option, impl::Command::Receive); } diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp b/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp index 9f1ad98ed..f248127f3 100644 --- a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp +++ b/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.cpp @@ -23,7 +23,7 @@ namespace sts::i2c::driver::impl { void BusAccessor::Open(Bus bus, SpeedMode speed_mode) { - std::scoped_lock lk(this->open_mutex); + std::scoped_lock lk(this->open_mutex); /* Open new session. */ this->open_sessions++; @@ -37,7 +37,7 @@ namespace sts::i2c::driver::impl { /* Set all members for chosen bus. */ { - std::scoped_lock lk(this->register_mutex); + std::scoped_lock lk(this->register_mutex); /* Set bus/registers. */ this->SetBus(bus); /* Set pcv module. */ @@ -50,7 +50,7 @@ namespace sts::i2c::driver::impl { } void BusAccessor::Close() { - std::scoped_lock lk(this->open_mutex); + std::scoped_lock lk(this->open_mutex); /* Close current session. */ this->open_sessions--; if (this->open_sessions > 0) { @@ -67,8 +67,8 @@ namespace sts::i2c::driver::impl { } void BusAccessor::Suspend() { - std::scoped_lock lk(this->open_mutex); - std::scoped_lock lk_reg(this->register_mutex); + std::scoped_lock lk(this->open_mutex); + std::scoped_lock lk_reg(this->register_mutex); if (!this->suspended) { this->suspended = true; @@ -87,7 +87,7 @@ namespace sts::i2c::driver::impl { } void BusAccessor::DoInitialConfig() { - std::scoped_lock lk(this->register_mutex); + std::scoped_lock lk(this->register_mutex); if (this->pcv_module != PcvModule_I2C5) { pcv::Initialize(); @@ -124,7 +124,7 @@ namespace sts::i2c::driver::impl { } Result BusAccessor::Send(const u8 *data, size_t num_bytes, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address) { - std::scoped_lock lk(this->register_mutex); + std::scoped_lock lk(this->register_mutex); const u8 *cur_src = data; size_t remaining = num_bytes; @@ -193,7 +193,7 @@ namespace sts::i2c::driver::impl { } Result BusAccessor::Receive(u8 *out_data, size_t num_bytes, I2cTransactionOption option, AddressingMode addressing_mode, u32 slave_address) { - std::scoped_lock lk(this->register_mutex); + std::scoped_lock lk(this->register_mutex); u8 *cur_dst = out_data; size_t remaining = num_bytes; diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.hpp b/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.hpp index 37a43fdb7..a039434fb 100644 --- a/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.hpp +++ b/stratosphere/boot/source/i2c/driver/impl/i2c_bus_accessor.hpp @@ -32,8 +32,8 @@ namespace sts::i2c::driver::impl { static constexpr u64 InterruptTimeout = 100'000'000ul; private: Event interrupt_event; - HosMutex open_mutex; - HosMutex register_mutex; + os::Mutex open_mutex; + os::Mutex register_mutex; Registers *i2c_registers = nullptr; ClkRstRegisters clkrst_registers; SpeedMode speed_mode = SpeedMode::Fast; diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.cpp b/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.cpp index e7d01f34d..1e0d3b920 100644 --- a/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.cpp +++ b/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.cpp @@ -23,12 +23,12 @@ namespace sts::i2c::driver::impl { void ResourceManager::Initialize() { - std::scoped_lock lk(this->initialize_mutex); + std::scoped_lock lk(this->initialize_mutex); this->ref_cnt++; } void ResourceManager::Finalize() { - std::scoped_lock lk(this->initialize_mutex); + std::scoped_lock lk(this->initialize_mutex); if (this->ref_cnt == 0) { std::abort(); } @@ -38,7 +38,7 @@ namespace sts::i2c::driver::impl { } { - std::scoped_lock sess_lk(this->session_open_mutex); + std::scoped_lock sess_lk(this->session_open_mutex); for (size_t i = 0; i < MaxDriverSessions; i++) { this->sessions[i].Close(); } @@ -60,7 +60,7 @@ namespace sts::i2c::driver::impl { size_t session_id = InvalidSessionId; /* Get, open session. */ { - std::scoped_lock lk(this->session_open_mutex); + std::scoped_lock lk(this->session_open_mutex); if (out_session == nullptr || bus >= Bus::Count) { std::abort(); } @@ -98,7 +98,7 @@ namespace sts::i2c::driver::impl { bool need_disable_ldo6 = false; /* Get, open session. */ { - std::scoped_lock lk(this->session_open_mutex); + std::scoped_lock lk(this->session_open_mutex); if (!this->sessions[session.session_id].IsOpen()) { std::abort(); } @@ -128,7 +128,7 @@ namespace sts::i2c::driver::impl { if (!this->suspended) { { - std::scoped_lock lk(this->session_open_mutex); + std::scoped_lock lk(this->session_open_mutex); this->suspended = true; for (size_t i = 0; i < ConvertToIndex(Bus::Count); i++) { if (i != PowerBusId && this->bus_accessors[i].GetOpenSessions() > 0) { @@ -162,7 +162,7 @@ namespace sts::i2c::driver::impl { svcSleepThread(1'560'000ul); } { - std::scoped_lock lk(this->session_open_mutex); + std::scoped_lock lk(this->session_open_mutex); for (size_t i = 0; i < ConvertToIndex(Bus::Count); i++) { if (i != PowerBusId && this->bus_accessors[i].GetOpenSessions() > 0) { this->bus_accessors[i].Resume(); @@ -177,7 +177,7 @@ namespace sts::i2c::driver::impl { if (this->ref_cnt == 0) { std::abort(); } - std::scoped_lock lk(this->session_open_mutex); + std::scoped_lock lk(this->session_open_mutex); if (!this->power_bus_suspended) { this->power_bus_suspended = true; @@ -191,7 +191,7 @@ namespace sts::i2c::driver::impl { if (this->ref_cnt == 0) { std::abort(); } - std::scoped_lock lk(this->session_open_mutex); + std::scoped_lock lk(this->session_open_mutex); if (this->power_bus_suspended) { if (this->bus_accessors[PowerBusId].GetOpenSessions() > 0) { diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.hpp b/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.hpp index c0582491b..8f16e21de 100644 --- a/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.hpp +++ b/stratosphere/boot/source/i2c/driver/impl/i2c_resource_manager.hpp @@ -31,14 +31,14 @@ namespace sts::i2c::driver::impl { static constexpr size_t PowerBusId = ConvertToIndex(Bus::I2C5); static constexpr size_t InvalidSessionId = static_cast(-1); private: - HosMutex initialize_mutex; - HosMutex session_open_mutex; + os::Mutex initialize_mutex; + os::Mutex session_open_mutex; size_t ref_cnt = 0; bool suspended = false; bool power_bus_suspended = false; Session sessions[MaxDriverSessions]; BusAccessor bus_accessors[ConvertToIndex(Bus::Count)]; - HosMutex transaction_mutexes[ConvertToIndex(Bus::Count)]; + os::Mutex transaction_mutexes[ConvertToIndex(Bus::Count)]; public: ResourceManager() { /* ... */ @@ -60,7 +60,7 @@ namespace sts::i2c::driver::impl { return this->sessions[id]; } - HosMutex& GetTransactionMutex(Bus bus) { + os::Mutex& GetTransactionMutex(Bus bus) { return this->transaction_mutexes[ConvertToIndex(bus)]; } diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp b/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp index f54231dc7..5efd04988 100644 --- a/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp +++ b/stratosphere/boot/source/i2c/driver/impl/i2c_session.cpp @@ -22,7 +22,7 @@ namespace sts::i2c::driver::impl { void Session::Open(Bus bus, u32 slave_address, AddressingMode addr_mode, SpeedMode speed_mode, BusAccessor *bus_accessor, u32 max_retries, u64 retry_wait_time) { - std::scoped_lock lk(this->bus_accessor_mutex); + std::scoped_lock lk(this->bus_accessor_mutex); if (!this->open) { this->bus_accessor = bus_accessor; this->bus = bus; @@ -36,7 +36,7 @@ namespace sts::i2c::driver::impl { } void Session::Start() { - std::scoped_lock lk(this->bus_accessor_mutex); + std::scoped_lock lk(this->bus_accessor_mutex); if (this->open) { if (this->bus_accessor->GetOpenSessions() == 1) { this->bus_accessor->DoInitialConfig(); @@ -45,7 +45,7 @@ namespace sts::i2c::driver::impl { } void Session::Close() { - std::scoped_lock lk(this->bus_accessor_mutex); + std::scoped_lock lk(this->bus_accessor_mutex); if (this->open) { this->bus_accessor->Close(); this->bus_accessor = nullptr; @@ -58,7 +58,7 @@ namespace sts::i2c::driver::impl { } Result Session::DoTransaction(void *dst, const void *src, size_t num_bytes, I2cTransactionOption option, Command command) { - std::scoped_lock lk(this->bus_accessor_mutex); + std::scoped_lock lk(this->bus_accessor_mutex); if (this->bus_accessor->GetBusy()) { return ResultI2cBusBusy; diff --git a/stratosphere/boot/source/i2c/driver/impl/i2c_session.hpp b/stratosphere/boot/source/i2c/driver/impl/i2c_session.hpp index b9e162523..6ae8bbee8 100644 --- a/stratosphere/boot/source/i2c/driver/impl/i2c_session.hpp +++ b/stratosphere/boot/source/i2c/driver/impl/i2c_session.hpp @@ -25,7 +25,7 @@ namespace sts::i2c::driver::impl { class Session { private: - HosMutex bus_accessor_mutex; + os::Mutex bus_accessor_mutex; BusAccessor *bus_accessor = nullptr; Bus bus = Bus::I2C1; u32 slave_address = 0; diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp index 745703d08..cba90bcfc 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp @@ -31,14 +31,14 @@ namespace sts::dmnt::cheat::impl { /* Manager class. */ class CheatProcessManager { private: - HosMutex cheat_lock; - HosSignal debug_events_signal; - HosThread detect_thread, debug_events_thread; + os::Mutex cheat_lock; + os::Event debug_events_event; /* Autoclear. */ + os::Thread detect_thread, debug_events_thread; IEvent *cheat_process_event; Handle cheat_process_debug_handle = INVALID_HANDLE; CheatProcessMetadata cheat_process_metadata = {}; - HosThread vm_thread; + os::Thread vm_thread; bool needs_reload_vm = false; CheatVirtualMachine cheat_vm; @@ -546,7 +546,7 @@ namespace sts::dmnt::cheat::impl { CheatProcessManager *this_ptr = reinterpret_cast(_this); while (true) { /* Atomically wait (and clear) signal for new process. */ - this_ptr->debug_events_signal.Wait(true); + this_ptr->debug_events_event.Wait(); while (true) { while (R_SUCCEEDED(svcWaitSynchronizationSingle(this_ptr->GetCheatProcessHandle(), U64_MAX))) { std::scoped_lock lk(this_ptr->cheat_lock); @@ -707,7 +707,7 @@ namespace sts::dmnt::cheat::impl { } /* Signal to the debug events thread. */ - this->debug_events_signal.Signal(); + this->debug_events_event.Signal(); /* Signal to our fans. */ this->cheat_process_event->Signal(); diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_debug_events_manager.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_debug_events_manager.cpp index d7a2107e3..277edf2d9 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_debug_events_manager.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_debug_events_manager.cpp @@ -26,9 +26,9 @@ namespace sts::dmnt::cheat::impl { public: static constexpr size_t NumCores = 4; private: - HosMessageQueue message_queues[NumCores]; - HosThread threads[NumCores]; - HosSignal continued_signal; + std::array message_queues; + std::array threads; + os::Event continued_event; private: static void PerCoreThreadFunction(void *_this) { /* This thread will wait on the appropriate message queue. */ @@ -80,16 +80,15 @@ namespace sts::dmnt::cheat::impl { } void WaitContinued() { - this->continued_signal.Wait(); - this->continued_signal.Reset(); + this->continued_event.Wait(); } void SignalContinued() { - this->continued_signal.Signal(); + this->continued_event.Signal(); } public: - DebugEventsManager() : message_queues{HosMessageQueue(1), HosMessageQueue(1), HosMessageQueue(1), HosMessageQueue(1)} { + DebugEventsManager() : message_queues{os::MessageQueue(1), os::MessageQueue(1), os::MessageQueue(1), os::MessageQueue(1)} { for (size_t i = 0; i < NumCores; i++) { /* Create thread. */ R_ASSERT(this->threads[i].Initialize(&DebugEventsManager::PerCoreThreadFunction, reinterpret_cast(this), 0x1000, 24, i)); diff --git a/stratosphere/dmnt/source/dmnt_service_target_io.cpp b/stratosphere/dmnt/source/dmnt_service_target_io.cpp index 7ecca79b5..a22e63b44 100644 --- a/stratosphere/dmnt/source/dmnt_service_target_io.cpp +++ b/stratosphere/dmnt/source/dmnt_service_target_io.cpp @@ -31,15 +31,15 @@ namespace sts::dmnt { /* Nintendo uses actual pointers as file handles. We'll add a layer of indirection... */ bool g_sd_initialized = false; - HosMutex g_sd_lock; + os::Mutex g_sd_lock; FsFileSystem g_sd_fs; - HosMutex g_file_handle_lock; + os::Mutex g_file_handle_lock; u64 g_cur_fd; std::unordered_map g_file_handles; Result EnsureSdInitialized() { - std::scoped_lock lk(g_sd_lock); + std::scoped_lock lk(g_sd_lock); if (g_sd_initialized) { return ResultSuccess; } @@ -50,7 +50,7 @@ namespace sts::dmnt { } u64 GetNewFileHandle(FsFile f) { - std::scoped_lock lk(g_file_handle_lock); + std::scoped_lock lk(g_file_handle_lock); u64 fd = g_cur_fd++; g_file_handles[fd] = f; @@ -58,7 +58,7 @@ namespace sts::dmnt { } Result GetFileByHandle(FsFile *out, u64 handle) { - std::scoped_lock lk(g_file_handle_lock); + std::scoped_lock lk(g_file_handle_lock); if (g_file_handles.find(handle) != g_file_handles.end()) { *out = g_file_handles[handle]; @@ -69,7 +69,7 @@ namespace sts::dmnt { } Result CloseFileByHandle(u64 handle) { - std::scoped_lock lk(g_file_handle_lock); + std::scoped_lock lk(g_file_handle_lock); if (g_file_handles.find(handle) != g_file_handles.end()) { fsFileClose(&g_file_handles[handle]); diff --git a/stratosphere/fatal/source/fatal_event_manager.hpp b/stratosphere/fatal/source/fatal_event_manager.hpp index 2b477a482..b58e417eb 100644 --- a/stratosphere/fatal/source/fatal_event_manager.hpp +++ b/stratosphere/fatal/source/fatal_event_manager.hpp @@ -24,7 +24,7 @@ namespace sts::fatal::srv { private: static constexpr size_t NumFatalEvents = 3; - HosMutex lock; + os::Mutex lock; size_t num_events_gotten = 0; Event events[NumFatalEvents]; public: diff --git a/stratosphere/fatal/source/fatal_repair.cpp b/stratosphere/fatal/source/fatal_repair.cpp index a2ae32aac..efe47850f 100644 --- a/stratosphere/fatal/source/fatal_repair.cpp +++ b/stratosphere/fatal/source/fatal_repair.cpp @@ -45,7 +45,7 @@ namespace sts::fatal::srv { gpioPadSetDirection(&vol_btn, GpioDirection_Input); /* Ensure that we're holding the volume button for a full second. */ - TimeoutHelper timeout_helper(1'000'000'000ul); + os::TimeoutHelper timeout_helper(1'000'000'000ul); while (!timeout_helper.TimedOut()) { GpioValue val; if (R_FAILED(gpioPadGetValue(&vol_btn, &val)) || val != GpioValue_Low) { diff --git a/stratosphere/fatal/source/fatal_task.cpp b/stratosphere/fatal/source/fatal_task.cpp index 582b222a9..79c584923 100644 --- a/stratosphere/fatal/source/fatal_task.cpp +++ b/stratosphere/fatal/source/fatal_task.cpp @@ -33,7 +33,7 @@ namespace sts::fatal::srv { private: static constexpr int TaskThreadPriority = 15; private: - HosThread thread; + os::Thread thread; private: static void RunTaskImpl(void *arg) { ITask *task = reinterpret_cast(arg); diff --git a/stratosphere/fatal/source/fatal_task_power.cpp b/stratosphere/fatal/source/fatal_task_power.cpp index b6cd86672..20e1840fb 100644 --- a/stratosphere/fatal/source/fatal_task_power.cpp +++ b/stratosphere/fatal/source/fatal_task_power.cpp @@ -59,7 +59,7 @@ namespace sts::fatal::srv { /* Task Implementations. */ bool PowerControlTask::TryShutdown() { /* Set a timeout of 30 seconds. */ - TimeoutHelper timeout_helper(30'000'000'000ul); + os::TimeoutHelper timeout_helper(30'000'000'000ul); bool perform_shutdown = true; PsmBatteryVoltageState bv_state = PsmBatteryVoltageState_Normal; @@ -95,7 +95,7 @@ namespace sts::fatal::srv { /* Check the battery state, and shutdown on low voltage. */ if (R_FAILED(psmGetBatteryVoltageState(&bv_state)) || bv_state == PsmBatteryVoltageState_NeedsShutdown) { /* Wait a second for the error report task to finish. */ - eventWait(const_cast(&this->context->erpt_event), TimeoutHelper::NsToTick(1'000'000'000ul)); + eventWait(const_cast(&this->context->erpt_event), os::TimeoutHelper::NsToTick(1'000'000'000ul)); this->TryShutdown(); return; } @@ -129,12 +129,12 @@ namespace sts::fatal::srv { void PowerButtonObserveTask::WaitForPowerButton() { /* Wait up to a second for error report generation to finish. */ - eventWait(const_cast(&this->context->erpt_event), TimeoutHelper::NsToTick(1'000'000'000ul)); + eventWait(const_cast(&this->context->erpt_event), os::TimeoutHelper::NsToTick(1'000'000'000ul)); /* Force a reboot after some time if kiosk unit. */ const auto &config = GetFatalConfig(); - TimeoutHelper quest_reboot_helper(config.GetQuestRebootTimeoutInterval()); - TimeoutHelper fatal_reboot_helper(config.GetFatalRebootTimeoutInterval()); + os::TimeoutHelper quest_reboot_helper(config.GetQuestRebootTimeoutInterval()); + os::TimeoutHelper fatal_reboot_helper(config.GetFatalRebootTimeoutInterval()); bool check_vol_up = true, check_vol_down = true; GpioPadSession vol_up_btn, vol_down_btn; diff --git a/stratosphere/libstratosphere/Makefile b/stratosphere/libstratosphere/Makefile index add6a0814..c3f1c90d5 100644 --- a/stratosphere/libstratosphere/Makefile +++ b/stratosphere/libstratosphere/Makefile @@ -16,7 +16,7 @@ include $(DEVKITPRO)/libnx/switch_rules # INCLUDES is a list of directories containing header files #--------------------------------------------------------------------------------- TARGET := $(notdir $(CURDIR)) -SOURCES := source source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb +SOURCES := source source/os source/spl source/spl/smc source/updater source/patcher source/map source/rnd source/util source/sm source/cfg source/pm source/hid source/ldr source/kvdb DATA := data INCLUDES := include diff --git a/stratosphere/libstratosphere/include/stratosphere.hpp b/stratosphere/libstratosphere/include/stratosphere.hpp index 78832a5de..2192ff1dc 100644 --- a/stratosphere/libstratosphere/include/stratosphere.hpp +++ b/stratosphere/libstratosphere/include/stratosphere.hpp @@ -26,24 +26,20 @@ #include "stratosphere/version_check.hpp" #include "stratosphere/auto_handle.hpp" -#include "stratosphere/hossynch.hpp" -#include "stratosphere/message_queue.hpp" #include "stratosphere/iwaitable.hpp" #include "stratosphere/event.hpp" #include "stratosphere/waitable_manager.hpp" #include "stratosphere/ipc.hpp" - #include "stratosphere/mitm.hpp" -#include "stratosphere/services.hpp" - #include "stratosphere/results.hpp" #include "stratosphere/on_crash.hpp" #include "stratosphere/svc.hpp" +#include "stratosphere/os.hpp" #include "stratosphere/cfg.hpp" #include "stratosphere/fatal.hpp" #include "stratosphere/hid.hpp" diff --git a/stratosphere/libstratosphere/include/stratosphere/event.hpp b/stratosphere/libstratosphere/include/stratosphere/event.hpp index aa33419cf..326bf9354 100644 --- a/stratosphere/libstratosphere/include/stratosphere/event.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/event.hpp @@ -53,7 +53,7 @@ class IEvent : public IWaitable { } void Clear() { - std::scoped_lock lock(this->sig_lock); + std::scoped_lock lock(this->sig_lock); this->is_signaled = false; if (this->w_h != INVALID_HANDLE) { svcClearEvent(this->w_h); @@ -63,7 +63,7 @@ class IEvent : public IWaitable { } void Signal() { - std::scoped_lock lock(this->sig_lock); + std::scoped_lock lock(this->sig_lock); if (this->w_h == INVALID_HANDLE && this->r_h != INVALID_HANDLE) { /* We can't signal an event if we only have a read handle. */ diff --git a/stratosphere/libstratosphere/include/stratosphere/hossynch.hpp b/stratosphere/libstratosphere/include/stratosphere/hossynch.hpp deleted file mode 100644 index 2b654a74e..000000000 --- a/stratosphere/libstratosphere/include/stratosphere/hossynch.hpp +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (c) 2018-2019 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 -#include -#include -#include "results.hpp" -#include "auto_handle.hpp" - -class HosMutex { - private: - Mutex m; - Mutex *GetMutex() { - return &this->m; - } - public: - HosMutex() { - mutexInit(GetMutex()); - } - - void lock() { - mutexLock(GetMutex()); - } - - void unlock() { - mutexUnlock(GetMutex()); - } - - bool try_lock() { - return mutexTryLock(GetMutex()); - } - - void Lock() { - lock(); - } - - void Unlock() { - unlock(); - } - - bool TryLock() { - return try_lock(); - } - - friend class HosCondVar; -}; - -class HosRecursiveMutex { - private: - RMutex m; - RMutex *GetMutex() { - return &this->m; - } - public: - HosRecursiveMutex() { - rmutexInit(GetMutex()); - } - - void lock() { - rmutexLock(GetMutex()); - } - - void unlock() { - rmutexUnlock(GetMutex()); - } - - bool try_lock() { - return rmutexTryLock(GetMutex()); - } - - void Lock() { - lock(); - } - - void Unlock() { - unlock(); - } - - bool TryLock() { - return try_lock(); - } -}; - -class HosCondVar { - private: - CondVar cv; - public: - HosCondVar() { - condvarInit(&cv); - } - - Result TimedWait(u64 timeout, HosMutex *hm) { - return TimedWait(timeout, hm->GetMutex()); - } - - Result Wait(HosMutex *hm) { - return Wait(hm->GetMutex()); - } - - Result TimedWait(u64 timeout, Mutex *m) { - return condvarWaitTimeout(&cv, m, timeout); - } - - Result Wait(Mutex *m) { - return condvarWait(&cv, m); - } - - Result Wake(int num) { - return condvarWake(&cv, num); - } - - Result WakeOne() { - return condvarWakeOne(&cv); - } - - Result WakeAll() { - return condvarWakeAll(&cv); - } -}; - -class HosSemaphore { - private: - Semaphore s; - public: - HosSemaphore() { - semaphoreInit(&s, 0); - } - - HosSemaphore(u64 c) { - semaphoreInit(&s, c); - } - - void Signal() { - semaphoreSignal(&s); - } - - void Wait() { - semaphoreWait(&s); - } - - bool TryWait() { - return semaphoreTryWait(&s); - } -}; - -class TimeoutHelper { - private: - u64 end_tick; - public: - TimeoutHelper(u64 ns) { - /* Special case zero-time timeouts. */ - if (ns == 0) { - end_tick = 0; - return; - } - - u64 cur_tick = armGetSystemTick(); - this->end_tick = cur_tick + NsToTick(ns) + 1; - } - - static inline u64 NsToTick(u64 ns) { - return (ns * 12) / 625; - } - - static inline u64 TickToNs(u64 tick) { - return (tick * 625) / 12; - } - - u64 NsUntilTimeout() { - u64 diff = TickToNs(this->end_tick - armGetSystemTick()); - - if (TimedOut()) { - return 0; - } - - return diff; - } - - bool TimedOut() { - if (this->end_tick == 0) { - return true; - } - - return armGetSystemTick() >= this->end_tick; - } -}; - -class HosSignal { - private: - CondVar cv; - Mutex m; - bool signaled; - public: - HosSignal() { - condvarInit(&cv); - mutexInit(&m); - signaled = false; - } - - void Signal() { - mutexLock(&m); - signaled = true; - condvarWakeAll(&cv); - mutexUnlock(&m); - } - - void Reset() { - mutexLock(&m); - signaled = false; - mutexUnlock(&m); - } - - void Wait(bool reset = false) { - mutexLock(&m); - - while (!signaled) { - condvarWait(&cv, &m); - } - - if (reset) { - this->signaled = false; - } - - mutexUnlock(&m); - } - - bool TryWait(bool reset = false) { - mutexLock(&m); - - bool success = signaled; - if (reset) { - this->signaled = false; - } - - mutexUnlock(&m); - return success; - } - - Result TimedWait(u64 ns, bool reset = false) { - mutexLock(&m); - TimeoutHelper timeout_helper(ns); - - while (!signaled) { - if (R_FAILED(condvarWaitTimeout(&cv, &m, timeout_helper.NsUntilTimeout()))) { - return false; - } - } - - if (reset) { - this->signaled = false; - } - - mutexUnlock(&m); - return true; - } -}; - -class HosThread { - private: - Thread thr = {}; - public: - HosThread() {} - - Result Initialize(ThreadFunc entry, void *arg, size_t stack_sz, int prio, int cpuid = -2) { - return threadCreate(&this->thr, entry, arg, stack_sz, prio, cpuid); - } - - Handle GetHandle() const { - return this->thr.handle; - } - - Result Start() { - return threadStart(&this->thr); - } - - Result Join() { - R_TRY(threadWaitForExit(&this->thr)); - R_TRY(threadClose(&this->thr)); - return ResultSuccess; - } - - Result CancelSynchronization() { - return svcCancelSynchronization(this->thr.handle); - } -}; \ No newline at end of file diff --git a/stratosphere/libstratosphere/include/stratosphere/iwaitable.hpp b/stratosphere/libstratosphere/include/stratosphere/iwaitable.hpp index 9997a42ea..b5b206504 100644 --- a/stratosphere/libstratosphere/include/stratosphere/iwaitable.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/iwaitable.hpp @@ -17,9 +17,9 @@ #pragma once #include +#include "os.hpp" #include "waitable_manager_base.hpp" -#include "hossynch.hpp" class IWaitable { private: @@ -27,7 +27,7 @@ class IWaitable { bool is_deferred = false; WaitableManagerBase *manager = nullptr; protected: - HosMutex sig_lock; + sts::os::Mutex sig_lock; bool is_signaled = false; public: virtual ~IWaitable() = default; @@ -38,7 +38,7 @@ class IWaitable { } bool IsSignaled() { - std::scoped_lock lock(this->sig_lock); + std::scoped_lock lock(this->sig_lock); return this->is_signaled; } diff --git a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp index 708de5157..ea06860b3 100644 --- a/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/kvdb/kvdb_file_key_value_store.hpp @@ -17,6 +17,7 @@ #pragma once #include #include +#include "../os.hpp" #include "kvdb_bounded_string.hpp" @@ -66,7 +67,7 @@ namespace sts::kvdb { bool Contains(const void *key, size_t key_size); }; private: - HosMutex lock; + os::Mutex lock; Path dir_path; Cache cache; private: diff --git a/stratosphere/libstratosphere/include/stratosphere/message_queue.hpp b/stratosphere/libstratosphere/include/stratosphere/message_queue.hpp deleted file mode 100644 index cd9dc7439..000000000 --- a/stratosphere/libstratosphere/include/stratosphere/message_queue.hpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2018-2019 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 -#include "hossynch.hpp" -#include - -class HosMessageQueue { - private: - HosMutex queue_lock; - HosCondVar cv_not_full; - HosCondVar cv_not_empty; - std::unique_ptr buffer; - size_t capacity; - - size_t count = 0; - size_t offset = 0; - public: - HosMessageQueue(size_t c) : capacity(c) { - this->buffer = std::make_unique(this->capacity); - } - - HosMessageQueue(std::unique_ptr buf, size_t c) : buffer(std::move(buf)), capacity(c) { } - - /* Sending (FIFO functionality) */ - void Send(uintptr_t data); - bool TrySend(uintptr_t data); - bool TimedSend(uintptr_t data, u64 timeout); - - /* Sending (LIFO functionality) */ - void SendNext(uintptr_t data); - bool TrySendNext(uintptr_t data); - bool TimedSendNext(uintptr_t data, u64 timeout); - - /* Receive functionality */ - void Receive(uintptr_t *out); - bool TryReceive(uintptr_t *out); - bool TimedReceive(uintptr_t *out, u64 timeout); - - /* Peek functionality */ - void Peek(uintptr_t *out); - bool TryPeek(uintptr_t *out); - bool TimedPeek(uintptr_t *out, u64 timeout); - private: - bool IsFull() { - return this->count >= this->capacity; - } - - bool IsEmpty() { - return this->count == 0; - } - - void SendInternal(uintptr_t data); - void SendNextInternal(uintptr_t data); - uintptr_t ReceiveInternal(); - uintptr_t PeekInternal(); - -}; - diff --git a/stratosphere/libstratosphere/include/stratosphere/services.hpp b/stratosphere/libstratosphere/include/stratosphere/os.hpp similarity index 73% rename from stratosphere/libstratosphere/include/stratosphere/services.hpp rename to stratosphere/libstratosphere/include/stratosphere/os.hpp index fdd292abc..b3a53469d 100644 --- a/stratosphere/libstratosphere/include/stratosphere/services.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/os.hpp @@ -15,7 +15,12 @@ */ #pragma once +#include -#include "ipc.hpp" - -#include "services/dmntcht.h" \ No newline at end of file +#include "os/os_mutex.hpp" +#include "os/os_condvar.hpp" +#include "os/os_semaphore.hpp" +#include "os/os_timeout_helper.hpp" +#include "os/os_event.hpp" +#include "os/os_thread.hpp" +#include "os/os_message_queue.hpp" \ No newline at end of file diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_condvar.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_condvar.hpp new file mode 100644 index 000000000..eed8e16c4 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_condvar.hpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018-2019 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 "os_mutex.hpp" + +namespace sts::os { + + class ConditionVariable { + NON_COPYABLE(ConditionVariable); + NON_MOVEABLE(ConditionVariable); + private: + CondVar cv; + public: + ConditionVariable() { + condvarInit(&cv); + } + + Result TimedWait(::Mutex *m, u64 timeout) { + return condvarWaitTimeout(&cv, m, timeout); + } + + Result Wait(::Mutex *m) { + return condvarWait(&cv, m); + } + + Result TimedWait(os::Mutex *m, u64 timeout) { + return TimedWait(m->GetMutex(), timeout); + } + + Result Wait(os::Mutex *m) { + return Wait(m->GetMutex()); + } + + Result Wake(int num) { + return condvarWake(&cv, num); + } + + Result WakeOne() { + return condvarWakeOne(&cv); + } + + Result WakeAll() { + return condvarWakeAll(&cv); + } + + Result Signal() { + return this->WakeOne(); + } + + Result Broadcast() { + return this->WakeAll(); + } + }; + +} \ No newline at end of file diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_event.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_event.hpp new file mode 100644 index 000000000..e287db6c9 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_event.hpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018-2019 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 "os_mutex.hpp" +#include "os_condvar.hpp" +#include "os_timeout_helper.hpp" + +namespace sts::os { + + class Event { + NON_COPYABLE(Event); + NON_MOVEABLE(Event); + private: + Mutex m; + ConditionVariable cv; + bool auto_clear; + bool signaled; + u64 counter = 0; + public: + Event(bool a = true, bool s = false) : auto_clear(a), signaled(s) {} + + void Signal() { + std::scoped_lock lk(this->m); + + /* If we're already signaled, nothing more to do. */ + if (this->signaled) { + return; + } + + this->signaled = true; + + /* Signal! */ + if (this->auto_clear) { + /* If we're auto clear, signal one thread, which will clear. */ + this->cv.Signal(); + } else { + /* If we're manual clear, increment counter and wake all. */ + this->counter++; + this->cv.Broadcast(); + } + + /* TODO: Waitable auto-wakeup. */ + } + + void Reset() { + std::scoped_lock lk(this->m); + this->signaled = false; + } + + void Wait() { + std::scoped_lock lk(this->m); + + u64 cur_counter = this->counter; + while (!this->signaled) { + if (this->counter != cur_counter) { + break; + } + this->cv.Wait(&this->m); + } + + if (this->auto_clear) { + this->signaled = false; + } + } + + bool TryWait() { + std::scoped_lock lk(this->m); + + const bool success = this->signaled; + if (this->auto_clear) { + this->signaled = false; + } + + return success; + } + + bool TimedWait(u64 ns) { + TimeoutHelper timeout_helper(ns); + std::scoped_lock lk(this->m); + + u64 cur_counter = this->counter; + while (!this->signaled) { + if (this->counter != cur_counter) { + break; + } + if (R_FAILED(this->cv.TimedWait(&this->m, timeout_helper.NsUntilTimeout()))) { + return false; + } + } + + if (this->auto_clear) { + this->signaled = false; + } + + return true; + } + }; + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_message_queue.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_message_queue.hpp new file mode 100644 index 000000000..7c9f8bad6 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_message_queue.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018-2019 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 +#include "os_mutex.hpp" +#include "os_condvar.hpp" + +namespace sts::os { + + class MessageQueue { + NON_COPYABLE(MessageQueue); + NON_MOVEABLE(MessageQueue); + private: + Mutex queue_lock; + ConditionVariable cv_not_full; + ConditionVariable cv_not_empty; + std::unique_ptr buffer; + size_t capacity; + + size_t count = 0; + size_t offset = 0; + private: + bool IsFull() const { + return this->count >= this->capacity; + } + + bool IsEmpty() const { + return this->count == 0; + } + + void SendInternal(uintptr_t data); + void SendNextInternal(uintptr_t data); + uintptr_t ReceiveInternal(); + uintptr_t PeekInternal(); + public: + MessageQueue(size_t c) : capacity(c) { + this->buffer = std::make_unique(this->capacity); + } + + MessageQueue(std::unique_ptr buf, size_t c) : buffer(std::move(buf)), capacity(c) { } + + /* Sending (FIFO functionality) */ + void Send(uintptr_t data); + bool TrySend(uintptr_t data); + bool TimedSend(uintptr_t data, u64 timeout); + + /* Sending (LIFO functionality) */ + void SendNext(uintptr_t data); + bool TrySendNext(uintptr_t data); + bool TimedSendNext(uintptr_t data, u64 timeout); + + /* Receive functionality */ + void Receive(uintptr_t *out); + bool TryReceive(uintptr_t *out); + bool TimedReceive(uintptr_t *out, u64 timeout); + + /* Peek functionality */ + void Peek(uintptr_t *out); + bool TryPeek(uintptr_t *out); + bool TimedPeek(uintptr_t *out, u64 timeout); + }; + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_mutex.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_mutex.hpp new file mode 100644 index 000000000..c17038d84 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_mutex.hpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2018-2019 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 +#include +#include "../util.hpp" + +namespace sts::os { + + class ConditionVariable; + + class Mutex { + NON_COPYABLE(Mutex); + NON_MOVEABLE(Mutex); + friend class sts::os::ConditionVariable; + private: + ::Mutex m; + private: + ::Mutex *GetMutex() { + return &this->m; + } + public: + Mutex() { + mutexInit(GetMutex()); + } + + void lock() { + mutexLock(GetMutex()); + } + + void unlock() { + mutexUnlock(GetMutex()); + } + + bool try_lock() { + return mutexTryLock(GetMutex()); + } + + void Lock() { + lock(); + } + + void Unlock() { + unlock(); + } + + bool TryLock() { + return try_lock(); + } + }; + + class RecursiveMutex { + private: + ::RMutex m; + private: + ::RMutex *GetMutex() { + return &this->m; + } + public: + RecursiveMutex() { + rmutexInit(GetMutex()); + } + + void lock() { + rmutexLock(GetMutex()); + } + + void unlock() { + rmutexUnlock(GetMutex()); + } + + bool try_lock() { + return rmutexTryLock(GetMutex()); + } + + void Lock() { + lock(); + } + + void Unlock() { + unlock(); + } + + bool TryLock() { + return try_lock(); + } + }; + +} \ No newline at end of file diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_semaphore.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_semaphore.hpp new file mode 100644 index 000000000..3b8ac7063 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_semaphore.hpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2018-2019 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 + +namespace sts::os { + + class Semaphore { + NON_COPYABLE(Semaphore); + NON_MOVEABLE(Semaphore); + private: + ::Semaphore s; + public: + Semaphore() { + semaphoreInit(&s, 0); + } + + Semaphore(u64 c) { + semaphoreInit(&s, c); + } + + void Signal() { + semaphoreSignal(&s); + } + + void Wait() { + semaphoreWait(&s); + } + + bool TryWait() { + return semaphoreTryWait(&s); + } + }; + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp new file mode 100644 index 000000000..e659ac3c7 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_thread.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018-2019 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 + +namespace sts::os { + + class Thread { + private: + ::Thread thr = {}; + public: + Thread() {} + + Result Initialize(ThreadFunc entry, void *arg, size_t stack_sz, int prio, int cpuid = -2) { + return threadCreate(&this->thr, entry, arg, stack_sz, prio, cpuid); + } + + Handle GetHandle() const { + return this->thr.handle; + } + + Result Start() { + return threadStart(&this->thr); + } + + Result Join() { + R_TRY(threadWaitForExit(&this->thr)); + R_TRY(threadClose(&this->thr)); + return ResultSuccess; + } + + Result CancelSynchronization() { + return svcCancelSynchronization(this->thr.handle); + } + }; + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/os/os_timeout_helper.hpp b/stratosphere/libstratosphere/include/stratosphere/os/os_timeout_helper.hpp new file mode 100644 index 000000000..31c52b385 --- /dev/null +++ b/stratosphere/libstratosphere/include/stratosphere/os/os_timeout_helper.hpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018-2019 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 + +namespace sts::os { + + class TimeoutHelper { + private: + u64 end_tick; + public: + TimeoutHelper(u64 ns) { + /* Special case zero-time timeouts. */ + if (ns == 0) { + end_tick = 0; + return; + } + + u64 cur_tick = armGetSystemTick(); + this->end_tick = cur_tick + NsToTick(ns) + 1; + } + + static constexpr inline u64 NsToTick(u64 ns) { + return (ns * 12) / 625; + } + + static constexpr inline u64 TickToNs(u64 tick) { + return (tick * 625) / 12; + } + + bool TimedOut() const { + if (this->end_tick == 0) { + return true; + } + + return armGetSystemTick() >= this->end_tick; + } + + u64 NsUntilTimeout() const { + u64 diff = TickToNs(this->end_tick - armGetSystemTick()); + + if (this->TimedOut()) { + return 0; + } + + return diff; + } + }; + +} diff --git a/stratosphere/libstratosphere/include/stratosphere/utilities.hpp b/stratosphere/libstratosphere/include/stratosphere/utilities.hpp index a9f993f7f..4de68dc18 100644 --- a/stratosphere/libstratosphere/include/stratosphere/utilities.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/utilities.hpp @@ -16,9 +16,9 @@ #pragma once #include -#include - -#include "hossynch.hpp" +#include "defines.hpp" +#include "results.hpp" +#include "os.hpp" static inline uintptr_t GetIoMapping(const u64 io_addr, const u64 io_size) { u64 vaddr; @@ -115,11 +115,11 @@ static inline bool ShouldBlankProdInfo() { return should_blank_prodinfo; } -HosRecursiveMutex &GetSmSessionMutex(); +sts::os::RecursiveMutex &GetSmSessionMutex(); template static void DoWithSmSession(F f) { - std::scoped_lock lk(GetSmSessionMutex()); + std::scoped_lock lk(GetSmSessionMutex()); { R_ASSERT(smInitialize()); f(); diff --git a/stratosphere/libstratosphere/include/stratosphere/waitable_manager.hpp b/stratosphere/libstratosphere/include/stratosphere/waitable_manager.hpp index 556a1c44b..7edc4b52e 100644 --- a/stratosphere/libstratosphere/include/stratosphere/waitable_manager.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/waitable_manager.hpp @@ -21,6 +21,7 @@ #include #include "results.hpp" +#include "os.hpp" #include "waitable_manager_base.hpp" #include "event.hpp" #include "ipc.hpp" @@ -47,7 +48,7 @@ template class WaitableManager : public SessionManagerBase { private: /* Domain Manager */ - HosMutex domain_lock; + sts::os::Mutex domain_lock; std::array domain_keys; std::array is_domain_allocated; std::array domain_objects; @@ -58,13 +59,13 @@ class WaitableManager : public SessionManagerBase { std::vector deferred_waitables; u32 num_extra_threads = 0; - HosThread *threads = nullptr; + sts::os::Thread *threads = nullptr; - HosMutex process_lock; - HosMutex signal_lock; - HosMutex add_lock; - HosMutex cur_thread_lock; - HosMutex deferred_lock; + sts::os::Mutex process_lock; + sts::os::Mutex signal_lock; + sts::os::Mutex add_lock; + sts::os::Mutex cur_thread_lock; + sts::os::Mutex deferred_lock; bool has_new_waitables = false; std::atomic should_stop = false; @@ -75,7 +76,7 @@ class WaitableManager : public SessionManagerBase { WaitableManager(u32 n, u32 ss = 0x8000) : num_extra_threads(n-1) { u32 prio; if (num_extra_threads) { - threads = new HosThread[num_extra_threads]; + threads = new sts::os::Thread[num_extra_threads]; R_ASSERT(svcGetThreadPriority(&prio, CUR_THREAD_HANDLE)); for (unsigned int i = 0; i < num_extra_threads; i++) { R_ASSERT(threads[i].Initialize(&WaitableManager::ProcessLoop, this, ss, prio)); @@ -132,12 +133,12 @@ class WaitableManager : public SessionManagerBase { } private: void SetProcessingThreadHandle(Handle h) { - std::scoped_lock lk{this->cur_thread_lock}; + std::scoped_lock lk{this->cur_thread_lock}; this->cur_thread_handle = h; } Handle GetProcessingThreadHandle() { - std::scoped_lock lk{this->cur_thread_lock}; + std::scoped_lock lk{this->cur_thread_lock}; return this->cur_thread_handle; } diff --git a/stratosphere/libstratosphere/source/cfg/cfg_privileged_process.cpp b/stratosphere/libstratosphere/source/cfg/cfg_privileged_process.cpp index cab6469bc..b12c5237b 100644 --- a/stratosphere/libstratosphere/source/cfg/cfg_privileged_process.cpp +++ b/stratosphere/libstratosphere/source/cfg/cfg_privileged_process.cpp @@ -27,7 +27,7 @@ namespace sts::cfg { constexpr u64 InitialProcessIdMaxDeprecated = 0x50; /* Privileged process globals. */ - HosMutex g_lock; + os::Mutex g_lock; bool g_got_privileged_process_status = false; u64 g_min_initial_process_id = 0, g_max_initial_process_id = 0; u64 g_cur_process_id = 0; @@ -69,7 +69,7 @@ namespace sts::cfg { /* Privileged Process utilities. */ bool IsInitialProcess() { - std::scoped_lock lk(g_lock); + std::scoped_lock lk(g_lock); /* If we've not detected, do detection. */ if (!g_got_privileged_process_status) { @@ -81,7 +81,7 @@ namespace sts::cfg { } void GetInitialProcessRange(u64 *out_min, u64 *out_max) { - std::scoped_lock lk(g_lock); + std::scoped_lock lk(g_lock); /* If we've not detected, do detection. */ if (!g_got_privileged_process_status) { diff --git a/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp b/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp index 9543cf670..e2276fac7 100644 --- a/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp +++ b/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp @@ -33,7 +33,7 @@ namespace sts::cfg { constexpr size_t NumRequiredServicesForSdCardAccess = util::size(RequiredServicesForSdCardAccess); /* SD card globals. */ - HosMutex g_sd_card_lock; + os::Mutex g_sd_card_lock; bool g_sd_card_initialized = false; FsFileSystem g_sd_card_filesystem = {}; @@ -64,7 +64,7 @@ namespace sts::cfg { /* SD card utilities. */ bool IsSdCardInitialized() { - std::scoped_lock lk(g_sd_card_lock); + std::scoped_lock lk(g_sd_card_lock); if (!g_sd_card_initialized) { if (R_SUCCEEDED(TryInitializeSdCard())) { @@ -75,7 +75,7 @@ namespace sts::cfg { } void WaitSdCardInitialized() { - std::scoped_lock lk(g_sd_card_lock); + std::scoped_lock lk(g_sd_card_lock); InitializeSdCard(); } diff --git a/stratosphere/libstratosphere/source/hid/hid_api.cpp b/stratosphere/libstratosphere/source/hid/hid_api.cpp index b4f476756..7f1fc7f5a 100644 --- a/stratosphere/libstratosphere/source/hid/hid_api.cpp +++ b/stratosphere/libstratosphere/source/hid/hid_api.cpp @@ -24,7 +24,7 @@ namespace sts::hid { namespace { /* Global lock. */ - HosMutex g_hid_lock; + os::Mutex g_hid_lock; bool g_initialized_hid = false; /* Helper. */ @@ -53,7 +53,7 @@ namespace sts::hid { } Result GetKeysHeld(u64 *out) { - std::scoped_lock lk(g_hid_lock); + std::scoped_lock lk(g_hid_lock); R_TRY(EnsureHidInitialized()); diff --git a/stratosphere/libstratosphere/source/message_queue.cpp b/stratosphere/libstratosphere/source/message_queue.cpp deleted file mode 100644 index d972e53e8..000000000 --- a/stratosphere/libstratosphere/source/message_queue.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2018-2019 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 . - */ - -#include -#include -#include - - -void HosMessageQueue::Send(uintptr_t data) { - /* Acquire mutex, wait sendable. */ - std::scoped_lock lock(this->queue_lock); - - while (this->IsFull()) { - this->cv_not_full.Wait(&this->queue_lock); - } - - /* Send, signal. */ - this->SendInternal(data); - this->cv_not_empty.WakeAll(); -} - -bool HosMessageQueue::TrySend(uintptr_t data) { - std::scoped_lock lock(this->queue_lock); - if (this->IsFull()) { - return false; - } - - /* Send, signal. */ - this->SendInternal(data); - this->cv_not_empty.WakeAll(); - return true; -} - -bool HosMessageQueue::TimedSend(uintptr_t data, u64 timeout) { - std::scoped_lock lock(this->queue_lock); - TimeoutHelper timeout_helper(timeout); - - while (this->IsFull()) { - if (timeout_helper.TimedOut()) { - return false; - } - - this->cv_not_full.TimedWait(timeout, &this->queue_lock); - } - - /* Send, signal. */ - this->SendInternal(data); - this->cv_not_empty.WakeAll(); - return true; -} - -void HosMessageQueue::SendNext(uintptr_t data) { - /* Acquire mutex, wait sendable. */ - std::scoped_lock lock(this->queue_lock); - - while (this->IsFull()) { - this->cv_not_full.Wait(&this->queue_lock); - } - - /* Send, signal. */ - this->SendNextInternal(data); - this->cv_not_empty.WakeAll(); -} - -bool HosMessageQueue::TrySendNext(uintptr_t data) { - std::scoped_lock lock(this->queue_lock); - if (this->IsFull()) { - return false; - } - - /* Send, signal. */ - this->SendNextInternal(data); - this->cv_not_empty.WakeAll(); - return true; -} - -bool HosMessageQueue::TimedSendNext(uintptr_t data, u64 timeout) { - std::scoped_lock lock(this->queue_lock); - TimeoutHelper timeout_helper(timeout); - - while (this->IsFull()) { - if (timeout_helper.TimedOut()) { - return false; - } - - this->cv_not_full.TimedWait(timeout, &this->queue_lock); - } - - /* Send, signal. */ - this->SendNextInternal(data); - this->cv_not_empty.WakeAll(); - return true; -} - -void HosMessageQueue::Receive(uintptr_t *out) { - /* Acquire mutex, wait receivable. */ - std::scoped_lock lock(this->queue_lock); - - while (this->IsEmpty()) { - this->cv_not_empty.Wait(&this->queue_lock); - } - - /* Receive, signal. */ - *out = this->ReceiveInternal(); - this->cv_not_full.WakeAll(); -} -bool HosMessageQueue::TryReceive(uintptr_t *out) { - /* Acquire mutex, wait receivable. */ - std::scoped_lock lock(this->queue_lock); - - if (this->IsEmpty()) { - return false; - } - - /* Receive, signal. */ - *out = this->ReceiveInternal(); - this->cv_not_full.WakeAll(); - return true; -} - -bool HosMessageQueue::TimedReceive(uintptr_t *out, u64 timeout) { - std::scoped_lock lock(this->queue_lock); - TimeoutHelper timeout_helper(timeout); - - while (this->IsEmpty()) { - if (timeout_helper.TimedOut()) { - return false; - } - - this->cv_not_empty.TimedWait(timeout, &this->queue_lock); - } - - /* Receive, signal. */ - *out = this->ReceiveInternal(); - this->cv_not_full.WakeAll(); - return true; -} - -void HosMessageQueue::Peek(uintptr_t *out) { - /* Acquire mutex, wait receivable. */ - std::scoped_lock lock(this->queue_lock); - - while (this->IsEmpty()) { - this->cv_not_empty.Wait(&this->queue_lock); - } - - /* Peek. */ - *out = this->PeekInternal(); -} - -bool HosMessageQueue::TryPeek(uintptr_t *out) { - /* Acquire mutex, wait receivable. */ - std::scoped_lock lock(this->queue_lock); - - if (this->IsEmpty()) { - return false; - } - - /* Peek. */ - *out = this->PeekInternal(); - return true; -} - -bool HosMessageQueue::TimedPeek(uintptr_t *out, u64 timeout) { - std::scoped_lock lock(this->queue_lock); - TimeoutHelper timeout_helper(timeout); - - while (this->IsEmpty()) { - if (timeout_helper.TimedOut()) { - return false; - } - - this->cv_not_empty.TimedWait(timeout, &this->queue_lock); - } - - /* Peek. */ - *out = this->PeekInternal(); - return true; -} - -void HosMessageQueue::SendInternal(uintptr_t data) { - /* Ensure we don't corrupt the queue, but this should never happen. */ - if (this->count >= this->capacity) { - std::abort(); - } - - /* Write data to tail of queue. */ - this->buffer[(this->count++ + this->offset) % this->capacity] = data; -} - -void HosMessageQueue::SendNextInternal(uintptr_t data) { - /* Ensure we don't corrupt the queue, but this should never happen. */ - if (this->count >= this->capacity) { - std::abort(); - } - - /* Write data to head of queue. */ - this->offset = (this->offset + this->capacity - 1) % this->capacity; - this->buffer[this->offset] = data; - this->count++; -} - -uintptr_t HosMessageQueue::ReceiveInternal() { - /* Ensure we don't corrupt the queue, but this should never happen. */ - if (this->count == 0) { - std::abort(); - } - - uintptr_t data = this->buffer[this->offset]; - this->offset = (this->offset + 1) % this->capacity; - this->count--; - return data; -} - -uintptr_t HosMessageQueue::PeekInternal() { - /* Ensure we don't corrupt the queue, but this should never happen. */ - if (this->count == 0) { - std::abort(); - } - - return this->buffer[this->offset]; -} \ No newline at end of file diff --git a/stratosphere/libstratosphere/source/mitm_server.cpp b/stratosphere/libstratosphere/source/mitm_server.cpp index d090584e2..7f9f74cb2 100644 --- a/stratosphere/libstratosphere/source/mitm_server.cpp +++ b/stratosphere/libstratosphere/source/mitm_server.cpp @@ -18,8 +18,8 @@ #include #include -static HosMutex g_server_query_mutex; -static HosThread g_server_query_manager_thread; +static sts::os::Mutex g_server_query_mutex; +static sts::os::Thread g_server_query_manager_thread; static SessionManagerBase *g_server_query_manager = nullptr; static void ServerQueryManagerThreadFunc(void *arg) { @@ -27,7 +27,7 @@ static void ServerQueryManagerThreadFunc(void *arg) { } void RegisterMitmServerQueryHandle(Handle query_h, ServiceObjectHolder &&service) { - std::scoped_lock lock(g_server_query_mutex); + std::scoped_lock lock(g_server_query_mutex); const bool exists = g_server_query_manager != nullptr; if (!exists) { diff --git a/stratosphere/libstratosphere/source/os/os_message_queue.cpp b/stratosphere/libstratosphere/source/os/os_message_queue.cpp new file mode 100644 index 000000000..2008ed7b3 --- /dev/null +++ b/stratosphere/libstratosphere/source/os/os_message_queue.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2018-2019 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 . + */ +#include + +namespace sts::os { + + void MessageQueue::SendInternal(uintptr_t data) { + /* Ensure we don't corrupt the queue, but this should never happen. */ + if (this->count >= this->capacity) { + std::abort(); + } + + /* Write data to tail of queue. */ + this->buffer[(this->count++ + this->offset) % this->capacity] = data; + } + + void MessageQueue::SendNextInternal(uintptr_t data) { + /* Ensure we don't corrupt the queue, but this should never happen. */ + if (this->count >= this->capacity) { + std::abort(); + } + + /* Write data to head of queue. */ + this->offset = (this->offset + this->capacity - 1) % this->capacity; + this->buffer[this->offset] = data; + this->count++; + } + + uintptr_t MessageQueue::ReceiveInternal() { + /* Ensure we don't corrupt the queue, but this should never happen. */ + if (this->count == 0) { + std::abort(); + } + + uintptr_t data = this->buffer[this->offset]; + this->offset = (this->offset + 1) % this->capacity; + this->count--; + return data; + } + + uintptr_t MessageQueue::PeekInternal() { + /* Ensure we don't corrupt the queue, but this should never happen. */ + if (this->count == 0) { + std::abort(); + } + + return this->buffer[this->offset]; + } + + void MessageQueue::Send(uintptr_t data) { + /* Acquire mutex, wait sendable. */ + std::scoped_lock lock(this->queue_lock); + + while (this->IsFull()) { + this->cv_not_full.Wait(&this->queue_lock); + } + + /* Send, signal. */ + this->SendInternal(data); + this->cv_not_empty.WakeAll(); + } + + bool MessageQueue::TrySend(uintptr_t data) { + std::scoped_lock lock(this->queue_lock); + if (this->IsFull()) { + return false; + } + + /* Send, signal. */ + this->SendInternal(data); + this->cv_not_empty.WakeAll(); + return true; + } + + bool MessageQueue::TimedSend(uintptr_t data, u64 timeout) { + std::scoped_lock lock(this->queue_lock); + TimeoutHelper timeout_helper(timeout); + + while (this->IsFull()) { + if (timeout_helper.TimedOut()) { + return false; + } + + this->cv_not_full.TimedWait(&this->queue_lock, timeout); + } + + /* Send, signal. */ + this->SendInternal(data); + this->cv_not_empty.WakeAll(); + return true; + } + + void MessageQueue::SendNext(uintptr_t data) { + /* Acquire mutex, wait sendable. */ + std::scoped_lock lock(this->queue_lock); + + while (this->IsFull()) { + this->cv_not_full.Wait(&this->queue_lock); + } + + /* Send, signal. */ + this->SendNextInternal(data); + this->cv_not_empty.WakeAll(); + } + + bool MessageQueue::TrySendNext(uintptr_t data) { + std::scoped_lock lock(this->queue_lock); + if (this->IsFull()) { + return false; + } + + /* Send, signal. */ + this->SendNextInternal(data); + this->cv_not_empty.WakeAll(); + return true; + } + + bool MessageQueue::TimedSendNext(uintptr_t data, u64 timeout) { + std::scoped_lock lock(this->queue_lock); + TimeoutHelper timeout_helper(timeout); + + while (this->IsFull()) { + if (timeout_helper.TimedOut()) { + return false; + } + + this->cv_not_full.TimedWait(&this->queue_lock, timeout); + } + + /* Send, signal. */ + this->SendNextInternal(data); + this->cv_not_empty.WakeAll(); + return true; + } + + void MessageQueue::Receive(uintptr_t *out) { + /* Acquire mutex, wait receivable. */ + std::scoped_lock lock(this->queue_lock); + + while (this->IsEmpty()) { + this->cv_not_empty.Wait(&this->queue_lock); + } + + /* Receive, signal. */ + *out = this->ReceiveInternal(); + this->cv_not_full.WakeAll(); + } + bool MessageQueue::TryReceive(uintptr_t *out) { + /* Acquire mutex, wait receivable. */ + std::scoped_lock lock(this->queue_lock); + + if (this->IsEmpty()) { + return false; + } + + /* Receive, signal. */ + *out = this->ReceiveInternal(); + this->cv_not_full.WakeAll(); + return true; + } + + bool MessageQueue::TimedReceive(uintptr_t *out, u64 timeout) { + std::scoped_lock lock(this->queue_lock); + TimeoutHelper timeout_helper(timeout); + + while (this->IsEmpty()) { + if (timeout_helper.TimedOut()) { + return false; + } + + this->cv_not_empty.TimedWait(&this->queue_lock, timeout); + } + + /* Receive, signal. */ + *out = this->ReceiveInternal(); + this->cv_not_full.WakeAll(); + return true; + } + + void MessageQueue::Peek(uintptr_t *out) { + /* Acquire mutex, wait receivable. */ + std::scoped_lock lock(this->queue_lock); + + while (this->IsEmpty()) { + this->cv_not_empty.Wait(&this->queue_lock); + } + + /* Peek. */ + *out = this->PeekInternal(); + } + + bool MessageQueue::TryPeek(uintptr_t *out) { + /* Acquire mutex, wait receivable. */ + std::scoped_lock lock(this->queue_lock); + + if (this->IsEmpty()) { + return false; + } + + /* Peek. */ + *out = this->PeekInternal(); + return true; + } + + bool MessageQueue::TimedPeek(uintptr_t *out, u64 timeout) { + std::scoped_lock lock(this->queue_lock); + TimeoutHelper timeout_helper(timeout); + + while (this->IsEmpty()) { + if (timeout_helper.TimedOut()) { + return false; + } + + this->cv_not_empty.TimedWait(&this->queue_lock, timeout); + } + + /* Peek. */ + *out = this->PeekInternal(); + return true; + } + +} diff --git a/stratosphere/libstratosphere/source/pm/pm_info_api.cpp b/stratosphere/libstratosphere/source/pm/pm_info_api.cpp index 379d49c19..9f3c8b7db 100644 --- a/stratosphere/libstratosphere/source/pm/pm_info_api.cpp +++ b/stratosphere/libstratosphere/source/pm/pm_info_api.cpp @@ -25,26 +25,26 @@ namespace sts::pm::info { namespace { /* Global lock. */ - HosMutex g_info_lock; + os::Mutex g_info_lock; std::set g_cached_launched_titles; } /* Information API. */ Result GetTitleId(ncm::TitleId *out_title_id, u64 process_id) { - std::scoped_lock lk(g_info_lock); + std::scoped_lock lk(g_info_lock); return pminfoGetTitleId(reinterpret_cast(out_title_id), process_id); } Result GetProcessId(u64 *out_process_id, ncm::TitleId title_id) { - std::scoped_lock lk(g_info_lock); + std::scoped_lock lk(g_info_lock); return pminfoAtmosphereGetProcessId(out_process_id, static_cast(title_id)); } Result WEAK HasLaunchedTitle(bool *out, ncm::TitleId title_id) { - std::scoped_lock lk(g_info_lock); + std::scoped_lock lk(g_info_lock); if (g_cached_launched_titles.find(static_cast(title_id)) != g_cached_launched_titles.end()) { *out = true; diff --git a/stratosphere/libstratosphere/source/sm/sm_utils.cpp b/stratosphere/libstratosphere/source/sm/sm_utils.cpp index c2cd1c258..460fce338 100644 --- a/stratosphere/libstratosphere/source/sm/sm_utils.cpp +++ b/stratosphere/libstratosphere/source/sm/sm_utils.cpp @@ -21,17 +21,17 @@ namespace sts::sm::impl { namespace { /* Globals. */ - HosRecursiveMutex g_user_session_mutex; - HosRecursiveMutex g_mitm_session_mutex; + os::RecursiveMutex g_user_session_mutex; + os::RecursiveMutex g_mitm_session_mutex; } /* Utilities. */ - HosRecursiveMutex &GetUserSessionMutex() { + os::RecursiveMutex &GetUserSessionMutex() { return g_user_session_mutex; } - HosRecursiveMutex &GetMitmSessionMutex() { + os::RecursiveMutex &GetMitmSessionMutex() { return g_mitm_session_mutex; } diff --git a/stratosphere/libstratosphere/source/sm/sm_utils.hpp b/stratosphere/libstratosphere/source/sm/sm_utils.hpp index 410806f01..11bb99408 100644 --- a/stratosphere/libstratosphere/source/sm/sm_utils.hpp +++ b/stratosphere/libstratosphere/source/sm/sm_utils.hpp @@ -25,12 +25,12 @@ namespace sts::sm::impl { /* Utilities. */ - HosRecursiveMutex &GetUserSessionMutex(); - HosRecursiveMutex &GetMitmSessionMutex(); + os::RecursiveMutex &GetUserSessionMutex(); + os::RecursiveMutex &GetMitmSessionMutex(); template Result DoWithUserSession(F f) { - std::scoped_lock lk(GetUserSessionMutex()); + std::scoped_lock lk(GetUserSessionMutex()); { R_ASSERT(smInitialize()); ON_SCOPE_EXIT { smExit(); }; @@ -41,7 +41,7 @@ namespace sts::sm::impl { template Result DoWithMitmSession(F f) { - std::scoped_lock lk(GetMitmSessionMutex()); + std::scoped_lock lk(GetMitmSessionMutex()); { R_ASSERT(smAtmosphereMitmInitialize()); ON_SCOPE_EXIT { smAtmosphereMitmExit(); }; diff --git a/stratosphere/libstratosphere/source/utilities.cpp b/stratosphere/libstratosphere/source/utilities.cpp index 1494dd03f..af8d221d8 100644 --- a/stratosphere/libstratosphere/source/utilities.cpp +++ b/stratosphere/libstratosphere/source/utilities.cpp @@ -17,14 +17,8 @@ #include #include -static HosRecursiveMutex g_sm_session_lock; -static HosRecursiveMutex g_sm_mitm_session_lock; +static sts::os::RecursiveMutex g_sm_session_lock; - -HosRecursiveMutex &GetSmSessionMutex() { +sts::os::RecursiveMutex &GetSmSessionMutex() { return g_sm_session_lock; } - -HosRecursiveMutex &GetSmMitmSessionMutex() { - return g_sm_mitm_session_lock; -} diff --git a/stratosphere/pm/source/impl/pm_process_info.hpp b/stratosphere/pm/source/impl/pm_process_info.hpp index 5be9f3bc4..10d060944 100644 --- a/stratosphere/pm/source/impl/pm_process_info.hpp +++ b/stratosphere/pm/source/impl/pm_process_info.hpp @@ -171,7 +171,7 @@ namespace sts::pm::impl { class ProcessList final { private: - HosMutex lock; + os::Mutex lock; std::vector> processes; public: void Lock() { diff --git a/stratosphere/pm/source/impl/pm_process_manager.cpp b/stratosphere/pm/source/impl/pm_process_manager.cpp index 790bd0949..048fcb7c5 100644 --- a/stratosphere/pm/source/impl/pm_process_manager.cpp +++ b/stratosphere/pm/source/impl/pm_process_manager.cpp @@ -140,7 +140,7 @@ namespace sts::pm::impl { } /* Process Tracking globals. */ - HosThread g_process_track_thread; + os::Thread g_process_track_thread; auto g_process_waitable_manager = WaitableManager(1); /* Process lists. */ @@ -155,7 +155,7 @@ namespace sts::pm::impl { /* Process Launch synchronization globals. */ IEvent *g_process_launch_start_event = CreateWriteOnlySystemEvent(); - HosSignal g_process_launch_finish_signal; + os::Event g_process_launch_finish_event; Result g_process_launch_result = ResultSuccess; LaunchProcessArgs g_process_launch_args = {}; @@ -286,7 +286,7 @@ namespace sts::pm::impl { Result LaunchProcessEventCallback(u64 timeout) { g_process_launch_start_event->Clear(); g_process_launch_result = LaunchProcess(&g_process_launch_args); - g_process_launch_finish_signal.Signal(); + g_process_launch_finish_event.Signal(); return ResultSuccess; } @@ -402,7 +402,7 @@ namespace sts::pm::impl { /* Process Management. */ Result LaunchTitle(u64 *out_process_id, const ncm::TitleLocation &loc, u32 flags) { /* Ensure we only try to launch one title at a time. */ - static HosMutex s_lock; + static os::Mutex s_lock; std::scoped_lock lk(s_lock); /* Set global arguments, signal, wait. */ @@ -411,9 +411,8 @@ namespace sts::pm::impl { .location = loc, .flags = flags, }; - g_process_launch_finish_signal.Reset(); g_process_launch_start_event->Signal(); - g_process_launch_finish_signal.Wait(); + g_process_launch_finish_event.Wait(); return g_process_launch_result; } diff --git a/stratosphere/pm/source/impl/pm_resource_manager.cpp b/stratosphere/pm/source/impl/pm_resource_manager.cpp index 7c625b49b..50798750a 100644 --- a/stratosphere/pm/source/impl/pm_resource_manager.cpp +++ b/stratosphere/pm/source/impl/pm_resource_manager.cpp @@ -45,7 +45,7 @@ namespace sts::pm::resource { constexpr size_t ExtraSystemMemorySizeAtmosphere = 24 * Megabyte; /* Globals. */ - HosMutex g_resource_limit_lock; + os::Mutex g_resource_limit_lock; Handle g_resource_limit_handles[ResourceLimitGroup_Count]; spl::MemoryArrangement g_memory_arrangement = spl::MemoryArrangement_Standard; u64 g_system_memory_boost_size = 0; diff --git a/stratosphere/spl/source/spl_api_impl.cpp b/stratosphere/spl/source/spl_api_impl.cpp index e6f67a5c4..9ecf65f1a 100644 --- a/stratosphere/spl/source/spl_api_impl.cpp +++ b/stratosphere/spl/source/spl_api_impl.cpp @@ -110,7 +110,7 @@ namespace sts::spl::impl { u32 g_se_mapped_work_buffer_addr; u8 __attribute__((aligned(0x1000))) g_work_buffer[2 * WorkBufferSizeMax]; - HosMutex g_async_op_lock; + os::Mutex g_async_op_lock; const void *g_keyslot_owners[MaxAesKeyslots]; BootReasonValue g_boot_reason; @@ -320,7 +320,7 @@ namespace sts::spl::impl { armDCacheFlush(layout, sizeof(*layout)); { - std::scoped_lock lk(g_async_op_lock); + std::scoped_lock lk(g_async_op_lock); smc::AsyncOperationKey op_key; const IvCtr iv_ctr = {}; const u32 mode = smc::GetCryptAesMode(smc::CipherMode::CbcDecrypt, keyslot); @@ -395,7 +395,7 @@ namespace sts::spl::impl { /* Do exp mod operation. */ armDCacheFlush(layout, sizeof(*layout)); { - std::scoped_lock lk(g_async_op_lock); + std::scoped_lock lk(g_async_op_lock); smc::AsyncOperationKey op_key; smc::Result res = smc::SecureExpMod(&op_key, layout->base, layout->mod, mode); @@ -441,7 +441,7 @@ namespace sts::spl::impl { /* Do exp mod operation. */ armDCacheFlush(layout, sizeof(*layout)); { - std::scoped_lock lk(g_async_op_lock); + std::scoped_lock lk(g_async_op_lock); smc::AsyncOperationKey op_key; smc::Result res = smc::UnwrapTitleKey(&op_key, layout->base, layout->mod, label_digest, label_digest_size, smc::GetUnwrapEsKeyOption(type, generation)); @@ -528,7 +528,7 @@ namespace sts::spl::impl { /* Do exp mod operation. */ armDCacheFlush(layout, sizeof(*layout)); { - std::scoped_lock lk(g_async_op_lock); + std::scoped_lock lk(g_async_op_lock); smc::AsyncOperationKey op_key; smc::Result res = smc::ExpMod(&op_key, layout->base, layout->exp, exp_size, layout->mod); @@ -676,7 +676,7 @@ namespace sts::spl::impl { armDCacheFlush(const_cast(src), src_size); armDCacheFlush(dst, dst_size); { - std::scoped_lock lk(g_async_op_lock); + std::scoped_lock lk(g_async_op_lock); smc::AsyncOperationKey op_key; const u32 mode = smc::GetCryptAesMode(smc::CipherMode::Ctr, keyslot); const u32 dst_ll_addr = g_se_mapped_work_buffer_addr + offsetof(SeCryptContext, out);