mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
util::unique_lock, update loader to new sf semantics
This commit is contained in:
parent
3761f80592
commit
e4e278bb3d
9 changed files with 262 additions and 39 deletions
|
@ -42,9 +42,9 @@ namespace ams::fssrv::impl {
|
||||||
private:
|
private:
|
||||||
ams::sf::SharedPointer<FileSystemInterfaceAdapter> parent_filesystem;
|
ams::sf::SharedPointer<FileSystemInterfaceAdapter> parent_filesystem;
|
||||||
std::unique_ptr<fs::fsa::IFile> base_file;
|
std::unique_ptr<fs::fsa::IFile> base_file;
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
public:
|
public:
|
||||||
FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
||||||
~FileInterfaceAdapter();
|
~FileInterfaceAdapter();
|
||||||
private:
|
private:
|
||||||
void InvalidateCache();
|
void InvalidateCache();
|
||||||
|
@ -64,9 +64,9 @@ namespace ams::fssrv::impl {
|
||||||
private:
|
private:
|
||||||
ams::sf::SharedPointer<FileSystemInterfaceAdapter> parent_filesystem;
|
ams::sf::SharedPointer<FileSystemInterfaceAdapter> parent_filesystem;
|
||||||
std::unique_ptr<fs::fsa::IDirectory> base_dir;
|
std::unique_ptr<fs::fsa::IDirectory> base_dir;
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
public:
|
public:
|
||||||
DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema);
|
||||||
~DirectoryInterfaceAdapter();
|
~DirectoryInterfaceAdapter();
|
||||||
public:
|
public:
|
||||||
/* Command API */
|
/* Command API */
|
||||||
|
@ -79,7 +79,7 @@ namespace ams::fssrv::impl {
|
||||||
NON_COPYABLE(FileSystemInterfaceAdapter);
|
NON_COPYABLE(FileSystemInterfaceAdapter);
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<fs::fsa::IFileSystem> base_fs;
|
std::shared_ptr<fs::fsa::IFileSystem> base_fs;
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> mount_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> mount_count_semaphore;
|
||||||
os::ReadWriteLock invalidation_lock;
|
os::ReadWriteLock invalidation_lock;
|
||||||
bool open_count_limited;
|
bool open_count_limited;
|
||||||
bool deep_retry_enabled = false;
|
bool deep_retry_enabled = false;
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace ams::fssrv::impl {
|
||||||
private:
|
private:
|
||||||
/* TODO: Nintendo uses fssystem::AsynchronousAccessStorage here. */
|
/* TODO: Nintendo uses fssystem::AsynchronousAccessStorage here. */
|
||||||
std::shared_ptr<fs::IStorage> base_storage;
|
std::shared_ptr<fs::IStorage> base_storage;
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
os::ReadWriteLock invalidation_lock;
|
os::ReadWriteLock invalidation_lock;
|
||||||
/* TODO: DataStorageContext. */
|
/* TODO: DataStorageContext. */
|
||||||
bool deep_retry_enabled = false;
|
bool deep_retry_enabled = false;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
namespace ams::fssrv::impl {
|
namespace ams::fssrv::impl {
|
||||||
|
|
||||||
FileInterfaceAdapter::FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema)
|
FileInterfaceAdapter::FileInterfaceAdapter(std::unique_ptr<fs::fsa::IFile> &&file, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema)
|
||||||
: parent_filesystem(parent, true), base_file(std::move(file)), open_count_semaphore(std::move(sema))
|
: parent_filesystem(parent, true), base_file(std::move(file)), open_count_semaphore(std::move(sema))
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
|
@ -89,7 +89,7 @@ namespace ams::fssrv::impl {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectoryInterfaceAdapter::DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, std::unique_lock<fssystem::SemaphoreAdapter> &&sema)
|
DirectoryInterfaceAdapter::DirectoryInterfaceAdapter(std::unique_ptr<fs::fsa::IDirectory> &&dir, FileSystemInterfaceAdapter *parent, util::unique_lock<fssystem::SemaphoreAdapter> &&sema)
|
||||||
: parent_filesystem(parent, true), base_dir(std::move(dir)), open_count_semaphore(std::move(sema))
|
: parent_filesystem(parent, true), base_dir(std::move(dir)), open_count_semaphore(std::move(sema))
|
||||||
{
|
{
|
||||||
/* ... */
|
/* ... */
|
||||||
|
@ -236,7 +236,7 @@ namespace ams::fssrv::impl {
|
||||||
Result FileSystemInterfaceAdapter::OpenFile(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode) {
|
Result FileSystemInterfaceAdapter::OpenFile(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IFile>> out, const fssrv::sf::Path &path, u32 mode) {
|
||||||
auto read_lock = this->AcquireCacheInvalidationReadLock();
|
auto read_lock = this->AcquireCacheInvalidationReadLock();
|
||||||
|
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
if (this->open_count_limited) {
|
if (this->open_count_limited) {
|
||||||
/* TODO: This calls into fssrv::FileSystemProxyImpl, which we don't have yet. */
|
/* TODO: This calls into fssrv::FileSystemProxyImpl, which we don't have yet. */
|
||||||
AMS_ABORT_UNLESS(false);
|
AMS_ABORT_UNLESS(false);
|
||||||
|
@ -264,7 +264,7 @@ namespace ams::fssrv::impl {
|
||||||
Result FileSystemInterfaceAdapter::OpenDirectory(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IDirectory>> out, const fssrv::sf::Path &path, u32 mode) {
|
Result FileSystemInterfaceAdapter::OpenDirectory(ams::sf::Out<ams::sf::SharedPointer<fssrv::sf::IDirectory>> out, const fssrv::sf::Path &path, u32 mode) {
|
||||||
auto read_lock = this->AcquireCacheInvalidationReadLock();
|
auto read_lock = this->AcquireCacheInvalidationReadLock();
|
||||||
|
|
||||||
std::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
util::unique_lock<fssystem::SemaphoreAdapter> open_count_semaphore;
|
||||||
if (this->open_count_limited) {
|
if (this->open_count_limited) {
|
||||||
/* TODO: This calls into fssrv::FileSystemProxyImpl, which we don't have yet. */
|
/* TODO: This calls into fssrv::FileSystemProxyImpl, which we don't have yet. */
|
||||||
AMS_ABORT_UNLESS(false);
|
AMS_ABORT_UNLESS(false);
|
||||||
|
|
|
@ -22,10 +22,10 @@ namespace ams::fssystem {
|
||||||
NON_COPYABLE(KeySlotCacheAccessor);
|
NON_COPYABLE(KeySlotCacheAccessor);
|
||||||
NON_MOVEABLE(KeySlotCacheAccessor);
|
NON_MOVEABLE(KeySlotCacheAccessor);
|
||||||
private:
|
private:
|
||||||
std::unique_lock<os::Mutex> lk;
|
util::unique_lock<os::Mutex> lk;
|
||||||
const s32 slot_index;
|
const s32 slot_index;
|
||||||
public:
|
public:
|
||||||
KeySlotCacheAccessor(s32 idx, std::unique_lock<os::Mutex> &&l) : lk(std::move(l)), slot_index(idx) { /* ... */ }
|
KeySlotCacheAccessor(s32 idx, util::unique_lock<os::Mutex> &&l) : lk(std::move(l)), slot_index(idx) { /* ... */ }
|
||||||
|
|
||||||
s32 GetKeySlotIndex() const { return this->slot_index; }
|
s32 GetKeySlotIndex() const { return this->slot_index; }
|
||||||
};
|
};
|
||||||
|
@ -79,7 +79,7 @@ namespace ams::fssystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result Find(std::unique_ptr<KeySlotCacheAccessor> *out, const void *key, size_t key_size, s32 key2) {
|
Result Find(std::unique_ptr<KeySlotCacheAccessor> *out, const void *key, size_t key_size, s32 key2) {
|
||||||
std::unique_lock lk(this->mutex);
|
util::unique_lock lk(this->mutex);
|
||||||
|
|
||||||
KeySlotCacheEntryList *lists[2] = { std::addressof(this->high_priority_mru_list), std::addressof(this->low_priority_mru_list) };
|
KeySlotCacheEntryList *lists[2] = { std::addressof(this->high_priority_mru_list), std::addressof(this->low_priority_mru_list) };
|
||||||
for (auto list : lists) {
|
for (auto list : lists) {
|
||||||
|
@ -100,12 +100,12 @@ namespace ams::fssystem {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddEntry(KeySlotCacheEntry *entry) {
|
void AddEntry(KeySlotCacheEntry *entry) {
|
||||||
std::unique_lock lk(this->mutex);
|
util::unique_lock lk(this->mutex);
|
||||||
this->low_priority_mru_list.push_front(*entry);
|
this->low_priority_mru_list.push_front(*entry);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Result AllocateFromLru(std::unique_ptr<KeySlotCacheAccessor> *out, KeySlotCacheEntryList &dst_list, const void *key, size_t key_size, s32 key2) {
|
Result AllocateFromLru(std::unique_ptr<KeySlotCacheAccessor> *out, KeySlotCacheEntryList &dst_list, const void *key, size_t key_size, s32 key2) {
|
||||||
std::unique_lock lk(this->mutex);
|
util::unique_lock lk(this->mutex);
|
||||||
|
|
||||||
KeySlotCacheEntryList &src_list = this->low_priority_mru_list.empty() ? this->high_priority_mru_list : this->low_priority_mru_list;
|
KeySlotCacheEntryList &src_list = this->low_priority_mru_list.empty() ? this->high_priority_mru_list : this->low_priority_mru_list;
|
||||||
AMS_ASSERT(!src_list.empty());
|
AMS_ASSERT(!src_list.empty());
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <vapours/util/util_overlap.hpp>
|
#include <vapours/util/util_overlap.hpp>
|
||||||
#include <vapours/util/util_string_util.hpp>
|
#include <vapours/util/util_string_util.hpp>
|
||||||
#include <vapours/util/util_string_view.hpp>
|
#include <vapours/util/util_string_view.hpp>
|
||||||
|
#include <vapours/util/util_mutex_utils.hpp>
|
||||||
#include <vapours/util/util_variadic.hpp>
|
#include <vapours/util/util_variadic.hpp>
|
||||||
#include <vapours/util/util_character_encoding.hpp>
|
#include <vapours/util/util_character_encoding.hpp>
|
||||||
#include <vapours/util/util_format_string.hpp>
|
#include <vapours/util/util_format_string.hpp>
|
||||||
|
|
141
libraries/libvapours/include/vapours/util/util_mutex_utils.hpp
Normal file
141
libraries/libvapours/include/vapours/util/util_mutex_utils.hpp
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* 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 <vapours/common.hpp>
|
||||||
|
#include <vapours/assert.hpp>
|
||||||
|
|
||||||
|
namespace ams::util {
|
||||||
|
|
||||||
|
template<typename _Mutex>
|
||||||
|
class unique_lock {
|
||||||
|
NON_COPYABLE(unique_lock);
|
||||||
|
public:
|
||||||
|
using mutex_type = _Mutex;
|
||||||
|
private:
|
||||||
|
mutex_type *m_mutex;
|
||||||
|
bool m_owns;
|
||||||
|
public:
|
||||||
|
unique_lock() noexcept : m_mutex(nullptr), m_owns(false) { /* ... */ }
|
||||||
|
|
||||||
|
explicit unique_lock(mutex_type &m) noexcept : m_mutex(std::addressof(m)), m_owns(false) {
|
||||||
|
this->lock();
|
||||||
|
m_owns = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_lock(mutex_type &m, std::defer_lock_t) noexcept : m_mutex(std::addressof(m)), m_owns(false) { /* ... */ }
|
||||||
|
unique_lock(mutex_type &m, std::try_to_lock_t) noexcept : m_mutex(std::addressof(m)), m_owns(m_mutex->try_lock()) { /* ... */ }
|
||||||
|
unique_lock(mutex_type &m, std::adopt_lock_t) noexcept : m_mutex(std::addressof(m)), m_owns(true) { /* ... */ }
|
||||||
|
|
||||||
|
template<typename _Clock, typename _Duration>
|
||||||
|
unique_lock(mutex_type &m, const std::chrono::time_point<_Clock, _Duration> &time) noexcept : m_mutex(std::addressof(m)), m_owns(m_mutex->try_lock_until(time)) { /* ... */ }
|
||||||
|
|
||||||
|
template<typename _Rep, typename _Period>
|
||||||
|
unique_lock(mutex_type &m, const std::chrono::duration<_Rep, _Period> &time) noexcept : m_mutex(std::addressof(m)), m_owns(m_mutex->try_lock_for(time)) { /* ... */ }
|
||||||
|
|
||||||
|
~unique_lock() noexcept {
|
||||||
|
if (m_owns) {
|
||||||
|
this->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_lock(unique_lock &&rhs) noexcept : m_mutex(rhs.m_mutex), m_owns(rhs.m_owns) {
|
||||||
|
rhs.m_mutex = nullptr;
|
||||||
|
rhs.m_owns = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_lock &operator=(unique_lock &&rhs) noexcept {
|
||||||
|
if (m_owns) {
|
||||||
|
this->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_lock(std::move(rhs)).swap(*this);
|
||||||
|
|
||||||
|
rhs.m_mutex = nullptr;
|
||||||
|
rhs.m_owns = false;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lock() noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_mutex);
|
||||||
|
AMS_ABORT_UNLESS(!m_owns);
|
||||||
|
|
||||||
|
m_mutex->lock();
|
||||||
|
m_owns = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool try_lock() noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_mutex);
|
||||||
|
AMS_ABORT_UNLESS(!m_owns);
|
||||||
|
|
||||||
|
m_owns = m_mutex->try_lock();
|
||||||
|
return m_owns;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename _Clock, typename _Duration>
|
||||||
|
bool try_lock_until(const std::chrono::time_point<_Clock, _Duration> &time) noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_mutex);
|
||||||
|
AMS_ABORT_UNLESS(!m_owns);
|
||||||
|
m_owns = m_mutex->try_lock_until(time);
|
||||||
|
return m_owns;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename _Rep, typename _Period>
|
||||||
|
bool try_lock_for(const std::chrono::duration<_Rep, _Period> &time) noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_mutex);
|
||||||
|
AMS_ABORT_UNLESS(!m_owns);
|
||||||
|
m_owns = m_mutex->try_lock_for(time);
|
||||||
|
return m_owns;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void unlock() noexcept {
|
||||||
|
AMS_ABORT_UNLESS(m_owns);
|
||||||
|
if (m_mutex) {
|
||||||
|
m_mutex->unlock();
|
||||||
|
m_owns = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(unique_lock &rhs) noexcept {
|
||||||
|
std::swap(m_mutex, rhs.m_mutex);
|
||||||
|
std::swap(m_owns, rhs.m_owns);
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_type *release() noexcept {
|
||||||
|
mutex_type *ret = m_mutex;
|
||||||
|
m_mutex = nullptr;
|
||||||
|
m_owns = false;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool owns_lock() const noexcept {
|
||||||
|
return m_owns;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const noexcept {
|
||||||
|
return this->owns_lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_type *mutex() const noexcept {
|
||||||
|
return m_mutex;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename _Mutex>
|
||||||
|
inline void swap(unique_lock<_Mutex> &lhs, unique_lock<_Mutex> &rhs) noexcept { return lhs.swap(rhs); }
|
||||||
|
|
||||||
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
namespace ams::ldr {
|
namespace ams::ldr {
|
||||||
|
|
||||||
class LoaderService final {
|
class LoaderService {
|
||||||
public:
|
public:
|
||||||
/* Official commands. */
|
/* Official commands. */
|
||||||
Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle reslimit_h);
|
Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle reslimit_h);
|
||||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
||||||
u32 __nx_applet_type = AppletType_None;
|
u32 __nx_applet_type = AppletType_None;
|
||||||
u32 __nx_fs_num_sessions = 1;
|
u32 __nx_fs_num_sessions = 1;
|
||||||
|
|
||||||
#define INNER_HEAP_SIZE 0x8000
|
#define INNER_HEAP_SIZE 0x0
|
||||||
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
size_t nx_inner_heap_size = INNER_HEAP_SIZE;
|
||||||
char nx_inner_heap[INNER_HEAP_SIZE];
|
char nx_inner_heap[INNER_HEAP_SIZE];
|
||||||
|
|
||||||
|
@ -35,6 +35,9 @@ extern "C" {
|
||||||
alignas(16) u8 __nx_exception_stack[ams::os::MemoryPageSize];
|
alignas(16) u8 __nx_exception_stack[ams::os::MemoryPageSize];
|
||||||
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
u64 __nx_exception_stack_size = sizeof(__nx_exception_stack);
|
||||||
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
void __libnx_exception_handler(ThreadExceptionDump *ctx);
|
||||||
|
|
||||||
|
void *__libnx_thread_alloc(size_t size);
|
||||||
|
void __libnx_thread_free(void *mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ams {
|
namespace ams {
|
||||||
|
@ -55,6 +58,78 @@ void __libnx_exception_handler(ThreadExceptionDump *ctx) {
|
||||||
ams::CrashHandler(ctx);
|
ams::CrashHandler(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ams::ldr {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constinit u8 g_heap_memory[16_KB];
|
||||||
|
lmem::HeapHandle g_server_heap_handle;
|
||||||
|
constinit ams::sf::ExpHeapAllocator g_server_allocator;
|
||||||
|
|
||||||
|
void *Allocate(size_t size) {
|
||||||
|
return lmem::AllocateFromExpHeap(g_server_heap_handle, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Deallocate(void *p, size_t size) {
|
||||||
|
return lmem::FreeToExpHeap(g_server_heap_handle, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeHeap() {
|
||||||
|
g_server_heap_handle = lmem::CreateExpHeap(g_heap_memory, sizeof(g_heap_memory), lmem::CreateOption_None);
|
||||||
|
g_server_allocator.Attach(g_server_heap_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct ServerOptions {
|
||||||
|
static constexpr size_t PointerBufferSize = 0x400;
|
||||||
|
static constexpr size_t MaxDomains = 0;
|
||||||
|
static constexpr size_t MaxDomainObjects = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ldr:pm, ldr:shel, ldr:dmnt. */
|
||||||
|
enum PortIndex {
|
||||||
|
PortIndex_ProcessManager,
|
||||||
|
PortIndex_Shell,
|
||||||
|
PortIndex_DebugMonitor,
|
||||||
|
PortIndex_Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr sm::ServiceName ProcessManagerServiceName = sm::ServiceName::Encode("ldr:pm");
|
||||||
|
constexpr size_t ProcessManagerMaxSessions = 1;
|
||||||
|
|
||||||
|
constexpr sm::ServiceName ShellServiceName = sm::ServiceName::Encode("ldr:shel");
|
||||||
|
constexpr size_t ShellMaxSessions = 3;
|
||||||
|
|
||||||
|
constexpr sm::ServiceName DebugMonitorServiceName = sm::ServiceName::Encode("ldr:dmnt");
|
||||||
|
constexpr size_t DebugMonitorMaxSessions = 3;
|
||||||
|
|
||||||
|
constinit sf::UnmanagedServiceObject<impl::IProcessManagerInterface, LoaderService> g_pm_service;
|
||||||
|
constinit sf::UnmanagedServiceObject<impl::IShellInterface, LoaderService> g_shell_service;
|
||||||
|
constinit sf::UnmanagedServiceObject<impl::IDebugMonitorInterface, LoaderService> g_dmnt_service;
|
||||||
|
|
||||||
|
constexpr size_t MaxSessions = ProcessManagerMaxSessions + ShellMaxSessions + DebugMonitorMaxSessions + 1;
|
||||||
|
|
||||||
|
using ServerManager = ams::sf::hipc::ServerManager<PortIndex_Count, ServerOptions, MaxSessions>;
|
||||||
|
|
||||||
|
ServerManager g_server_manager;
|
||||||
|
|
||||||
|
void RegisterServiceSessions() {
|
||||||
|
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_pm_service.GetShared(), ProcessManagerServiceName, ProcessManagerMaxSessions));
|
||||||
|
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_shell_service.GetShared(), ShellServiceName, ShellMaxSessions));
|
||||||
|
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_dmnt_service.GetShared(), DebugMonitorServiceName, DebugMonitorMaxSessions));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoopProcess() {
|
||||||
|
g_server_manager.LoopProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void __libnx_initheap(void) {
|
void __libnx_initheap(void) {
|
||||||
void* addr = nx_inner_heap;
|
void* addr = nx_inner_heap;
|
||||||
size_t size = nx_inner_heap_size;
|
size_t size = nx_inner_heap_size;
|
||||||
|
@ -65,11 +140,15 @@ void __libnx_initheap(void) {
|
||||||
|
|
||||||
fake_heap_start = (char*)addr;
|
fake_heap_start = (char*)addr;
|
||||||
fake_heap_end = (char*)addr + size;
|
fake_heap_end = (char*)addr + size;
|
||||||
|
|
||||||
|
ams::ldr::InitializeHeap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void __appInit(void) {
|
void __appInit(void) {
|
||||||
hos::InitializeForStratosphere();
|
hos::InitializeForStratosphere();
|
||||||
|
|
||||||
|
fs::SetAllocator(ldr::Allocate, ldr::Deallocate);
|
||||||
|
|
||||||
/* Initialize services we need. */
|
/* Initialize services we need. */
|
||||||
sm::DoWithSession([&]() {
|
sm::DoWithSession([&]() {
|
||||||
R_ABORT_UNLESS(fsInitialize());
|
R_ABORT_UNLESS(fsInitialize());
|
||||||
|
@ -89,28 +168,32 @@ void __appExit(void) {
|
||||||
fsExit();
|
fsExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace ams {
|
||||||
|
|
||||||
struct ServerOptions {
|
void *Malloc(size_t size) {
|
||||||
static constexpr size_t PointerBufferSize = 0x400;
|
AMS_ABORT("ams::Malloc was called");
|
||||||
static constexpr size_t MaxDomains = 0;
|
}
|
||||||
static constexpr size_t MaxDomainObjects = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr sm::ServiceName ProcessManagerServiceName = sm::ServiceName::Encode("ldr:pm");
|
void Free(void *ptr) {
|
||||||
constexpr size_t ProcessManagerMaxSessions = 1;
|
AMS_ABORT("ams::Free was called");
|
||||||
|
}
|
||||||
|
|
||||||
constexpr sm::ServiceName ShellServiceName = sm::ServiceName::Encode("ldr:shel");
|
}
|
||||||
constexpr size_t ShellMaxSessions = 3;
|
|
||||||
|
|
||||||
constexpr sm::ServiceName DebugMonitorServiceName = sm::ServiceName::Encode("ldr:dmnt");
|
void *operator new(size_t size) {
|
||||||
constexpr size_t DebugMonitorMaxSessions = 3;
|
return ldr::Allocate(size);
|
||||||
|
}
|
||||||
|
|
||||||
/* ldr:pm, ldr:shel, ldr:dmnt. */
|
void operator delete(void *p) {
|
||||||
constexpr size_t NumServers = 3;
|
return ldr::Deallocate(p, 0);
|
||||||
constexpr size_t MaxSessions = ProcessManagerMaxSessions + ShellMaxSessions + DebugMonitorMaxSessions + 1;
|
}
|
||||||
sf::hipc::ServerManager<NumServers, ServerOptions, MaxSessions> g_server_manager;
|
|
||||||
|
|
||||||
|
void *__libnx_thread_alloc(size_t size) {
|
||||||
|
AMS_ABORT("__libnx_thread_alloc was called");
|
||||||
|
}
|
||||||
|
|
||||||
|
void __libnx_thread_free(void *mem) {
|
||||||
|
AMS_ABORT("__libnx_thread_free was called");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
@ -128,13 +211,11 @@ int main(int argc, char **argv)
|
||||||
ldr::SetDevelopmentForAntiDowngradeCheck(spl::IsDevelopment());
|
ldr::SetDevelopmentForAntiDowngradeCheck(spl::IsDevelopment());
|
||||||
ldr::SetDevelopmentForAcidSignatureCheck(spl::IsDevelopment());
|
ldr::SetDevelopmentForAcidSignatureCheck(spl::IsDevelopment());
|
||||||
|
|
||||||
/* Add services to manager. */
|
/* Register the loader services. */
|
||||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::impl::IProcessManagerInterface, ldr::LoaderService>(ProcessManagerServiceName, ProcessManagerMaxSessions)));
|
ldr::RegisterServiceSessions();
|
||||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::impl::IShellInterface, ldr::LoaderService>(ShellServiceName, ShellMaxSessions)));
|
|
||||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::impl::IDebugMonitorInterface, ldr::LoaderService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
|
|
||||||
|
|
||||||
/* Loop forever, servicing our services. */
|
/* Loop forever, servicing our services. */
|
||||||
g_server_manager.LoopProcess();
|
ldr::LoopProcess();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -654,7 +654,7 @@ namespace ams::ldr {
|
||||||
fssystem::DestroyExternalCode(loc.program_id);
|
fssystem::DestroyExternalCode(loc.program_id);
|
||||||
|
|
||||||
/* Note that we've created the program. */
|
/* Note that we've created the program. */
|
||||||
SetLaunchedProgram(loc.program_id);
|
SetLaunchedBootProgram(loc.program_id);
|
||||||
|
|
||||||
/* Move the process handle to output. */
|
/* Move the process handle to output. */
|
||||||
*out = info.process_handle.Move();
|
*out = info.process_handle.Move();
|
||||||
|
|
Loading…
Reference in a new issue