mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
libstrat: namespace hossynch.hpp
This commit is contained in:
parent
73d904036d
commit
bb223eb5ae
57 changed files with 923 additions and 773 deletions
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -145,7 +145,7 @@ Result DirectorySaveDataFileSystem::GetFullPath(char *out, size_t out_size, cons
|
|||
}
|
||||
|
||||
void DirectorySaveDataFileSystem::OnWritableFileClose() {
|
||||
std::scoped_lock<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<IFile> &out_fil
|
|||
FsPath full_path;
|
||||
R_TRY(GetFullPath(full_path, path));
|
||||
|
||||
std::scoped_lock<HosMutex> lk(this->lock);
|
||||
std::scoped_lock lk(this->lock);
|
||||
|
||||
{
|
||||
/* Open the raw file. */
|
||||
|
@ -265,7 +265,7 @@ Result DirectorySaveDataFileSystem::OpenDirectoryImpl(std::unique_ptr<IDirectory
|
|||
FsPath full_path;
|
||||
R_TRY(GetFullPath(full_path, path));
|
||||
|
||||
std::scoped_lock<HosMutex> 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<HosMutex> 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<HosMutex> lk(this->lock);
|
||||
std::scoped_lock lk(this->lock);
|
||||
return this->fs->CleanDirectoryRecursively(full_path);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class DirectorySaveDataFileSystem : public IFileSystem {
|
|||
std::unique_ptr<IFileSystem> unique_fs;
|
||||
std::unique_ptr<IFileSystem> proxy_save_fs;
|
||||
IFileSystem *fs;
|
||||
HosMutex lock;
|
||||
sts::os::Mutex lock;
|
||||
size_t open_writable_files = 0;
|
||||
|
||||
public:
|
||||
|
|
|
@ -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<HosMutex> 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<HosMutex> lk{g_boot0_mutex};
|
||||
std::scoped_lock lk{g_boot0_mutex};
|
||||
|
||||
u8 *buffer = static_cast<u8 *>(_buffer);
|
||||
|
||||
|
|
|
@ -36,11 +36,11 @@
|
|||
|
||||
#include "../debug.hpp"
|
||||
|
||||
static HosMutex g_StorageCacheLock;
|
||||
static sts::os::Mutex g_StorageCacheLock;
|
||||
static std::unordered_map<u64, std::weak_ptr<IStorageInterface>> g_StorageCache;
|
||||
|
||||
static bool StorageCacheGetEntry(sts::ncm::TitleId title_id, std::shared_ptr<IStorageInterface> *out) {
|
||||
std::scoped_lock<HosMutex> lock(g_StorageCacheLock);
|
||||
std::scoped_lock lock(g_StorageCacheLock);
|
||||
if (g_StorageCache.find(static_cast<u64>(title_id)) == g_StorageCache.end()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ static bool StorageCacheGetEntry(sts::ncm::TitleId title_id, std::shared_ptr<ISt
|
|||
}
|
||||
|
||||
static void StorageCacheSetEntry(sts::ncm::TitleId title_id, std::shared_ptr<IStorageInterface> *ptr) {
|
||||
std::scoped_lock<HosMutex> lock(g_StorageCacheLock);
|
||||
std::scoped_lock lock(g_StorageCacheLock);
|
||||
|
||||
/* Ensure we always use the cached copy if present. */
|
||||
if (g_StorageCache.find(static_cast<u64>(title_id)) != g_StorageCache.end()) {
|
||||
|
|
|
@ -64,7 +64,7 @@ bool SetMitmService::IsValidRegionCode(u32 region_code) {
|
|||
}
|
||||
|
||||
Result SetMitmService::EnsureLocale() {
|
||||
std::scoped_lock<HosMutex> lk(this->lock);
|
||||
std::scoped_lock lk(this->lock);
|
||||
|
||||
if (!this->got_locale) {
|
||||
std::memset(&this->locale, 0xCC, sizeof(this->locale));
|
||||
|
|
|
@ -31,7 +31,7 @@ class SetMitmService : public IMitmServiceObject {
|
|||
GetAvailableLanguageCodes = 1,
|
||||
};
|
||||
private:
|
||||
HosMutex lock;
|
||||
sts::os::Mutex lock;
|
||||
OverrideLocale locale;
|
||||
bool got_locale;
|
||||
public:
|
||||
|
|
|
@ -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<HosMutex> lock(g_version_mutex);
|
||||
std::scoped_lock lock(g_version_mutex);
|
||||
|
||||
if (g_got_version) {
|
||||
return;
|
||||
|
|
|
@ -35,7 +35,7 @@ struct SettingsItemValue {
|
|||
std::map<std::string, SettingsItemValue> 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);
|
||||
|
|
|
@ -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<u64> g_mitm_flagged_tids;
|
||||
static std::vector<u64> 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) {
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -132,7 +132,7 @@ namespace sts::i2c::driver {
|
|||
std::abort();
|
||||
}
|
||||
|
||||
std::scoped_lock<HosMutex &> lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx)));
|
||||
std::scoped_lock<os::Mutex &> 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<HosMutex &> lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx)));
|
||||
std::scoped_lock<os::Mutex &> lk(GetResourceManager().GetTransactionMutex(impl::ConvertFromIndex(session.bus_idx)));
|
||||
return GetResourceManager().GetSession(session.session_id).DoTransactionWithRetry(dst, nullptr, size, option, impl::Command::Receive);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
namespace sts::i2c::driver::impl {
|
||||
|
||||
void BusAccessor::Open(Bus bus, SpeedMode speed_mode) {
|
||||
std::scoped_lock<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> lk(this->open_mutex);
|
||||
std::scoped_lock<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> lk(this->register_mutex);
|
||||
std::scoped_lock lk(this->register_mutex);
|
||||
u8 *cur_dst = out_data;
|
||||
size_t remaining = num_bytes;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
namespace sts::i2c::driver::impl {
|
||||
|
||||
void ResourceManager::Initialize() {
|
||||
std::scoped_lock<HosMutex> lk(this->initialize_mutex);
|
||||
std::scoped_lock lk(this->initialize_mutex);
|
||||
this->ref_cnt++;
|
||||
}
|
||||
|
||||
void ResourceManager::Finalize() {
|
||||
std::scoped_lock<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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) {
|
||||
|
|
|
@ -31,14 +31,14 @@ namespace sts::i2c::driver::impl {
|
|||
static constexpr size_t PowerBusId = ConvertToIndex(Bus::I2C5);
|
||||
static constexpr size_t InvalidSessionId = static_cast<size_t>(-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)];
|
||||
}
|
||||
|
||||
|
|
|
@ -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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> lk(this->bus_accessor_mutex);
|
||||
std::scoped_lock lk(this->bus_accessor_mutex);
|
||||
|
||||
if (this->bus_accessor->GetBusy()) {
|
||||
return ResultI2cBusBusy;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<CheatProcessManager *>(_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();
|
||||
|
|
|
@ -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<os::MessageQueue, NumCores> message_queues;
|
||||
std::array<os::Thread, NumCores> 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<void *>(this), 0x1000, 24, i));
|
||||
|
|
|
@ -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<u64, FsFile> g_file_handles;
|
||||
|
||||
Result EnsureSdInitialized() {
|
||||
std::scoped_lock<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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]);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<ITask *>(arg);
|
||||
|
|
|
@ -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<Event *>(&this->context->erpt_event), TimeoutHelper::NsToTick(1'000'000'000ul));
|
||||
eventWait(const_cast<Event *>(&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<Event *>(&this->context->erpt_event), TimeoutHelper::NsToTick(1'000'000'000ul));
|
||||
eventWait(const_cast<Event *>(&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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -53,7 +53,7 @@ class IEvent : public IWaitable {
|
|||
}
|
||||
|
||||
void Clear() {
|
||||
std::scoped_lock<HosMutex> 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<HosMutex> 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. */
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <switch/arm/counter.h>
|
||||
#include <mutex>
|
||||
#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);
|
||||
}
|
||||
};
|
|
@ -17,9 +17,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <switch.h>
|
||||
#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<HosMutex> lock(this->sig_lock);
|
||||
std::scoped_lock lock(this->sig_lock);
|
||||
return this->is_signaled;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#pragma once
|
||||
#include <optional>
|
||||
#include <switch.h>
|
||||
#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:
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include "hossynch.hpp"
|
||||
#include <memory>
|
||||
|
||||
class HosMessageQueue {
|
||||
private:
|
||||
HosMutex queue_lock;
|
||||
HosCondVar cv_not_full;
|
||||
HosCondVar cv_not_empty;
|
||||
std::unique_ptr<uintptr_t[]> buffer;
|
||||
size_t capacity;
|
||||
|
||||
size_t count = 0;
|
||||
size_t offset = 0;
|
||||
public:
|
||||
HosMessageQueue(size_t c) : capacity(c) {
|
||||
this->buffer = std::make_unique<uintptr_t[]>(this->capacity);
|
||||
}
|
||||
|
||||
HosMessageQueue(std::unique_ptr<uintptr_t[]> 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();
|
||||
|
||||
};
|
||||
|
|
@ -15,7 +15,12 @@
|
|||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
|
||||
#include "ipc.hpp"
|
||||
|
||||
#include "services/dmntcht.h"
|
||||
#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"
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#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<uintptr_t[]> 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<uintptr_t[]>(this->capacity);
|
||||
}
|
||||
|
||||
MessageQueue(std::unique_ptr<uintptr_t[]> 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);
|
||||
};
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <mutex>
|
||||
#include <switch.h>
|
||||
#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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
#pragma once
|
||||
#include <switch.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#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<typename F>
|
||||
static void DoWithSmSession(F f) {
|
||||
std::scoped_lock<HosRecursiveMutex &> lk(GetSmSessionMutex());
|
||||
std::scoped_lock lk(GetSmSessionMutex());
|
||||
{
|
||||
R_ASSERT(smInitialize());
|
||||
f();
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <functional>
|
||||
|
||||
#include "results.hpp"
|
||||
#include "os.hpp"
|
||||
#include "waitable_manager_base.hpp"
|
||||
#include "event.hpp"
|
||||
#include "ipc.hpp"
|
||||
|
@ -47,7 +48,7 @@ template<typename ManagerOptions = DefaultManagerOptions>
|
|||
class WaitableManager : public SessionManagerBase {
|
||||
private:
|
||||
/* Domain Manager */
|
||||
HosMutex domain_lock;
|
||||
sts::os::Mutex domain_lock;
|
||||
std::array<uintptr_t, ManagerOptions::MaxDomains> domain_keys;
|
||||
std::array<bool, ManagerOptions::MaxDomains> is_domain_allocated;
|
||||
std::array<DomainEntry, ManagerOptions::MaxDomainObjects> domain_objects;
|
||||
|
@ -58,13 +59,13 @@ class WaitableManager : public SessionManagerBase {
|
|||
std::vector<IWaitable *> 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<bool> 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<HosMutex> lk{this->cur_thread_lock};
|
||||
std::scoped_lock lk{this->cur_thread_lock};
|
||||
this->cur_thread_handle = h;
|
||||
}
|
||||
|
||||
Handle GetProcessingThreadHandle() {
|
||||
std::scoped_lock<HosMutex> lk{this->cur_thread_lock};
|
||||
std::scoped_lock lk{this->cur_thread_lock};
|
||||
return this->cur_thread_handle;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<HosMutex> 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<HosMutex> lk(g_lock);
|
||||
std::scoped_lock lk(g_lock);
|
||||
|
||||
/* If we've not detected, do detection. */
|
||||
if (!g_got_privileged_process_status) {
|
||||
|
|
|
@ -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<HosMutex> 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<HosMutex> lk(g_sd_card_lock);
|
||||
std::scoped_lock lk(g_sd_card_lock);
|
||||
|
||||
InitializeSdCard();
|
||||
}
|
||||
|
|
|
@ -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<HosMutex> lk(g_hid_lock);
|
||||
std::scoped_lock lk(g_hid_lock);
|
||||
|
||||
R_TRY(EnsureHidInitialized());
|
||||
|
||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <mutex>
|
||||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
|
||||
void HosMessageQueue::Send(uintptr_t data) {
|
||||
/* Acquire mutex, wait sendable. */
|
||||
std::scoped_lock<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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];
|
||||
}
|
|
@ -18,8 +18,8 @@
|
|||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
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<HosMutex> lock(g_server_query_mutex);
|
||||
std::scoped_lock lock(g_server_query_mutex);
|
||||
|
||||
const bool exists = g_server_query_manager != nullptr;
|
||||
if (!exists) {
|
||||
|
|
235
stratosphere/libstratosphere/source/os/os_message_queue.cpp
Normal file
235
stratosphere/libstratosphere/source/os/os_message_queue.cpp
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -25,26 +25,26 @@ namespace sts::pm::info {
|
|||
namespace {
|
||||
|
||||
/* Global lock. */
|
||||
HosMutex g_info_lock;
|
||||
os::Mutex g_info_lock;
|
||||
std::set<u64> g_cached_launched_titles;
|
||||
|
||||
}
|
||||
|
||||
/* Information API. */
|
||||
Result GetTitleId(ncm::TitleId *out_title_id, u64 process_id) {
|
||||
std::scoped_lock<HosMutex> lk(g_info_lock);
|
||||
std::scoped_lock lk(g_info_lock);
|
||||
|
||||
return pminfoGetTitleId(reinterpret_cast<u64 *>(out_title_id), process_id);
|
||||
}
|
||||
|
||||
Result GetProcessId(u64 *out_process_id, ncm::TitleId title_id) {
|
||||
std::scoped_lock<HosMutex> lk(g_info_lock);
|
||||
std::scoped_lock lk(g_info_lock);
|
||||
|
||||
return pminfoAtmosphereGetProcessId(out_process_id, static_cast<u64>(title_id));
|
||||
}
|
||||
|
||||
Result WEAK HasLaunchedTitle(bool *out, ncm::TitleId title_id) {
|
||||
std::scoped_lock<HosMutex> lk(g_info_lock);
|
||||
std::scoped_lock lk(g_info_lock);
|
||||
|
||||
if (g_cached_launched_titles.find(static_cast<u64>(title_id)) != g_cached_launched_titles.end()) {
|
||||
*out = true;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
namespace sts::sm::impl {
|
||||
|
||||
/* Utilities. */
|
||||
HosRecursiveMutex &GetUserSessionMutex();
|
||||
HosRecursiveMutex &GetMitmSessionMutex();
|
||||
os::RecursiveMutex &GetUserSessionMutex();
|
||||
os::RecursiveMutex &GetMitmSessionMutex();
|
||||
|
||||
template<typename F>
|
||||
Result DoWithUserSession(F f) {
|
||||
std::scoped_lock<HosRecursiveMutex &> lk(GetUserSessionMutex());
|
||||
std::scoped_lock<os::RecursiveMutex &> lk(GetUserSessionMutex());
|
||||
{
|
||||
R_ASSERT(smInitialize());
|
||||
ON_SCOPE_EXIT { smExit(); };
|
||||
|
@ -41,7 +41,7 @@ namespace sts::sm::impl {
|
|||
|
||||
template<typename F>
|
||||
Result DoWithMitmSession(F f) {
|
||||
std::scoped_lock<HosRecursiveMutex &> lk(GetMitmSessionMutex());
|
||||
std::scoped_lock<os::RecursiveMutex &> lk(GetMitmSessionMutex());
|
||||
{
|
||||
R_ASSERT(smAtmosphereMitmInitialize());
|
||||
ON_SCOPE_EXIT { smAtmosphereMitmExit(); };
|
||||
|
|
|
@ -17,14 +17,8 @@
|
|||
#include <switch.h>
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ namespace sts::pm::impl {
|
|||
|
||||
class ProcessList final {
|
||||
private:
|
||||
HosMutex lock;
|
||||
os::Mutex lock;
|
||||
std::vector<std::shared_ptr<ProcessInfo>> processes;
|
||||
public:
|
||||
void Lock() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<HosMutex> 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<HosMutex> 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<HosMutex> 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<HosMutex> 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<void *>(src), src_size);
|
||||
armDCacheFlush(dst, dst_size);
|
||||
{
|
||||
std::scoped_lock<HosMutex> 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);
|
||||
|
|
Loading…
Reference in a new issue