stratosphere: use SdkMutex/SdkRecursiveMutex over Mutex

This commit is contained in:
Michael Scire 2021-09-29 22:52:50 -07:00
parent a4fe1bb5d8
commit 41ab4c2c68
70 changed files with 188 additions and 645 deletions

View file

@ -92,9 +92,9 @@ namespace ams::fs {
FileHandle handle; FileHandle handle;
bool close_file; bool close_file;
s64 size; s64 size;
os::Mutex mutex; os::SdkMutex mutex;
public: public:
constexpr explicit FileHandleStorage(FileHandle handle, bool close_file) : handle(handle), close_file(close_file), size(InvalidSize), mutex(false) { /* ... */ } constexpr explicit FileHandleStorage(FileHandle handle, bool close_file) : handle(handle), close_file(close_file), size(InvalidSize), mutex() { /* ... */ }
constexpr explicit FileHandleStorage(FileHandle handle) : FileHandleStorage(handle, false) { /* ... */ } constexpr explicit FileHandleStorage(FileHandle handle) : FileHandleStorage(handle, false) { /* ... */ }
virtual ~FileHandleStorage() override { virtual ~FileHandleStorage() override {

View file

@ -42,11 +42,11 @@ namespace ams::fssrv {
class PeakCheckableMemoryResourceFromExpHeap : public ams::MemoryResource { class PeakCheckableMemoryResourceFromExpHeap : public ams::MemoryResource {
private: private:
lmem::HeapHandle heap_handle; lmem::HeapHandle heap_handle;
os::Mutex mutex; os::SdkMutex mutex;
size_t peak_free_size; size_t peak_free_size;
size_t current_free_size; size_t current_free_size;
public: public:
constexpr explicit PeakCheckableMemoryResourceFromExpHeap(size_t heap_size) : heap_handle(nullptr), mutex(false), peak_free_size(heap_size), current_free_size(heap_size) { /* ... */ } constexpr explicit PeakCheckableMemoryResourceFromExpHeap(size_t heap_size) : heap_handle(nullptr), mutex(), peak_free_size(heap_size), current_free_size(heap_size) { /* ... */ }
void SetHeapHandle(lmem::HeapHandle handle) { void SetHeapHandle(lmem::HeapHandle handle) {
this->heap_handle = handle; this->heap_handle = handle;
@ -57,7 +57,7 @@ namespace ams::fssrv {
void ClearPeak() { this->peak_free_size = this->current_free_size; } void ClearPeak() { this->peak_free_size = this->current_free_size; }
std::scoped_lock<os::Mutex> GetScopedLock() { std::scoped_lock<os::SdkMutex> GetScopedLock() {
return std::scoped_lock(this->mutex); return std::scoped_lock(this->mutex);
} }

View file

@ -192,7 +192,7 @@ namespace ams::fssystem {
size_t peak_free_size; size_t peak_free_size;
size_t peak_total_allocatable_size; size_t peak_total_allocatable_size;
size_t retried_count; size_t retried_count;
mutable os::Mutex mutex; mutable os::SdkRecursiveMutex mutex;
public: public:
static constexpr size_t QueryWorkBufferSize(s32 max_cache_count, s32 max_order) { static constexpr size_t QueryWorkBufferSize(s32 max_cache_count, s32 max_order) {
const auto buddy_size = FileSystemBuddyHeap::QueryWorkBufferSize(max_order); const auto buddy_size = FileSystemBuddyHeap::QueryWorkBufferSize(max_order);
@ -200,7 +200,7 @@ namespace ams::fssystem {
return buddy_size + table_size; return buddy_size + table_size;
} }
public: public:
FileSystemBufferManager() : total_size(), peak_free_size(), peak_total_allocatable_size(), retried_count(), mutex(true) { /* ... */ } FileSystemBufferManager() : total_size(), peak_free_size(), peak_total_allocatable_size(), retried_count(), mutex() { /* ... */ }
virtual ~FileSystemBufferManager() { /* ... */ } virtual ~FileSystemBufferManager() { /* ... */ }

View file

@ -33,7 +33,7 @@ namespace ams::fssystem {
char key[2][KeySize]; char key[2][KeySize];
char iv[IvSize]; char iv[IvSize];
const size_t block_size; const size_t block_size;
os::Mutex mutex; os::SdkMutex mutex;
public: public:
AesXtsStorage(IStorage *base, const void *key1, const void *key2, size_t key_size, const void *iv, size_t iv_size, size_t block_size); AesXtsStorage(IStorage *base, const void *key1, const void *key2, size_t key_size, const void *iv, size_t iv_size, size_t block_size);

View file

@ -34,7 +34,7 @@ namespace ams::fssystem {
virtual ~DirectoryRedirectionFileSystem(); virtual ~DirectoryRedirectionFileSystem();
protected: protected:
inline util::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const { inline util::optional<std::scoped_lock<os::SdkMutex>> GetAccessorLock() const {
/* No accessor lock is needed. */ /* No accessor lock is needed. */
return util::nullopt; return util::nullopt;
} }

View file

@ -24,7 +24,7 @@ namespace ams::fssystem {
using PathResolutionFileSystem = impl::IPathResolutionFileSystem<DirectorySaveDataFileSystem>; using PathResolutionFileSystem = impl::IPathResolutionFileSystem<DirectorySaveDataFileSystem>;
friend class impl::IPathResolutionFileSystem<DirectorySaveDataFileSystem>; friend class impl::IPathResolutionFileSystem<DirectorySaveDataFileSystem>;
private: private:
os::Mutex accessor_mutex; os::SdkMutex accessor_mutex;
s32 open_writable_files; s32 open_writable_files;
public: public:
DirectorySaveDataFileSystem(std::shared_ptr<fs::fsa::IFileSystem> fs); DirectorySaveDataFileSystem(std::shared_ptr<fs::fsa::IFileSystem> fs);
@ -33,9 +33,9 @@ namespace ams::fssystem {
virtual ~DirectorySaveDataFileSystem(); virtual ~DirectorySaveDataFileSystem();
protected: protected:
inline util::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() { inline util::optional<std::scoped_lock<os::SdkMutex>> GetAccessorLock() {
/* We have a real accessor lock that we want to use. */ /* We have a real accessor lock that we want to use. */
return util::make_optional<std::scoped_lock<os::Mutex>>(this->accessor_mutex); return util::make_optional<std::scoped_lock<os::SdkMutex>>(this->accessor_mutex);
} }
private: private:
Result AllocateWorkBuffer(std::unique_ptr<u8[]> *out, size_t *out_size, size_t ideal_size); Result AllocateWorkBuffer(std::unique_ptr<u8[]> *out, size_t *out_size, size_t ideal_size);

View file

@ -30,11 +30,11 @@ namespace ams::fssystem {
private: private:
save::HierarchicalIntegrityVerificationStorage integrity_storage; save::HierarchicalIntegrityVerificationStorage integrity_storage;
save::FileSystemBufferManagerSet buffers; save::FileSystemBufferManagerSet buffers;
os::Mutex mutex; os::SdkRecursiveMutex mutex;
Hash master_hash; Hash master_hash;
std::unique_ptr<fs::MemoryStorage> master_hash_storage; std::unique_ptr<fs::MemoryStorage> master_hash_storage;
public: public:
IntegrityRomFsStorage() : mutex(true) { /* ... */ } IntegrityRomFsStorage() : mutex() { /* ... */ }
virtual ~IntegrityRomFsStorage() override { this->Finalize(); } virtual ~IntegrityRomFsStorage() override { this->Finalize(); }
Result Initialize(save::HierarchicalIntegrityVerificationInformation level_hash_info, Hash master_hash, save::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation storage_info, IBufferManager *bm); Result Initialize(save::HierarchicalIntegrityVerificationInformation level_hash_info, Hash master_hash, save::HierarchicalIntegrityVerificationStorage::HierarchicalStorageInformation storage_info, IBufferManager *bm);

View file

@ -32,7 +32,7 @@ namespace ams::fssystem {
virtual ~SubDirectoryFileSystem(); virtual ~SubDirectoryFileSystem();
protected: protected:
inline util::optional<std::scoped_lock<os::Mutex>> GetAccessorLock() const { inline util::optional<std::scoped_lock<os::SdkMutex>> GetAccessorLock() const {
/* No accessor lock is needed. */ /* No accessor lock is needed. */
return util::nullopt; return util::nullopt;
} }

View file

@ -62,7 +62,7 @@ namespace ams::fssystem::save {
}; };
private: private:
IBufferManager *buffer_manager; IBufferManager *buffer_manager;
os::Mutex *mutex; os::SdkRecursiveMutex *mutex;
std::unique_ptr<CacheEntry[], ::ams::fs::impl::Deleter> entries; std::unique_ptr<CacheEntry[], ::ams::fs::impl::Deleter> entries;
IStorage *data_storage; IStorage *data_storage;
Result last_result; Result last_result;
@ -78,7 +78,7 @@ namespace ams::fssystem::save {
BlockCacheBufferedStorage(); BlockCacheBufferedStorage();
virtual ~BlockCacheBufferedStorage() override; virtual ~BlockCacheBufferedStorage() override;
Result Initialize(IBufferManager *bm, os::Mutex *mtx, IStorage *data, s64 data_size, size_t verif_block_size, s32 max_cache_entries, bool is_real_data, s8 buffer_level, bool is_keep_burst_mode, fs::StorageType storage_type); Result Initialize(IBufferManager *bm, os::SdkRecursiveMutex *mtx, IStorage *data, s64 data_size, size_t verif_block_size, s32 max_cache_entries, bool is_real_data, s8 buffer_level, bool is_keep_burst_mode, fs::StorageType storage_type);
void Finalize(); void Finalize();
virtual Result Read(s64 offset, void *buffer, size_t size) override; virtual Result Read(s64 offset, void *buffer, size_t size) override;

View file

@ -38,7 +38,7 @@ namespace ams::fssystem::save {
s32 cache_count; s32 cache_count;
Cache *next_acquire_cache; Cache *next_acquire_cache;
Cache *next_fetch_cache; Cache *next_fetch_cache;
os::Mutex mutex; os::SdkMutex mutex;
bool bulk_read_enabled; bool bulk_read_enabled;
public: public:
BufferedStorage(); BufferedStorage();

View file

@ -147,7 +147,7 @@ namespace ams::fssystem::save {
} }
private: private:
FileSystemBufferManagerSet *buffers; FileSystemBufferManagerSet *buffers;
os::Mutex *mutex; os::SdkRecursiveMutex *mutex;
IntegrityVerificationStorage verify_storages[MaxLayers - 1]; IntegrityVerificationStorage verify_storages[MaxLayers - 1];
BlockCacheBufferedStorage buffer_storages[MaxLayers - 1]; BlockCacheBufferedStorage buffer_storages[MaxLayers - 1];
s64 data_size; s64 data_size;
@ -157,7 +157,7 @@ namespace ams::fssystem::save {
HierarchicalIntegrityVerificationStorage() : buffers(nullptr), mutex(nullptr), data_size(-1), is_written_for_rollback(false) { /* ... */ } HierarchicalIntegrityVerificationStorage() : buffers(nullptr), mutex(nullptr), data_size(-1), is_written_for_rollback(false) { /* ... */ }
virtual ~HierarchicalIntegrityVerificationStorage() override { this->Finalize(); } virtual ~HierarchicalIntegrityVerificationStorage() override { this->Finalize(); }
Result Initialize(const HierarchicalIntegrityVerificationInformation &info, HierarchicalStorageInformation storage, FileSystemBufferManagerSet *bufs, os::Mutex *mtx, fs::StorageType storage_type); Result Initialize(const HierarchicalIntegrityVerificationInformation &info, HierarchicalStorageInformation storage, FileSystemBufferManagerSet *bufs, os::SdkRecursiveMutex *mtx, fs::StorageType storage_type);
void Finalize(); void Finalize();
virtual Result Read(s64 offset, void *buffer, size_t size) override; virtual Result Read(s64 offset, void *buffer, size_t size) override;

View file

@ -63,14 +63,14 @@ namespace ams::kvdb {
bool Contains(const void *key, size_t key_size); bool Contains(const void *key, size_t key_size);
}; };
private: private:
os::Mutex lock; os::SdkMutex lock;
Path dir_path; Path dir_path;
Cache cache; Cache cache;
private: private:
Path GetPath(const void *key, size_t key_size); Path GetPath(const void *key, size_t key_size);
Result GetKey(size_t *out_size, void *out_key, size_t max_out_size, const FileName &file_name); Result GetKey(size_t *out_size, void *out_key, size_t max_out_size, const FileName &file_name);
public: public:
FileKeyValueStore() : lock(false) { /* ... */ } FileKeyValueStore() : lock() { /* ... */ }
/* Basic accessors. */ /* Basic accessors. */
Result Initialize(const char *dir); Result Initialize(const char *dir);

View file

@ -85,7 +85,7 @@ namespace ams::lmem::impl {
void *heap_start; void *heap_start;
void *heap_end; void *heap_end;
os::MutexType mutex; os::SdkMutexType mutex;
u8 option; u8 option;
ImplementationHeapHead impl_head; ImplementationHeapHead impl_head;
}; };

View file

@ -28,7 +28,7 @@ namespace ams::lr {
sf::SharedPointer<IRegisteredLocationResolver> registered_location_resolver = nullptr; sf::SharedPointer<IRegisteredLocationResolver> registered_location_resolver = nullptr;
sf::SharedPointer<IAddOnContentLocationResolver> add_on_content_location_resolver = nullptr; sf::SharedPointer<IAddOnContentLocationResolver> add_on_content_location_resolver = nullptr;
os::Mutex mutex{false}; os::SdkMutex mutex{};
public: public:
/* Actual commands. */ /* Actual commands. */
Result OpenLocationResolver(sf::Out<sf::SharedPointer<ILocationResolver>> out, ncm::StorageId storage_id); Result OpenLocationResolver(sf::Out<sf::SharedPointer<ILocationResolver>> out, ncm::StorageId storage_id);

View file

@ -102,7 +102,7 @@ namespace ams::ncm {
ContentMetaDatabaseRoot() { /* ... */ } ContentMetaDatabaseRoot() { /* ... */ }
}; };
private: private:
os::Mutex mutex; os::SdkRecursiveMutex mutex;
bool initialized; bool initialized;
ContentStorageRoot content_storage_roots[MaxContentStorageRoots]; ContentStorageRoot content_storage_roots[MaxContentStorageRoots];
ContentMetaDatabaseRoot content_meta_database_roots[MaxContentMetaDatabaseRoots]; ContentMetaDatabaseRoot content_meta_database_roots[MaxContentMetaDatabaseRoots];
@ -111,8 +111,8 @@ namespace ams::ncm {
RightsIdCache rights_id_cache; RightsIdCache rights_id_cache;
RegisteredHostContent registered_host_content; RegisteredHostContent registered_host_content;
public: public:
ContentManagerImpl() : mutex(true), initialized(false), num_content_storage_entries(0), num_content_meta_entries(0), rights_id_cache(), registered_host_content() { ContentManagerImpl() : mutex(), initialized(false), num_content_storage_entries(0), num_content_meta_entries(0), rights_id_cache(), registered_host_content() {
/* ... */ /* ... */
}; };
~ContentManagerImpl(); ~ContentManagerImpl();
public: public:

View file

@ -86,13 +86,13 @@ namespace ams::ncm {
StorageId install_storage; StorageId install_storage;
InstallTaskDataBase *data; InstallTaskDataBase *data;
InstallProgress progress; InstallProgress progress;
os::Mutex progress_mutex; os::SdkMutex progress_mutex;
u32 config; u32 config;
os::Mutex cancel_mutex; os::SdkMutex cancel_mutex;
bool cancel_requested; bool cancel_requested;
InstallThroughput throughput; InstallThroughput throughput;
TimeSpan throughput_start_time; TimeSpan throughput_start_time;
os::Mutex throughput_mutex; os::SdkMutex throughput_mutex;
FirmwareVariationId firmware_variation_id; FirmwareVariationId firmware_variation_id;
private: private:
ALWAYS_INLINE Result SetLastResultOnFailure(Result result) { ALWAYS_INLINE Result SetLastResultOnFailure(Result result) {
@ -102,7 +102,7 @@ namespace ams::ncm {
return result; return result;
} }
public: public:
InstallTaskBase() : data(), progress(), progress_mutex(false), cancel_mutex(false), cancel_requested(), throughput_mutex(false) { /* ... */ } InstallTaskBase() : data(), progress(), progress_mutex(), cancel_mutex(), cancel_requested(), throughput_mutex() { /* ... */ }
virtual ~InstallTaskBase() { /* ... */ }; virtual ~InstallTaskBase() { /* ... */ };
public: public:
virtual void Cancel(); virtual void Cancel();

View file

@ -40,13 +40,13 @@ namespace ams::ncm {
class HeapState { class HeapState {
private: private:
os::Mutex mutex; os::SdkMutex mutex;
lmem::HeapHandle heap_handle; lmem::HeapHandle heap_handle;
size_t total_alloc_size; size_t total_alloc_size;
size_t peak_total_alloc_size; size_t peak_total_alloc_size;
size_t peak_alloc_size; size_t peak_alloc_size;
public: public:
constexpr HeapState() : mutex(false), heap_handle(nullptr), total_alloc_size(0), peak_total_alloc_size(0), peak_alloc_size(0) { /* ... */ } constexpr HeapState() : mutex(), heap_handle(nullptr), total_alloc_size(0), peak_total_alloc_size(0), peak_alloc_size(0) { /* ... */ }
void Initialize(lmem::HeapHandle heap_handle); void Initialize(lmem::HeapHandle heap_handle);
void Allocate(size_t size); void Allocate(size_t size);

View file

@ -84,7 +84,7 @@ namespace ams::sf::cmif {
private: private:
using EntryList = typename util::IntrusiveListMemberTraits<&Entry::free_list_node>::ListType; using EntryList = typename util::IntrusiveListMemberTraits<&Entry::free_list_node>::ListType;
private: private:
os::Mutex lock; os::SdkMutex lock;
EntryList free_list; EntryList free_list;
Entry *entries; Entry *entries;
size_t num_entries; size_t num_entries;
@ -114,13 +114,13 @@ namespace ams::sf::cmif {
} }
}; };
private: private:
os::Mutex entry_owner_lock; os::SdkMutex entry_owner_lock;
EntryManager entry_manager; EntryManager entry_manager;
private: private:
virtual void *AllocateDomain() = 0; virtual void *AllocateDomain() = 0;
virtual void FreeDomain(void *) = 0; virtual void FreeDomain(void *) = 0;
protected: protected:
ServerDomainManager(DomainEntryStorage *entry_storage, size_t entry_count) : entry_owner_lock(false), entry_manager(entry_storage, entry_count) { /* ... */ } ServerDomainManager(DomainEntryStorage *entry_storage, size_t entry_count) : entry_owner_lock(), entry_manager(entry_storage, entry_count) { /* ... */ }
inline DomainServiceObject *AllocateDomainServiceObject() { inline DomainServiceObject *AllocateDomainServiceObject() {
void *storage = this->AllocateDomain(); void *storage = this->AllocateDomain();

View file

@ -80,9 +80,9 @@ namespace ams::sf::hipc {
os::Event notify_event; os::Event notify_event;
os::WaitableHolderType notify_event_holder; os::WaitableHolderType notify_event_holder;
os::Mutex waitable_selection_mutex; os::SdkMutex waitable_selection_mutex;
os::Mutex waitlist_mutex; os::SdkMutex waitlist_mutex;
os::WaitableManagerType waitlist; os::WaitableManagerType waitlist;
private: private:
virtual void RegisterSessionToWaitList(ServerSession *session) override final; virtual void RegisterSessionToWaitList(ServerSession *session) override final;
@ -192,7 +192,7 @@ namespace ams::sf::hipc {
ServerManagerBase(DomainEntryStorage *entry_storage, size_t entry_count) : ServerManagerBase(DomainEntryStorage *entry_storage, size_t entry_count) :
ServerDomainSessionManager(entry_storage, entry_count), ServerDomainSessionManager(entry_storage, entry_count),
request_stop_event(os::EventClearMode_ManualClear), notify_event(os::EventClearMode_ManualClear), request_stop_event(os::EventClearMode_ManualClear), notify_event(os::EventClearMode_ManualClear),
waitable_selection_mutex(false), waitlist_mutex(false) waitable_selection_mutex(), waitlist_mutex()
{ {
/* Link waitables. */ /* Link waitables. */
os::InitializeWaitableManager(std::addressof(this->waitable_manager)); os::InitializeWaitableManager(std::addressof(this->waitable_manager));
@ -259,7 +259,7 @@ namespace ams::sf::hipc {
using ServerManagerBase::DomainStorage; using ServerManagerBase::DomainStorage;
private: private:
/* Resource storage. */ /* Resource storage. */
os::Mutex resource_mutex; os::SdkMutex resource_mutex;
util::TypedStorage<Server> server_storages[MaxServers]; util::TypedStorage<Server> server_storages[MaxServers];
bool server_allocated[MaxServers]; bool server_allocated[MaxServers];
util::TypedStorage<ServerSession> session_storages[MaxSessions]; util::TypedStorage<ServerSession> session_storages[MaxSessions];
@ -370,7 +370,7 @@ namespace ams::sf::hipc {
return this->GetObjectBySessionIndex(session, this->saved_messages_start, hipc::TlsMessageBufferSize); return this->GetObjectBySessionIndex(session, this->saved_messages_start, hipc::TlsMessageBufferSize);
} }
public: public:
ServerManager() : ServerManagerBase(this->domain_entry_storages, ManagerOptions::MaxDomainObjects), resource_mutex(false) { ServerManager() : ServerManagerBase(this->domain_entry_storages, ManagerOptions::MaxDomainObjects), resource_mutex() {
/* Clear storages. */ /* Clear storages. */
#define SF_SM_MEMCLEAR(obj) if constexpr (sizeof(obj) > 0) { std::memset(obj, 0, sizeof(obj)); } #define SF_SM_MEMCLEAR(obj) if constexpr (sizeof(obj) > 0) { std::memset(obj, 0, sizeof(obj)); }
SF_SM_MEMCLEAR(this->server_storages); SF_SM_MEMCLEAR(this->server_storages);

View file

@ -355,7 +355,7 @@ namespace ams::tipc {
using PortAllocatorTuple = std::tuple<typename PortInfos::Allocator...>; using PortAllocatorTuple = std::tuple<typename PortInfos::Allocator...>;
private: private:
os::Mutex m_mutex; os::SdkRecursiveMutex m_mutex;
os::TlsSlot m_tls_slot; os::TlsSlot m_tls_slot;
PortManagerTuple m_port_managers; PortManagerTuple m_port_managers;
PortAllocatorTuple m_port_allocators; PortAllocatorTuple m_port_allocators;
@ -390,11 +390,11 @@ namespace ams::tipc {
os::StartThread(m_port_threads + Ix); os::StartThread(m_port_threads + Ix);
} }
public: public:
ServerManagerImpl() : m_mutex(true), m_tls_slot(), m_port_managers(), m_port_allocators() { /* ... */ } ServerManagerImpl() : m_mutex(), m_tls_slot(), m_port_managers(), m_port_allocators() { /* ... */ }
os::TlsSlot GetTlsSlot() const { return m_tls_slot; } os::TlsSlot GetTlsSlot() const { return m_tls_slot; }
os::Mutex &GetMutex() { return m_mutex; } os::SdkRecursiveMutex &GetMutex() { return m_mutex; }
void Initialize() { void Initialize() {
/* Initialize our tls slot. */ /* Initialize our tls slot. */

View file

@ -24,10 +24,10 @@ namespace ams::cfg {
constexpr os::ProcessId InitialProcessIdMaxDeprecated = {0x50}; constexpr os::ProcessId InitialProcessIdMaxDeprecated = {0x50};
/* Privileged process globals. */ /* Privileged process globals. */
os::Mutex g_lock(false); constinit os::SdkMutex g_lock;
bool g_got_privileged_process_status = false; constinit bool g_got_privileged_process_status = false;
os::ProcessId g_min_initial_process_id = os::InvalidProcessId, g_max_initial_process_id = os::InvalidProcessId; constinit os::ProcessId g_min_initial_process_id = os::InvalidProcessId, g_max_initial_process_id = os::InvalidProcessId;
os::ProcessId g_cur_process_id = os::InvalidProcessId; constinit os::ProcessId g_cur_process_id = os::InvalidProcessId;
/* SD card helpers. */ /* SD card helpers. */
void GetPrivilegedProcessIdRange(os::ProcessId *out_min, os::ProcessId *out_max) { void GetPrivilegedProcessIdRange(os::ProcessId *out_min, os::ProcessId *out_max) {

View file

@ -29,9 +29,9 @@ namespace ams::cfg {
constexpr size_t NumRequiredServicesForSdCardAccess = util::size(RequiredServicesForSdCardAccess); constexpr size_t NumRequiredServicesForSdCardAccess = util::size(RequiredServicesForSdCardAccess);
/* SD card globals. */ /* SD card globals. */
os::Mutex g_sd_card_lock(false); constinit os::SdkMutex g_sd_card_lock;
bool g_sd_card_initialized = false; constinit bool g_sd_card_initialized = false;
FsFileSystem g_sd_card_filesystem = {}; constinit FsFileSystem g_sd_card_filesystem = {};
/* SD card helpers. */ /* SD card helpers. */
Result CheckSdCardServicesReady() { Result CheckSdCardServicesReady() {

View file

@ -44,8 +44,8 @@ namespace ams::diag {
inline void DebugLog(const char *format, ...) __attribute__((format(printf, 1, 2))); inline void DebugLog(const char *format, ...) __attribute__((format(printf, 1, 2)));
#ifdef AMS_ENABLE_DETAILED_ASSERTIONS #ifdef AMS_ENABLE_DETAILED_ASSERTIONS
os::Mutex g_debug_log_lock(true); constinit os::SdkRecursiveMutex g_debug_log_lock;
char g_debug_buffer[0x400]; constinit char g_debug_buffer[0x400];
void DebugLogImpl(const char *format, ::std::va_list vl) { void DebugLogImpl(const char *format, ::std::va_list vl) {
std::scoped_lock lk(g_debug_log_lock); std::scoped_lock lk(g_debug_log_lock);

View file

@ -60,7 +60,7 @@ namespace ams::fs::impl {
} }
FileSystemAccessor::FileSystemAccessor(const char *n, std::unique_ptr<fsa::IFileSystem> &&fs, std::unique_ptr<fsa::ICommonMountNameGenerator> &&generator) FileSystemAccessor::FileSystemAccessor(const char *n, std::unique_ptr<fsa::IFileSystem> &&fs, std::unique_ptr<fsa::ICommonMountNameGenerator> &&generator)
: impl(std::move(fs)), open_list_lock(false), mount_name_generator(std::move(generator)), : impl(std::move(fs)), open_list_lock(), mount_name_generator(std::move(generator)),
access_log_enabled(false), data_cache_attachable(false), path_cache_attachable(false), path_cache_attached(false), multi_commit_supported(false) access_log_enabled(false), data_cache_attachable(false), path_cache_attachable(false), path_cache_attached(false), multi_commit_supported(false)
{ {
R_ABORT_UNLESS(ValidateMountName(n)); R_ABORT_UNLESS(ValidateMountName(n));

View file

@ -35,7 +35,7 @@ namespace ams::fs::impl {
std::unique_ptr<fsa::IFileSystem> impl; std::unique_ptr<fsa::IFileSystem> impl;
FileList open_file_list; FileList open_file_list;
DirList open_dir_list; DirList open_dir_list;
os::Mutex open_list_lock; os::SdkMutex open_list_lock;
std::unique_ptr<fsa::ICommonMountNameGenerator> mount_name_generator; std::unique_ptr<fsa::ICommonMountNameGenerator> mount_name_generator;
bool access_log_enabled; bool access_log_enabled;
bool data_cache_attachable; bool data_cache_attachable;

View file

@ -26,9 +26,9 @@ namespace ams::fs::impl {
using FileSystemList = util::IntrusiveListBaseTraits<FileSystemAccessor>::ListType; using FileSystemList = util::IntrusiveListBaseTraits<FileSystemAccessor>::ListType;
private: private:
FileSystemList fs_list; FileSystemList fs_list;
os::Mutex mutex; os::SdkMutex mutex;
public: public:
constexpr MountTable() : fs_list(), mutex(false) { /* ... */ } constexpr MountTable() : fs_list(), mutex() { /* ... */ }
private: private:
bool CanAcceptMountName(const char *name); bool CanAcceptMountName(const char *name);
public: public:

View file

@ -17,7 +17,7 @@
namespace ams::fssystem { namespace ams::fssystem {
AesXtsStorage::AesXtsStorage(IStorage *base, const void *key1, const void *key2, size_t key_size, const void *iv, size_t iv_size, size_t block_size) : base_storage(base), block_size(block_size), mutex(false) { AesXtsStorage::AesXtsStorage(IStorage *base, const void *key1, const void *key2, size_t key_size, const void *iv, size_t iv_size, size_t block_size) : base_storage(base), block_size(block_size), mutex() {
AMS_ASSERT(base != nullptr); AMS_ASSERT(base != nullptr);
AMS_ASSERT(key1 != nullptr); AMS_ASSERT(key1 != nullptr);
AMS_ASSERT(key2 != nullptr); AMS_ASSERT(key2 != nullptr);

View file

@ -74,13 +74,13 @@ namespace ams::fssystem {
} }
DirectorySaveDataFileSystem::DirectorySaveDataFileSystem(std::shared_ptr<fs::fsa::IFileSystem> fs) DirectorySaveDataFileSystem::DirectorySaveDataFileSystem(std::shared_ptr<fs::fsa::IFileSystem> fs)
: PathResolutionFileSystem(fs), accessor_mutex(false), open_writable_files(0) : PathResolutionFileSystem(fs), accessor_mutex(), open_writable_files(0)
{ {
/* ... */ /* ... */
} }
DirectorySaveDataFileSystem::DirectorySaveDataFileSystem(std::unique_ptr<fs::fsa::IFileSystem> fs) DirectorySaveDataFileSystem::DirectorySaveDataFileSystem(std::unique_ptr<fs::fsa::IFileSystem> fs)
: PathResolutionFileSystem(std::move(fs)), accessor_mutex(false), open_writable_files(0) : PathResolutionFileSystem(std::move(fs)), accessor_mutex(), open_writable_files(0)
{ {
/* ... */ /* ... */
} }

View file

@ -25,7 +25,7 @@ namespace ams::fssystem {
static constexpr s32 LayerCount = 3; static constexpr s32 LayerCount = 3;
static constexpr size_t HashSize = crypto::Sha256Generator::HashSize; static constexpr size_t HashSize = crypto::Sha256Generator::HashSize;
private: private:
os::Mutex mutex; os::SdkMutex mutex;
IStorage *base_storage; IStorage *base_storage;
s64 base_storage_size; s64 base_storage_size;
char *hash_buffer; char *hash_buffer;
@ -33,7 +33,7 @@ namespace ams::fssystem {
s32 hash_target_block_size; s32 hash_target_block_size;
s32 log_size_ratio; s32 log_size_ratio;
public: public:
HierarchicalSha256Storage() : mutex(false) { /* ... */ } HierarchicalSha256Storage() : mutex() { /* ... */ }
Result Initialize(IStorage **base_storages, s32 layer_count, size_t htbs, void *hash_buf, size_t hash_buf_size); Result Initialize(IStorage **base_storages, s32 layer_count, size_t htbs, void *hash_buf, size_t hash_buf_size);

View file

@ -22,10 +22,10 @@ namespace ams::fssystem {
NON_COPYABLE(KeySlotCacheAccessor); NON_COPYABLE(KeySlotCacheAccessor);
NON_MOVEABLE(KeySlotCacheAccessor); NON_MOVEABLE(KeySlotCacheAccessor);
private: private:
util::unique_lock<os::Mutex> lk; util::unique_lock<os::SdkMutex> lk;
const s32 slot_index; const s32 slot_index;
public: public:
KeySlotCacheAccessor(s32 idx, util::unique_lock<os::Mutex> &&l) : lk(std::move(l)), slot_index(idx) { /* ... */ } KeySlotCacheAccessor(s32 idx, util::unique_lock<os::SdkMutex> &&l) : lk(std::move(l)), slot_index(idx) { /* ... */ }
s32 GetKeySlotIndex() const { return this->slot_index; } s32 GetKeySlotIndex() const { return this->slot_index; }
}; };
@ -64,11 +64,11 @@ namespace ams::fssystem {
private: private:
using KeySlotCacheEntryList = util::IntrusiveListBaseTraits<KeySlotCacheEntry>::ListType; using KeySlotCacheEntryList = util::IntrusiveListBaseTraits<KeySlotCacheEntry>::ListType;
private: private:
os::Mutex mutex; os::SdkMutex mutex;
KeySlotCacheEntryList high_priority_mru_list; KeySlotCacheEntryList high_priority_mru_list;
KeySlotCacheEntryList low_priority_mru_list; KeySlotCacheEntryList low_priority_mru_list;
public: public:
constexpr KeySlotCache() : mutex(false), high_priority_mru_list(), low_priority_mru_list() { /* ... */ } constexpr KeySlotCache() : mutex(), high_priority_mru_list(), low_priority_mru_list() { /* ... */ }
Result AllocateHighPriority(std::unique_ptr<KeySlotCacheAccessor> *out, const void *key, size_t key_size, s32 key2) { Result AllocateHighPriority(std::unique_ptr<KeySlotCacheAccessor> *out, const void *key, size_t key_size, s32 key2) {
return this->AllocateFromLru(out, this->high_priority_mru_list, key, key_size, key2); return this->AllocateFromLru(out, this->high_priority_mru_list, key, key_size, key2);

View file

@ -21,13 +21,12 @@ namespace ams::fssystem {
class AdditionalDeviceAddressEntry { class AdditionalDeviceAddressEntry {
private: private:
/* TODO: SdkMutex */ os::SdkMutex mutex;
os::Mutex mutex;
bool is_registered; bool is_registered;
uintptr_t address; uintptr_t address;
size_t size; size_t size;
public: public:
constexpr AdditionalDeviceAddressEntry() : mutex(false), is_registered(), address(), size() { /* ... */ } constexpr AdditionalDeviceAddressEntry() : mutex(), is_registered(), address(), size() { /* ... */ }
void Register(uintptr_t addr, size_t sz) { void Register(uintptr_t addr, size_t sz) {
std::scoped_lock lk(this->mutex); std::scoped_lock lk(this->mutex);
@ -77,18 +76,17 @@ namespace ams::fssystem {
constexpr size_t HeapAllocatableSizeMax = HeapBlockSize * (static_cast<size_t>(1) << HeapOrderMax); constexpr size_t HeapAllocatableSizeMax = HeapBlockSize * (static_cast<size_t>(1) << HeapOrderMax);
constexpr size_t HeapAllocatableSizeMaxForLarge = HeapBlockSize * (static_cast<size_t>(1) << HeapOrderMaxForLarge); constexpr size_t HeapAllocatableSizeMaxForLarge = HeapBlockSize * (static_cast<size_t>(1) << HeapOrderMaxForLarge);
/* TODO: SdkMutex */ constinit os::SdkMutex g_heap_mutex;
os::Mutex g_heap_mutex(false); constinit FileSystemBuddyHeap g_heap;
FileSystemBuddyHeap g_heap;
std::atomic<size_t> g_retry_count; constinit std::atomic<size_t> g_retry_count;
std::atomic<size_t> g_reduce_allocation_count; constinit std::atomic<size_t> g_reduce_allocation_count;
void *g_heap_buffer; constinit void *g_heap_buffer;
size_t g_heap_size; constinit size_t g_heap_size;
size_t g_heap_free_size_peak; constinit size_t g_heap_free_size_peak;
AdditionalDeviceAddressEntry g_additional_device_address_entry; constinit AdditionalDeviceAddressEntry g_additional_device_address_entry;
} }

View file

@ -25,12 +25,12 @@ namespace ams::fssystem {
private: private:
using BlockCache = LruListCache<s64, char *>; using BlockCache = LruListCache<s64, char *>;
private: private:
os::Mutex mutex; os::SdkMutex mutex;
BlockCache block_cache; BlockCache block_cache;
fs::IStorage * const base_storage; fs::IStorage * const base_storage;
s32 block_size; s32 block_size;
public: public:
ReadOnlyBlockCacheStorage(IStorage *bs, s32 bsz, char *buf, size_t buf_size, s32 cache_block_count) : mutex(false), base_storage(bs), block_size(bsz) { ReadOnlyBlockCacheStorage(IStorage *bs, s32 bsz, char *buf, size_t buf_size, s32 cache_block_count) : mutex(), base_storage(bs), block_size(bsz) {
/* Validate preconditions. */ /* Validate preconditions. */
AMS_ASSERT(buf_size >= static_cast<size_t>(this->block_size)); AMS_ASSERT(buf_size >= static_cast<size_t>(this->block_size));
AMS_ASSERT(util::IsPowerOfTwo(this->block_size)); AMS_ASSERT(util::IsPowerOfTwo(this->block_size));

View file

@ -27,7 +27,7 @@ namespace ams::fssystem::save {
this->Finalize(); this->Finalize();
} }
Result BlockCacheBufferedStorage::Initialize(IBufferManager *bm, os::Mutex *mtx, IStorage *data, s64 data_size, size_t verif_block_size, s32 max_cache_entries, bool is_real_data, s8 buffer_level, bool is_keep_burst_mode, fs::StorageType storage_type) { Result BlockCacheBufferedStorage::Initialize(IBufferManager *bm, os::SdkRecursiveMutex *mtx, IStorage *data, s64 data_size, size_t verif_block_size, s32 max_cache_entries, bool is_real_data, s8 buffer_level, bool is_keep_burst_mode, fs::StorageType storage_type) {
/* Validate preconditions. */ /* Validate preconditions. */
AMS_ASSERT(data != nullptr); AMS_ASSERT(data != nullptr);
AMS_ASSERT(bm != nullptr); AMS_ASSERT(bm != nullptr);

View file

@ -582,7 +582,7 @@ namespace ams::fssystem::save {
} }
}; };
BufferedStorage::BufferedStorage() : base_storage(), buffer_manager(), block_size(), base_storage_size(), caches(), cache_count(), next_acquire_cache(), next_fetch_cache(), mutex(false), bulk_read_enabled() { BufferedStorage::BufferedStorage() : base_storage(), buffer_manager(), block_size(), base_storage_size(), caches(), cache_count(), next_acquire_cache(), next_fetch_cache(), mutex(), bulk_read_enabled() {
/* ... */ /* ... */
} }

View file

@ -150,7 +150,7 @@ namespace ams::fssystem::save {
this->storage = fs::SubStorage(); this->storage = fs::SubStorage();
} }
Result HierarchicalIntegrityVerificationStorage::Initialize(const HierarchicalIntegrityVerificationInformation &info, HierarchicalStorageInformation storage, FileSystemBufferManagerSet *bufs, os::Mutex *mtx, fs::StorageType storage_type) { Result HierarchicalIntegrityVerificationStorage::Initialize(const HierarchicalIntegrityVerificationInformation &info, HierarchicalStorageInformation storage, FileSystemBufferManagerSet *bufs, os::SdkRecursiveMutex *mtx, fs::StorageType storage_type) {
/* Validate preconditions. */ /* Validate preconditions. */
AMS_ASSERT(bufs != nullptr); AMS_ASSERT(bufs != nullptr);
AMS_ASSERT(IntegrityMinLayerCount <= info.max_layers && info.max_layers <= IntegrityMaxLayerCount); AMS_ASSERT(IntegrityMinLayerCount <= info.max_layers && info.max_layers <= IntegrityMaxLayerCount);

View file

@ -20,8 +20,8 @@ namespace ams::hid {
namespace { namespace {
/* Global lock. */ /* Global lock. */
os::Mutex g_hid_lock(false); constinit os::SdkMutex g_hid_lock;
bool g_initialized_hid = false; constinit bool g_initialized_hid = false;
/* Set of supported NpadIds (we want to read from any connected controllers). */ /* Set of supported NpadIds (we want to read from any connected controllers). */
constexpr const HidNpadIdType NpadIdTypes[] = { constexpr const HidNpadIdType NpadIdTypes[] = {

View file

@ -30,13 +30,13 @@ namespace ams::lmem::impl {
public: public:
explicit ScopedHeapLock(HeapHandle h) : handle(h) { explicit ScopedHeapLock(HeapHandle h) : handle(h) {
if (this->handle->option & CreateOption_ThreadSafe) { if (this->handle->option & CreateOption_ThreadSafe) {
os::LockMutex(std::addressof(this->handle->mutex)); os::LockSdkMutex(std::addressof(this->handle->mutex));
} }
} }
~ScopedHeapLock() { ~ScopedHeapLock() {
if (this->handle->option & CreateOption_ThreadSafe) { if (this->handle->option & CreateOption_ThreadSafe) {
os::UnlockMutex(std::addressof(this->handle->mutex)); os::UnlockSdkMutex(std::addressof(this->handle->mutex));
} }
} }
}; };

View file

@ -427,6 +427,7 @@ namespace ams::lmem::impl {
const s32 abs_alignment = std::abs(alignment); const s32 abs_alignment = std::abs(alignment);
AMS_ASSERT((abs_alignment & (abs_alignment - 1)) == 0); AMS_ASSERT((abs_alignment & (abs_alignment - 1)) == 0);
AMS_ASSERT(MinimumAlignment <= static_cast<size_t>(abs_alignment)); AMS_ASSERT(MinimumAlignment <= static_cast<size_t>(abs_alignment));
AMS_UNUSED(abs_alignment);
/* Fix size to be correctly aligned. */ /* Fix size to be correctly aligned. */
if (size == 0) { if (size == 0) {

View file

@ -21,15 +21,12 @@ namespace ams::lmem {
HeapHandle CreateExpHeap(void *address, size_t size, u32 option) { HeapHandle CreateExpHeap(void *address, size_t size, u32 option) {
HeapHandle handle = impl::CreateExpHeap(address, size, option); HeapHandle handle = impl::CreateExpHeap(address, size, option);
if (option & CreateOption_ThreadSafe) { if (option & CreateOption_ThreadSafe) {
os::InitializeMutex(std::addressof(handle->mutex), false, 0); os::InitializeSdkMutex(std::addressof(handle->mutex));
} }
return handle; return handle;
} }
void DestroyExpHeap(HeapHandle handle) { void DestroyExpHeap(HeapHandle handle) {
if (handle->option & CreateOption_ThreadSafe) {
os::FinalizeMutex(std::addressof(handle->mutex));
}
impl::DestroyExpHeap(handle); impl::DestroyExpHeap(handle);
} }

View file

@ -21,7 +21,7 @@ namespace ams::lmem {
HeapHandle CreateUnitHeap(void *address, size_t size, size_t unit_size, u32 option) { HeapHandle CreateUnitHeap(void *address, size_t size, size_t unit_size, u32 option) {
HeapHandle handle = impl::CreateUnitHeap(address, size, unit_size, DefaultAlignment, static_cast<u16>(option), InfoPlacement_Head, nullptr); HeapHandle handle = impl::CreateUnitHeap(address, size, unit_size, DefaultAlignment, static_cast<u16>(option), InfoPlacement_Head, nullptr);
if (option & CreateOption_ThreadSafe) { if (option & CreateOption_ThreadSafe) {
os::InitializeMutex(std::addressof(handle->mutex), false, 0); os::InitializeSdkMutex(std::addressof(handle->mutex));
} }
return handle; return handle;
} }
@ -29,7 +29,7 @@ namespace ams::lmem {
HeapHandle CreateUnitHeap(void *address, size_t size, size_t unit_size, u32 option, s32 alignment, InfoPlacement info_placement) { HeapHandle CreateUnitHeap(void *address, size_t size, size_t unit_size, u32 option, s32 alignment, InfoPlacement info_placement) {
HeapHandle handle = impl::CreateUnitHeap(address, size, unit_size, alignment, static_cast<u16>(option), info_placement, nullptr); HeapHandle handle = impl::CreateUnitHeap(address, size, unit_size, alignment, static_cast<u16>(option), info_placement, nullptr);
if (option & CreateOption_ThreadSafe) { if (option & CreateOption_ThreadSafe) {
os::InitializeMutex(std::addressof(handle->mutex), false, 0); os::InitializeSdkMutex(std::addressof(handle->mutex));
} }
return handle; return handle;
} }
@ -37,15 +37,12 @@ namespace ams::lmem {
HeapHandle CreateUnitHeap(void *address, size_t size, size_t unit_size, u32 option, s32 alignment, HeapCommonHead *heap_head) { HeapHandle CreateUnitHeap(void *address, size_t size, size_t unit_size, u32 option, s32 alignment, HeapCommonHead *heap_head) {
HeapHandle handle = impl::CreateUnitHeap(address, size, unit_size, alignment, static_cast<u16>(option), InfoPlacement_Head, heap_head); HeapHandle handle = impl::CreateUnitHeap(address, size, unit_size, alignment, static_cast<u16>(option), InfoPlacement_Head, heap_head);
if (option & CreateOption_ThreadSafe) { if (option & CreateOption_ThreadSafe) {
os::InitializeMutex(std::addressof(handle->mutex), false, 0); os::InitializeSdkMutex(std::addressof(handle->mutex));
} }
return handle; return handle;
} }
void DestroyUnitHeap(HeapHandle handle) { void DestroyUnitHeap(HeapHandle handle) {
if (handle->option & CreateOption_ThreadSafe) {
os::FinalizeMutex(std::addressof(handle->mutex));
}
impl::DestroyUnitHeap(handle); impl::DestroyUnitHeap(handle);
} }

View file

@ -201,14 +201,14 @@ namespace ams::mem::impl::heap {
s32 static_thread_quota; s32 static_thread_quota;
s32 dynamic_thread_quota; s32 dynamic_thread_quota;
bool use_virtual_memory; bool use_virtual_memory;
os::Mutex lock; os::SdkRecursiveMutex lock;
ListHeader<SpanPage> spanpage_list; ListHeader<SpanPage> spanpage_list;
ListHeader<SpanPage> full_spanpage_list; ListHeader<SpanPage> full_spanpage_list;
ListHeader<Span> freelists[FreeListCount]; ListHeader<Span> freelists[FreeListCount];
FreeListAvailableWord freelists_bitmap[NumFreeListBitmaps]; FreeListAvailableWord freelists_bitmap[NumFreeListBitmaps];
ListHeader<Span> smallmem_lists[TlsHeapStatic::NumClassInfo]; ListHeader<Span> smallmem_lists[TlsHeapStatic::NumClassInfo];
public: public:
TlsHeapCentral() : lock(true) { TlsHeapCentral() : lock() {
this->span_table.total_pages = 0; this->span_table.total_pages = 0;
} }

View file

@ -635,7 +635,7 @@ namespace ams::ncm {
for (s32 i = 0; i < count; i++) { for (s32 i = 0; i < count; i++) {
R_UNLESS(!this->IsCancelRequested(), ncm::ResultCreatePlaceHolderCancelled()); R_UNLESS(!this->IsCancelRequested(), ncm::ResultCreatePlaceHolderCancelled());
static os::Mutex s_placeholder_mutex(false); static constinit os::SdkMutex s_placeholder_mutex;
std::scoped_lock lk(s_placeholder_mutex); std::scoped_lock lk(s_placeholder_mutex);
InstallContentMeta content_meta; InstallContentMeta content_meta;

View file

@ -32,7 +32,7 @@ namespace ams::ncm {
std::array<CacheEntry, MaxCacheEntries> caches; std::array<CacheEntry, MaxCacheEntries> caches;
PathString *root_path; PathString *root_path;
u64 cur_counter; u64 cur_counter;
os::Mutex cache_mutex; os::SdkMutex cache_mutex;
MakePlaceHolderPathFunction make_placeholder_path_func; MakePlaceHolderPathFunction make_placeholder_path_func;
bool delay_flush; bool delay_flush;
private: private:
@ -43,7 +43,7 @@ namespace ams::ncm {
CacheEntry *FindInCache(PlaceHolderId placeholder_id); CacheEntry *FindInCache(PlaceHolderId placeholder_id);
CacheEntry *GetFreeEntry();; CacheEntry *GetFreeEntry();;
public: public:
PlaceHolderAccessor() : cur_counter(0), cache_mutex(false), delay_flush(false) { PlaceHolderAccessor() : cur_counter(0), cache_mutex(), delay_flush(false) {
for (size_t i = 0; i < MaxCacheEntries; i++) { for (size_t i = 0; i < MaxCacheEntries; i++) {
caches[i].id = InvalidPlaceHolderId; caches[i].id = InvalidPlaceHolderId;
} }

View file

@ -31,8 +31,8 @@ namespace ams::patcher {
constexpr size_t ModuleIpsPatchLength = 2 * sizeof(ro::ModuleId) + IpsFileExtensionLength; constexpr size_t ModuleIpsPatchLength = 2 * sizeof(ro::ModuleId) + IpsFileExtensionLength;
/* Global data. */ /* Global data. */
os::Mutex apply_patch_lock(false); constinit os::SdkMutex g_apply_patch_lock;
u8 g_patch_read_buffer[os::MemoryPageSize]; constinit u8 g_patch_read_buffer[os::MemoryPageSize];
/* Helpers. */ /* Helpers. */
inline u8 ConvertHexNybble(const char nybble) { inline u8 ConvertHexNybble(const char nybble) {
@ -213,7 +213,7 @@ namespace ams::patcher {
void LocateAndApplyIpsPatchesToModule(const char *mount_name, const char *patch_dir_name, size_t protected_size, size_t offset, const ro::ModuleId *module_id, u8 *mapped_module, size_t mapped_size) { void LocateAndApplyIpsPatchesToModule(const char *mount_name, const char *patch_dir_name, size_t protected_size, size_t offset, const ro::ModuleId *module_id, u8 *mapped_module, size_t mapped_size) {
/* Ensure only one thread tries to apply patches at a time. */ /* Ensure only one thread tries to apply patches at a time. */
std::scoped_lock lk(apply_patch_lock); std::scoped_lock lk(g_apply_patch_lock);
/* Inspect all patches from /atmosphere/<patch_dir>/<*>/<*>.ips */ /* Inspect all patches from /atmosphere/<patch_dir>/<*>/<*>.ips */
char path[fs::EntryNameLengthMax + 1]; char path[fs::EntryNameLengthMax + 1];

View file

@ -106,7 +106,7 @@ namespace ams::sf::cmif {
return entry->object.Clone(); return entry->object.Clone();
} }
ServerDomainManager::EntryManager::EntryManager(DomainEntryStorage *entry_storage, size_t entry_count) : lock(false) { ServerDomainManager::EntryManager::EntryManager(DomainEntryStorage *entry_storage, size_t entry_count) : lock() {
this->entries = reinterpret_cast<Entry *>(entry_storage); this->entries = reinterpret_cast<Entry *>(entry_storage);
this->num_entries = entry_count; this->num_entries = entry_count;
for (size_t i = 0; i < this->num_entries; i++) { for (size_t i = 0; i < this->num_entries; i++) {

View file

@ -21,17 +21,17 @@ namespace ams::sm::impl {
namespace { namespace {
/* Globals. */ /* Globals. */
constinit os::Mutex g_mitm_ack_session_mutex(true); constinit os::SdkRecursiveMutex g_mitm_ack_session_mutex;
constinit os::Mutex g_per_thread_session_mutex(true); constinit os::SdkRecursiveMutex g_per_thread_session_mutex;
} }
/* Utilities. */ /* Utilities. */
os::Mutex &GetMitmAcknowledgementSessionMutex() { os::SdkRecursiveMutex &GetMitmAcknowledgementSessionMutex() {
return g_mitm_ack_session_mutex; return g_mitm_ack_session_mutex;
} }
os::Mutex &GetPerThreadSessionMutex() { os::SdkRecursiveMutex &GetPerThreadSessionMutex() {
return g_per_thread_session_mutex; return g_per_thread_session_mutex;
} }

View file

@ -21,8 +21,8 @@
namespace ams::sm::impl { namespace ams::sm::impl {
/* Utilities. */ /* Utilities. */
os::Mutex &GetMitmAcknowledgementSessionMutex(); os::SdkRecursiveMutex &GetMitmAcknowledgementSessionMutex();
os::Mutex &GetPerThreadSessionMutex(); os::SdkRecursiveMutex &GetPerThreadSessionMutex();
template<typename F> template<typename F>
Result DoWithMitmAcknowledgementSession(F f) { Result DoWithMitmAcknowledgementSession(F f) {

View file

@ -214,9 +214,9 @@ namespace ams::sdmmc::impl {
bool is_awake; bool is_awake;
public: public:
#if defined(AMS_SDMMC_THREAD_SAFE) #if defined(AMS_SDMMC_THREAD_SAFE)
mutable os::Mutex device_mutex; mutable os::SdkRecursiveMutex device_mutex;
public: public:
BaseDevice() : device_mutex(true) BaseDevice() : device_mutex()
#else #else
BaseDevice() BaseDevice()
#endif #endif

View file

@ -501,18 +501,18 @@ namespace ams::mitm {
crypto::EncryptAes128Ctr(dst, dst_size, entropy.data, crypto::Aes128CtrEncryptor::KeySize, entropy.data + crypto::Aes128CtrEncryptor::KeySize, crypto::Aes128CtrEncryptor::IvSize, dst, dst_size); crypto::EncryptAes128Ctr(dst, dst_size, entropy.data, crypto::Aes128CtrEncryptor::KeySize, entropy.data + crypto::Aes128CtrEncryptor::KeySize, crypto::Aes128CtrEncryptor::IvSize, dst, dst_size);
} }
alignas(os::MemoryPageSize) CalibrationInfo g_calibration_info = {}; alignas(os::MemoryPageSize) constinit CalibrationInfo g_calibration_info = {};
alignas(os::MemoryPageSize) CalibrationInfo g_blank_calibration_info = {}; alignas(os::MemoryPageSize) constinit CalibrationInfo g_blank_calibration_info = {};
alignas(os::MemoryPageSize) SecureCalibrationInfoBackup g_secure_calibration_info_backup = {}; alignas(os::MemoryPageSize) constinit SecureCalibrationInfoBackup g_secure_calibration_info_backup = {};
util::optional<ams::fs::FileStorage> g_prodinfo_backup_file; constinit util::optional<ams::fs::FileStorage> g_prodinfo_backup_file;
util::optional<ams::fs::MemoryStorage> g_blank_prodinfo_storage; constinit util::optional<ams::fs::MemoryStorage> g_blank_prodinfo_storage;
util::optional<ams::fs::MemoryStorage> g_fake_secure_backup_storage; constinit util::optional<ams::fs::MemoryStorage> g_fake_secure_backup_storage;
bool g_allow_writes = false; constinit bool g_allow_writes = false;
bool g_has_secure_backup = false; constinit bool g_has_secure_backup = false;
os::Mutex g_prodinfo_management_lock(false); constinit os::SdkMutex g_prodinfo_management_lock;
} }

View file

@ -22,7 +22,7 @@ namespace ams::mitm::fs {
namespace { namespace {
os::Mutex g_cal0_access_mutex(false); constinit os::SdkMutex g_cal0_access_mutex;
} }
Result CalibrationBinaryStorage::Read(s64 offset, void *_buffer, size_t size) { Result CalibrationBinaryStorage::Read(s64 offset, void *_buffer, size_t size) {

View file

@ -22,9 +22,9 @@ namespace ams::mitm::fs {
namespace { namespace {
os::Mutex g_mq_lock(false); constinit os::SdkMutex g_mq_lock;
bool g_started_req_thread; constinit bool g_started_req_thread;
uintptr_t g_mq_storage[2]; constinit uintptr_t g_mq_storage[2];
os::MessageQueue g_req_mq(g_mq_storage + 0, 1); os::MessageQueue g_req_mq(g_mq_storage + 0, 1);
os::MessageQueue g_ack_mq(g_mq_storage + 1, 1); os::MessageQueue g_ack_mq(g_mq_storage + 1, 1);

View file

@ -258,8 +258,8 @@ namespace ams::mitm::fs {
} }
} }
os::Mutex g_fs_romfs_path_lock(false); constinit os::SdkMutex g_fs_romfs_path_lock;
char g_fs_romfs_path_buffer[fs::EntryNameLengthMax + 1]; constinit char g_fs_romfs_path_buffer[fs::EntryNameLengthMax + 1];
NOINLINE void OpenFileSystemRomfsDirectory(FsDir *out, ncm::ProgramId program_id, BuildDirectoryContext *parent, fs::OpenDirectoryMode mode, FsFileSystem *fs) { NOINLINE void OpenFileSystemRomfsDirectory(FsDir *out, ncm::ProgramId program_id, BuildDirectoryContext *parent, fs::OpenDirectoryMode mode, FsFileSystem *fs) {
std::scoped_lock lk(g_fs_romfs_path_lock); std::scoped_lock lk(g_fs_romfs_path_lock);

View file

@ -23,15 +23,19 @@ namespace ams::mitm::settings {
namespace { namespace {
os::Mutex g_firmware_version_lock(false); constinit os::SdkMutex g_firmware_version_lock;
bool g_cached_firmware_version; constinit bool g_cached_firmware_version;
settings::FirmwareVersion g_firmware_version; constinit settings::FirmwareVersion g_firmware_version;
settings::FirmwareVersion g_ams_firmware_version; constinit settings::FirmwareVersion g_ams_firmware_version;
void CacheFirmwareVersion() { void CacheFirmwareVersion() {
if (AMS_LIKELY(g_cached_firmware_version)) {
return;
}
std::scoped_lock lk(g_firmware_version_lock); std::scoped_lock lk(g_firmware_version_lock);
if (AMS_LIKELY(g_cached_firmware_version)) { if (AMS_UNLIKELY(g_cached_firmware_version)) {
return; return;
} }

View file

@ -20,9 +20,9 @@ namespace ams::mitm::sysupdater {
class SystemUpdateApplyManager { class SystemUpdateApplyManager {
private: private:
os::Mutex apply_mutex; os::SdkMutex apply_mutex;
public: public:
constexpr SystemUpdateApplyManager() : apply_mutex(false) { /* ... */ } constexpr SystemUpdateApplyManager() : apply_mutex() { /* ... */ }
Result ApplyPackageTask(ncm::PackageSystemDowngradeTask *task); Result ApplyPackageTask(ncm::PackageSystemDowngradeTask *task);
}; };

View file

@ -23,8 +23,8 @@ namespace ams::creport {
/* Convenience definitions. */ /* Convenience definitions. */
constexpr size_t MaximumLineLength = 0x20; constexpr size_t MaximumLineLength = 0x20;
os::Mutex g_format_lock(false); constinit os::SdkMutex g_format_lock;
char g_format_buffer[2 * os::MemoryPageSize]; constinit char g_format_buffer[2 * os::MemoryPageSize];
} }

View file

@ -83,7 +83,7 @@ namespace ams::dmnt::cheat::impl {
private: private:
static constexpr size_t ThreadStackSize = 0x4000; static constexpr size_t ThreadStackSize = 0x4000;
private: private:
os::Mutex cheat_lock; os::SdkMutex cheat_lock;
os::Event unsafe_break_event; os::Event unsafe_break_event;
os::Event debug_events_event; /* Autoclear. */ os::Event debug_events_event; /* Autoclear. */
os::ThreadType detect_thread, debug_events_thread; os::ThreadType detect_thread, debug_events_thread;
@ -250,7 +250,7 @@ namespace ams::dmnt::cheat::impl {
} }
public: public:
CheatProcessManager() : cheat_lock(false), unsafe_break_event(os::EventClearMode_ManualClear), debug_events_event(os::EventClearMode_AutoClear), cheat_process_event(os::EventClearMode_AutoClear, true) { CheatProcessManager() : cheat_lock(), unsafe_break_event(os::EventClearMode_ManualClear), debug_events_event(os::EventClearMode_AutoClear), cheat_process_event(os::EventClearMode_AutoClear, true) {
/* Learn whether we should enable cheats by default. */ /* Learn whether we should enable cheats by default. */
{ {
u8 en = 0; u8 en = 0;

View file

@ -14,7 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stratosphere.hpp> #include <stratosphere.hpp>
#include "dmnt_service.hpp"
#include "cheat/dmnt_cheat_service.hpp" #include "cheat/dmnt_cheat_service.hpp"
#include "cheat/impl/dmnt_cheat_api.hpp" #include "cheat/impl/dmnt_cheat_api.hpp"
@ -189,8 +188,6 @@ int main(int argc, char **argv)
ams::dmnt::cheat::impl::InitializeCheatManager(); ams::dmnt::cheat::impl::InitializeCheatManager();
/* Create services. */ /* Create services. */
/* TODO: Implement rest of dmnt:- in ams.tma development branch. */
/* TODO: register debug service */
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_cheat_service.GetShared(), CheatServiceName, CheatMaxSessions)); R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_cheat_service.GetShared(), CheatServiceName, CheatMaxSessions));
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */

View file

@ -1,137 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stratosphere.hpp>
namespace ams::dmnt {
/* TODO: Move into libstratosphere, eventually. */
struct TargetIOFileHandle : sf::LargeData, sf::PrefersMapAliasTransferMode {
u64 value;
constexpr u64 GetValue() const {
return this->value;
}
constexpr explicit operator u64() const {
return this->value;
}
inline constexpr bool operator==(const TargetIOFileHandle &rhs) const {
return this->value == rhs.value;
}
inline constexpr bool operator!=(const TargetIOFileHandle &rhs) const {
return this->value != rhs.value;
}
inline constexpr bool operator<(const TargetIOFileHandle &rhs) const {
return this->value < rhs.value;
}
inline constexpr bool operator<=(const TargetIOFileHandle &rhs) const {
return this->value <= rhs.value;
}
inline constexpr bool operator>(const TargetIOFileHandle &rhs) const {
return this->value > rhs.value;
}
inline constexpr bool operator>=(const TargetIOFileHandle &rhs) const {
return this->value >= rhs.value;
}
};
static_assert(util::is_pod<TargetIOFileHandle>::value && sizeof(TargetIOFileHandle) == sizeof(u64), "TargetIOFileHandle");
/* TODO: Convert to new sf format in the future. */
class DebugMonitorService final {
private:
enum class CommandId {
BreakDebugProcess = 0,
TerminateDebugProcess = 1,
CloseHandle = 2,
LoadImage = 3,
GetProcessId = 4,
GetProcessHandle = 5,
WaitSynchronization = 6,
GetDebugEvent = 7,
GetProcessModuleInfo = 8,
GetProcessList = 9,
GetThreadList = 10,
GetDebugThreadContext = 11,
ContinueDebugEvent = 12,
ReadDebugProcessMemory = 13,
WriteDebugProcessMemory = 14,
SetDebugThreadContext = 15,
GetDebugThreadParam = 16,
InitializeThreadInfo = 17,
SetHardwareBreakPoint = 18,
QueryDebugProcessMemory = 19,
GetProcessMemoryDetails = 20,
AttachByProgramId = 21,
AttachOnLaunch = 22,
GetDebugMonitorProcessId = 23,
GetJitDebugProcessList = 25,
CreateCoreDump = 26,
GetAllDebugThreadInfo = 27,
TargetIO_FileOpen = 29,
TargetIO_FileClose = 30,
TargetIO_FileRead = 31,
TargetIO_FileWrite = 32,
TargetIO_FileSetAttributes = 33,
TargetIO_FileGetInformation = 34,
TargetIO_FileSetTime = 35,
TargetIO_FileSetSize = 36,
TargetIO_FileDelete = 37,
TargetIO_FileMove = 38,
TargetIO_DirectoryCreate = 39,
TargetIO_DirectoryDelete = 40,
TargetIO_DirectoryRename = 41,
TargetIO_DirectoryGetCount = 42,
TargetIO_DirectoryOpen = 43,
TargetIO_DirectoryGetNext = 44,
TargetIO_DirectoryClose = 45,
TargetIO_GetFreeSpace = 46,
TargetIO_GetVolumeInformation = 47,
InitiateCoreDump = 48,
ContinueCoreDump = 49,
AddTTYToCoreDump = 50,
AddImageToCoreDump = 51,
CloseCoreDump = 52,
CancelAttach = 53,
};
private:
Result BreakDebugProcess(Handle debug_hnd);
Result TerminateDebugProcess(Handle debug_hnd);
Result CloseHandle(Handle debug_hnd);
Result GetProcessId(sf::Out<os::ProcessId> out_pid, Handle hnd);
Result GetProcessHandle(sf::Out<Handle> out_hnd, os::ProcessId pid);
Result WaitSynchronization(Handle hnd, u64 ns);
Result TargetIO_FileOpen(sf::Out<TargetIOFileHandle> out_hnd, const sf::InBuffer &path, int open_mode, u32 create_mode);
Result TargetIO_FileClose(TargetIOFileHandle hnd);
Result TargetIO_FileRead(TargetIOFileHandle hnd, const sf::OutNonSecureBuffer &out_data, sf::Out<u32> out_read, s64 offset);
Result TargetIO_FileWrite(TargetIOFileHandle hnd, const sf::InNonSecureBuffer &data, sf::Out<u32> out_written, s64 offset);
Result TargetIO_FileSetAttributes(const sf::InBuffer &path, const sf::InBuffer &attributes);
Result TargetIO_FileGetInformation(const sf::InBuffer &path, const sf::OutArray<u64> &out_info, sf::Out<int> is_directory);
Result TargetIO_FileSetTime(const sf::InBuffer &path, u64 create, u64 access, u64 modify);
Result TargetIO_FileSetSize(const sf::InBuffer &input, s64 size);
Result TargetIO_FileDelete(const sf::InBuffer &path);
Result TargetIO_FileMove(const sf::InBuffer &src_path, const sf::InBuffer &dst_path);
};
}

View file

@ -1,55 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "dmnt_service.hpp"
namespace ams::dmnt {
Result DebugMonitorService::BreakDebugProcess(Handle debug_hnd) {
/* Nintendo discards the output of this command, but we will return it. */
return svcBreakDebugProcess(debug_hnd);
}
Result DebugMonitorService::TerminateDebugProcess(Handle debug_hnd) {
/* Nintendo discards the output of this command, but we will return it. */
return svcTerminateDebugProcess(debug_hnd);
}
Result DebugMonitorService::CloseHandle(Handle debug_hnd) {
/* Nintendo discards the output of this command, but we will return it. */
/* This command is, entertainingly, also pretty unsafe in general... */
return svcCloseHandle(debug_hnd);
}
Result DebugMonitorService::GetProcessId(sf::Out<os::ProcessId> out_pid, Handle hnd) {
/* Nintendo discards the output of this command, but we will return it. */
return os::TryGetProcessId(out_pid.GetPointer(), hnd);
}
Result DebugMonitorService::GetProcessHandle(sf::Out<Handle> out_hnd, os::ProcessId pid) {
R_TRY_CATCH(svcDebugActiveProcess(out_hnd.GetPointer(), static_cast<u64>(pid))) {
R_CONVERT(svc::ResultBusy, dbg::ResultAlreadyAttached());
} R_END_TRY_CATCH;
return ResultSuccess();
}
Result DebugMonitorService::WaitSynchronization(Handle hnd, u64 ns) {
/* Nintendo discards the output of this command, but we will return it. */
return svcWaitSynchronizationSingle(hnd, ns);
}
}

View file

@ -1,259 +0,0 @@
/*
* Copyright (c) 2018-2020 Atmosphère-NX
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stratosphere.hpp>
#include "dmnt_service.hpp"
namespace std {
template<>
struct hash<ams::dmnt::TargetIOFileHandle> {
u64 operator()(ams::dmnt::TargetIOFileHandle const &handle) const noexcept {
return handle.GetValue();
}
};
}
namespace ams::dmnt {
namespace {
enum TIOCreateOption : u32 {
TIOCreateOption_CreateNew = 1,
TIOCreateOption_CreateAlways = 2,
TIOCreateOption_OpenExisting = 3,
TIOCreateOption_OpenAlways = 4,
TIOCreateOption_ResetSize = 5,
};
/* Nintendo uses actual pointers as file handles. We'll add a layer of indirection... */
bool g_sd_initialized = false;
os::Mutex g_sd_lock(false);
FsFileSystem g_sd_fs;
os::Mutex g_file_handle_lock(false);
u64 g_cur_fd;
std::unordered_map<TargetIOFileHandle, FsFile> g_file_handles;
Result EnsureSdInitialized() {
std::scoped_lock lk(g_sd_lock);
R_SUCCEED_IF(g_sd_initialized);
R_TRY(fsOpenSdCardFileSystem(&g_sd_fs));
g_sd_initialized = true;
return ResultSuccess();
}
TargetIOFileHandle GetNewFileHandle(FsFile f) {
std::scoped_lock lk(g_file_handle_lock);
TargetIOFileHandle fd = { .value = g_cur_fd++ };
g_file_handles[fd] = f;
return fd;
}
Result GetFileByHandle(FsFile *out, TargetIOFileHandle handle) {
std::scoped_lock lk(g_file_handle_lock);
if (g_file_handles.find(handle) != g_file_handles.end()) {
*out = g_file_handles[handle];
return ResultSuccess();
}
return fs::ResultInvalidArgument();
}
Result CloseFileByHandle(TargetIOFileHandle handle) {
std::scoped_lock lk(g_file_handle_lock);
if (g_file_handles.find(handle) != g_file_handles.end()) {
fsFileClose(&g_file_handles[handle]);
g_file_handles.erase(handle);
return ResultSuccess();
}
return fs::ResultInvalidArgument();
}
void FixPath(char *dst, size_t dst_size, const sf::InBuffer &path) {
dst[dst_size - 1] = 0;
strncpy(dst, "/", dst_size - 1);
const char *src = reinterpret_cast<const char *>(path.GetPointer());
size_t src_idx = 0;
size_t dst_idx = 1;
while (src_idx < path.GetSize() && (src[src_idx] == '/' || src[src_idx] == '\\')) {
src_idx++;
}
while (src_idx < path.GetSize() && dst_idx < dst_size - 1 && src[src_idx] != 0) {
if (src[src_idx] == '\\') {
dst[dst_idx] = '/';
} else {
dst[dst_idx] = src[src_idx];
}
src_idx++;
dst_idx++;
}
if (dst_idx < dst_size) {
dst[dst_idx] = 0;
}
}
}
Result DebugMonitorService::TargetIO_FileOpen(sf::Out<TargetIOFileHandle> out_hnd, const sf::InBuffer &path, int open_mode, u32 create_mode) {
R_TRY(EnsureSdInitialized());
char fs_path[FS_MAX_PATH];
FixPath(fs_path, sizeof(fs_path), path);
/* Create file as required by mode. */
if (create_mode == TIOCreateOption_CreateAlways) {
fsFsDeleteFile(&g_sd_fs, fs_path);
R_TRY(fsFsCreateFile(&g_sd_fs, fs_path, 0, 0));
} else if (create_mode == TIOCreateOption_CreateNew) {
R_TRY(fsFsCreateFile(&g_sd_fs, fs_path, 0, 0));
} else if (create_mode == TIOCreateOption_OpenAlways) {
fsFsCreateFile(&g_sd_fs, fs_path, 0, 0);
}
/* Open the file, guard to prevent failure to close. */
FsFile f;
R_TRY(fsFsOpenFile(&g_sd_fs, fs_path, open_mode, &f));
auto file_guard = SCOPE_GUARD { fsFileClose(&f); };
/* Set size if needed. */
if (create_mode == TIOCreateOption_ResetSize) {
R_TRY(fsFileSetSize(&f, 0));
}
/* Cancel guard, output file handle. */
file_guard.Cancel();
out_hnd.SetValue(GetNewFileHandle(f));
return ResultSuccess();
}
Result DebugMonitorService::TargetIO_FileClose(TargetIOFileHandle hnd) {
return CloseFileByHandle(hnd);
}
Result DebugMonitorService::TargetIO_FileRead(TargetIOFileHandle hnd, const sf::OutNonSecureBuffer &out_data, sf::Out<u32> out_read, s64 offset) {
FsFile f;
size_t read = 0;
R_TRY(GetFileByHandle(&f, hnd));
R_TRY(fsFileRead(&f, offset, out_data.GetPointer(), out_data.GetSize(), FsReadOption_None, &read));
out_read.SetValue(static_cast<u32>(read));
return ResultSuccess();
}
Result DebugMonitorService::TargetIO_FileWrite(TargetIOFileHandle hnd, const sf::InNonSecureBuffer &data, sf::Out<u32> out_written, s64 offset) {
FsFile f;
R_TRY(GetFileByHandle(&f, hnd));
R_TRY(fsFileWrite(&f, offset, data.GetPointer(), data.GetSize(), FsWriteOption_None));
out_written.SetValue(data.GetSize());
return ResultSuccess();
}
Result DebugMonitorService::TargetIO_FileSetAttributes(const sf::InBuffer &path, const sf::InBuffer &attributes) {
/* I don't really know why this command exists, Horizon doesn't allow you to set any attributes. */
/* N just returns ResultSuccess unconditionally here. */
return ResultSuccess();
}
Result DebugMonitorService::TargetIO_FileGetInformation(const sf::InBuffer &path, const sf::OutArray<u64> &out_info, sf::Out<int> is_directory) {
R_TRY(EnsureSdInitialized());
char fs_path[FS_MAX_PATH];
FixPath(fs_path, sizeof(fs_path), path);
for (size_t i = 0; i < out_info.GetSize(); i++) {
out_info[i] = 0;
}
is_directory.SetValue(0);
FsFile f;
if (R_SUCCEEDED(fsFsOpenFile(&g_sd_fs, fs_path, FsOpenMode_Read, &f))) {
ON_SCOPE_EXIT { fsFileClose(&f); };
/* N doesn't check this return code. */
if (out_info.GetSize() > 0) {
fsFileGetSize(&f, reinterpret_cast<s64 *>(&out_info[0]));
}
/* TODO: N does not call fsFsGetFileTimestampRaw here, but we possibly could. */
} else {
FsDir dir;
R_TRY(fsFsOpenDirectory(&g_sd_fs, fs_path, FsDirOpenMode_ReadFiles | FsDirOpenMode_ReadDirs, &dir));
fsDirClose(&dir);
is_directory.SetValue(1);
}
return ResultSuccess();
}
Result DebugMonitorService::TargetIO_FileSetTime(const sf::InBuffer &path, u64 create, u64 access, u64 modify) {
/* This is another function that doesn't really need to exist, because Horizon doesn't let you set anything. */
return ResultSuccess();
}
Result DebugMonitorService::TargetIO_FileSetSize(const sf::InBuffer &input, s64 size) {
/* Why does this function take in a path and not a file handle? */
R_TRY(EnsureSdInitialized());
/* We will try to be better than N, here. N only treats input as a path. */
FsFile f;
if (input.GetSize() == sizeof(TargetIOFileHandle)) {
R_UNLESS(R_FAILED(GetFileByHandle(&f, *reinterpret_cast<const TargetIOFileHandle *>(input.GetPointer()))), fsFileSetSize(&f, size));
}
char fs_path[FS_MAX_PATH];
FixPath(fs_path, sizeof(fs_path), input);
R_TRY(fsFsOpenFile(&g_sd_fs, fs_path, FsOpenMode_Write, &f));
ON_SCOPE_EXIT { fsFileClose(&f); };
return fsFileSetSize(&f, size);
}
Result DebugMonitorService::TargetIO_FileDelete(const sf::InBuffer &path) {
R_TRY(EnsureSdInitialized());
char fs_path[FS_MAX_PATH];
FixPath(fs_path, sizeof(fs_path), path);
return fsFsDeleteFile(&g_sd_fs, fs_path);
}
Result DebugMonitorService::TargetIO_FileMove(const sf::InBuffer &src_path, const sf::InBuffer &dst_path) {
R_TRY(EnsureSdInitialized());
char fs_src_path[FS_MAX_PATH];
char fs_dst_path[FS_MAX_PATH];
FixPath(fs_src_path, sizeof(fs_src_path), src_path);
FixPath(fs_dst_path, sizeof(fs_dst_path), dst_path);
return fsFsRenameFile(&g_sd_fs, fs_src_path, fs_dst_path);
}
}

View file

@ -18,7 +18,7 @@
namespace ams::fatal::srv { namespace ams::fatal::srv {
FatalEventManager::FatalEventManager() : lock(false) { FatalEventManager::FatalEventManager() : lock() {
/* Just create all the events. */ /* Just create all the events. */
for (size_t i = 0; i < FatalEventManager::NumFatalEvents; i++) { for (size_t i = 0; i < FatalEventManager::NumFatalEvents; i++) {
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(this->events[i]), os::EventClearMode_AutoClear, true)); R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(this->events[i]), os::EventClearMode_AutoClear, true));

View file

@ -24,7 +24,7 @@ namespace ams::fatal::srv {
public: public:
static constexpr size_t NumFatalEvents = 3; static constexpr size_t NumFatalEvents = 3;
private: private:
os::Mutex lock; os::SdkMutex lock;
size_t num_events_gotten = 0; size_t num_events_gotten = 0;
os::SystemEventType events[NumFatalEvents]; os::SystemEventType events[NumFatalEvents];
public: public:

View file

@ -23,8 +23,8 @@ namespace ams::fatal::srv {
/* Convenience definitions. */ /* Convenience definitions. */
constexpr size_t MaximumLineLength = 0x20; constexpr size_t MaximumLineLength = 0x20;
os::Mutex g_format_lock(false); constinit os::SdkMutex g_format_lock;
char g_format_buffer[2 * os::MemoryPageSize]; constinit char g_format_buffer[2 * os::MemoryPageSize];
} }

View file

@ -20,7 +20,7 @@ namespace ams::ldr {
namespace { namespace {
os::Mutex g_scoped_code_mount_lock(false); constinit os::SdkMutex g_scoped_code_mount_lock;
} }

View file

@ -23,7 +23,7 @@ namespace ams::ldr {
NON_COPYABLE(ScopedCodeMount); NON_COPYABLE(ScopedCodeMount);
NON_MOVEABLE(ScopedCodeMount); NON_MOVEABLE(ScopedCodeMount);
private: private:
std::scoped_lock<os::Mutex> lk; std::scoped_lock<os::SdkMutex> lk;
cfg::OverrideStatus override_status; cfg::OverrideStatus override_status;
fs::CodeVerificationData ams_code_verification_data; fs::CodeVerificationData ams_code_verification_data;
fs::CodeVerificationData sd_or_base_code_verification_data; fs::CodeVerificationData sd_or_base_code_verification_data;

View file

@ -167,9 +167,9 @@ namespace ams::pm::impl {
class ProcessList final : public util::IntrusiveListMemberTraits<&ProcessInfo::list_node>::ListType { class ProcessList final : public util::IntrusiveListMemberTraits<&ProcessInfo::list_node>::ListType {
private: private:
os::Mutex lock; os::SdkMutex lock;
public: public:
constexpr ProcessList() : lock(false) { /* ... */ } constexpr ProcessList() : lock() { /* ... */ }
void Lock() { void Lock() {
this->lock.Lock(); this->lock.Lock();

View file

@ -78,18 +78,15 @@ namespace ams::pm::impl {
NON_MOVEABLE(ProcessInfoAllocator); NON_MOVEABLE(ProcessInfoAllocator);
static_assert(MaxProcessInfos >= 0x40, "MaxProcessInfos is too small."); static_assert(MaxProcessInfos >= 0x40, "MaxProcessInfos is too small.");
private: private:
util::TypedStorage<ProcessInfo> process_info_storages[MaxProcessInfos]; util::TypedStorage<ProcessInfo> process_info_storages[MaxProcessInfos]{};
bool process_info_allocated[MaxProcessInfos]; bool process_info_allocated[MaxProcessInfos]{};
os::Mutex lock; os::SdkMutex lock{};
private: private:
constexpr inline size_t GetProcessInfoIndex(ProcessInfo *process_info) const { constexpr inline size_t GetProcessInfoIndex(ProcessInfo *process_info) const {
return process_info - GetPointer(this->process_info_storages[0]); return process_info - GetPointer(this->process_info_storages[0]);
} }
public: public:
constexpr ProcessInfoAllocator() : lock(false) { constexpr ProcessInfoAllocator() = default;
std::memset(this->process_info_storages, 0, sizeof(this->process_info_storages));
std::memset(this->process_info_allocated, 0, sizeof(this->process_info_allocated));
}
template<typename... Args> template<typename... Args>
ProcessInfo *AllocateProcessInfo(Args &&... args) { ProcessInfo *AllocateProcessInfo(Args &&... args) {
@ -123,34 +120,34 @@ namespace ams::pm::impl {
/* Process Tracking globals. */ /* Process Tracking globals. */
void ProcessTrackingMain(void *arg); void ProcessTrackingMain(void *arg);
os::ThreadType g_process_track_thread; constinit os::ThreadType g_process_track_thread;
alignas(os::ThreadStackAlignment) u8 g_process_track_thread_stack[16_KB]; alignas(os::ThreadStackAlignment) constinit u8 g_process_track_thread_stack[16_KB];
/* Process lists. */ /* Process lists. */
ProcessList g_process_list; constinit ProcessList g_process_list;
ProcessList g_dead_process_list; constinit ProcessList g_dead_process_list;
/* Process Info Allocation. */ /* Process Info Allocation. */
/* Note: The kernel slabheap is size 0x50 -- we allow slightly larger to account for the dead process list. */ /* Note: The kernel slabheap is size 0x50 -- we allow slightly larger to account for the dead process list. */
constexpr size_t MaxProcessCount = 0x60; constexpr size_t MaxProcessCount = 0x60;
ProcessInfoAllocator<MaxProcessCount> g_process_info_allocator; constinit ProcessInfoAllocator<MaxProcessCount> g_process_info_allocator;
/* Global events. */ /* Global events. */
os::SystemEventType g_process_event; constinit os::SystemEventType g_process_event;
os::SystemEventType g_hook_to_create_process_event; constinit os::SystemEventType g_hook_to_create_process_event;
os::SystemEventType g_hook_to_create_application_process_event; constinit os::SystemEventType g_hook_to_create_application_process_event;
os::SystemEventType g_boot_finished_event; constinit os::SystemEventType g_boot_finished_event;
/* Process Launch synchronization globals. */ /* Process Launch synchronization globals. */
os::Mutex g_launch_program_lock(false); constinit os::SdkMutex g_launch_program_lock;
os::Event g_process_launch_start_event(os::EventClearMode_AutoClear); os::Event g_process_launch_start_event(os::EventClearMode_AutoClear);
os::Event g_process_launch_finish_event(os::EventClearMode_AutoClear); os::Event g_process_launch_finish_event(os::EventClearMode_AutoClear);
Result g_process_launch_result = ResultSuccess(); constinit Result g_process_launch_result = ResultSuccess();
LaunchProcessArgs g_process_launch_args = {}; constinit LaunchProcessArgs g_process_launch_args = {};
/* Hook globals. */ /* Hook globals. */
std::atomic<ncm::ProgramId> g_program_id_hook; constinit std::atomic<ncm::ProgramId> g_program_id_hook;
std::atomic<bool> g_application_hook; constinit std::atomic<bool> g_application_hook;
/* Forward declarations. */ /* Forward declarations. */
Result LaunchProcess(os::WaitableManagerType &waitable_manager, const LaunchProcessArgs &args); Result LaunchProcess(os::WaitableManagerType &waitable_manager, const LaunchProcessArgs &args);

View file

@ -44,13 +44,13 @@ namespace ams::pm::resource {
constexpr size_t ExtraSystemMemorySizeAtmosphere500 = 33_MB; /* Applet pool is 0x20100000 */ constexpr size_t ExtraSystemMemorySizeAtmosphere500 = 33_MB; /* Applet pool is 0x20100000 */
/* Globals. */ /* Globals. */
os::Mutex g_resource_limit_lock(false); constinit os::SdkMutex g_resource_limit_lock;
Handle g_resource_limit_handles[ResourceLimitGroup_Count]; constinit Handle g_resource_limit_handles[ResourceLimitGroup_Count];
spl::MemoryArrangement g_memory_arrangement = spl::MemoryArrangement_Standard; constinit spl::MemoryArrangement g_memory_arrangement = spl::MemoryArrangement_Standard;
u64 g_system_memory_boost_size = 0; constinit u64 g_system_memory_boost_size = 0;
u64 g_extra_application_threads_available = 0; constinit u64 g_extra_application_threads_available = 0;
u64 g_resource_limits[ResourceLimitGroup_Count][svc::LimitableResource_Count] = { constinit u64 g_resource_limits[ResourceLimitGroup_Count][svc::LimitableResource_Count] = {
[ResourceLimitGroup_System] = { [ResourceLimitGroup_System] = {
[svc::LimitableResource_PhysicalMemoryMax] = 0, /* Initialized by more complicated logic later. */ [svc::LimitableResource_PhysicalMemoryMax] = 0, /* Initialized by more complicated logic later. */
[svc::LimitableResource_ThreadCountMax] = 508, [svc::LimitableResource_ThreadCountMax] = 508,
@ -74,7 +74,7 @@ namespace ams::pm::resource {
}, },
}; };
u64 g_memory_resource_limits[spl::MemoryArrangement_Count][ResourceLimitGroup_Count] = { constinit u64 g_memory_resource_limits[spl::MemoryArrangement_Count][ResourceLimitGroup_Count] = {
[spl::MemoryArrangement_Standard] = { [spl::MemoryArrangement_Standard] = {
[ResourceLimitGroup_System] = 269_MB, [ResourceLimitGroup_System] = 269_MB,
[ResourceLimitGroup_Application] = 3285_MB, [ResourceLimitGroup_Application] = 3285_MB,

View file

@ -145,7 +145,7 @@ namespace ams::sm::impl {
/* any kind of mutual exclusivity when accessing (and modifying) global state. Previously, this was */ /* any kind of mutual exclusivity when accessing (and modifying) global state. Previously, this was */
/* not a problem, because sm was strictly single-threaded, and so two threads could not race eachother. */ /* not a problem, because sm was strictly single-threaded, and so two threads could not race eachother. */
/* We will add a mutex (and perform locking) in order to prevent simultaneous access to global state. */ /* We will add a mutex (and perform locking) in order to prevent simultaneous access to global state. */
constinit os::Mutex g_mutex{true}; constinit os::SdkRecursiveMutex g_mutex;
constinit std::array<ProcessInfo, ProcessCountMax> g_process_list = [] { constinit std::array<ProcessInfo, ProcessCountMax> g_process_list = [] {
std::array<ProcessInfo, ProcessCountMax> list = {}; std::array<ProcessInfo, ProcessCountMax> list = {};

View file

@ -41,8 +41,8 @@ namespace ams::spl::impl {
constexpr s32 MaxVirtualAesKeySlots = 9; constexpr s32 MaxVirtualAesKeySlots = 9;
/* KeySlot management. */ /* KeySlot management. */
KeySlotCache g_keyslot_cache; constinit KeySlotCache g_keyslot_cache;
util::optional<KeySlotCacheEntry> g_keyslot_cache_entry[MaxPhysicalAesKeySlots]; constinit util::optional<KeySlotCacheEntry> g_keyslot_cache_entry[MaxPhysicalAesKeySlots];
inline s32 GetMaxPhysicalKeySlots() { inline s32 GetMaxPhysicalKeySlots() {
return (hos::GetVersion() >= hos::Version_6_0_0) ? MaxPhysicalAesKeySlots : MaxPhysicalAesKeySlotsDeprecated; return (hos::GetVersion() >= hos::Version_6_0_0) ? MaxPhysicalAesKeySlots : MaxPhysicalAesKeySlotsDeprecated;
@ -96,9 +96,9 @@ namespace ams::spl::impl {
}; };
}; };
const void *g_keyslot_owners[MaxVirtualAesKeySlots]; constinit const void *g_keyslot_owners[MaxVirtualAesKeySlots];
KeySlotContents g_keyslot_contents[MaxVirtualAesKeySlots]; constinit KeySlotContents g_keyslot_contents[MaxVirtualAesKeySlots];
KeySlotContents g_physical_keyslot_contents_for_backwards_compatibility[MaxPhysicalAesKeySlots]; constinit KeySlotContents g_physical_keyslot_contents_for_backwards_compatibility[MaxPhysicalAesKeySlots];
void ClearPhysicalKeySlot(s32 keyslot) { void ClearPhysicalKeySlot(s32 keyslot) {
AMS_ASSERT(IsPhysicalKeySlot(keyslot)); AMS_ASSERT(IsPhysicalKeySlot(keyslot));
@ -237,18 +237,18 @@ namespace ams::spl::impl {
}; };
/* Global variables. */ /* Global variables. */
CtrDrbg g_drbg; constinit CtrDrbg g_drbg;
os::InterruptEventType g_se_event; constinit os::InterruptEventType g_se_event;
os::SystemEventType g_se_keyslot_available_event; constinit os::SystemEventType g_se_keyslot_available_event;
Handle g_se_das_hnd; constinit Handle g_se_das_hnd;
u32 g_se_mapped_work_buffer_addr; constinit u32 g_se_mapped_work_buffer_addr;
alignas(os::MemoryPageSize) u8 g_work_buffer[2 * WorkBufferSizeMax]; alignas(os::MemoryPageSize) constinit u8 g_work_buffer[2 * WorkBufferSizeMax];
os::Mutex g_async_op_lock(false); constinit os::SdkMutex g_async_op_lock;
BootReasonValue g_boot_reason; constinit BootReasonValue g_boot_reason;
bool g_boot_reason_set; constinit bool g_boot_reason_set;
/* Boot Reason accessors. */ /* Boot Reason accessors. */
BootReasonValue GetBootReason() { BootReasonValue GetBootReason() {
@ -505,10 +505,13 @@ namespace ams::spl::impl {
void Initialize() { void Initialize() {
/* Initialize the Drbg. */ /* Initialize the Drbg. */
InitializeCtrDrbg(); InitializeCtrDrbg();
/* Initialize SE interrupt + keyslot events. */ /* Initialize SE interrupt + keyslot events. */
InitializeSeEvents(); InitializeSeEvents();
/* Initialize DAS for the SE. */ /* Initialize DAS for the SE. */
InitializeDeviceAddressSpace(); InitializeDeviceAddressSpace();
/* Initialize the keyslot cache. */ /* Initialize the keyslot cache. */
InitializeKeySlotCache(); InitializeKeySlotCache();
} }