mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-31 14:58:22 -04:00
os: refactor/rewrite entire namespace.
This commit is contained in:
parent
6193283f03
commit
065485b971
181 changed files with 5353 additions and 1929 deletions
|
@ -17,8 +17,9 @@
|
|||
|
||||
namespace ams::pm::impl {
|
||||
|
||||
ProcessInfo::ProcessInfo(Handle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s) : process_id(pid), pin_id(pin), loc(l), status(s), handle(h), state(svc::ProcessState_Created), flags(0), waitable_holder(h) {
|
||||
this->waitable_holder.SetUserData(reinterpret_cast<uintptr_t>(this));
|
||||
ProcessInfo::ProcessInfo(Handle h, os::ProcessId pid, ldr::PinId pin, const ncm::ProgramLocation &l, const cfg::OverrideStatus &s) : process_id(pid), pin_id(pin), loc(l), status(s), handle(h), state(svc::ProcessState_Created), flags(0) {
|
||||
os::InitializeWaitableHolder(std::addressof(this->waitable_holder), this->handle);
|
||||
os::SetWaitableHolderUserData(std::addressof(this->waitable_holder), reinterpret_cast<uintptr_t>(this));
|
||||
}
|
||||
|
||||
ProcessInfo::~ProcessInfo() {
|
||||
|
@ -37,7 +38,7 @@ namespace ams::pm::impl {
|
|||
this->handle = INVALID_HANDLE;
|
||||
|
||||
/* Unlink the process from its waitable manager. */
|
||||
this->waitable_holder.UnlinkFromWaitableManager();
|
||||
os::UnlinkWaitableHolder(std::addressof(this->waitable_holder));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace ams::pm::impl {
|
|||
Handle handle;
|
||||
svc::ProcessState state;
|
||||
u32 flags;
|
||||
os::WaitableHolder waitable_holder;
|
||||
os::WaitableHolderType waitable_holder;
|
||||
private:
|
||||
void SetFlag(Flag flag) {
|
||||
this->flags |= flag;
|
||||
|
@ -63,8 +63,8 @@ namespace ams::pm::impl {
|
|||
~ProcessInfo();
|
||||
void Cleanup();
|
||||
|
||||
void LinkToWaitableManager(os::WaitableManager &manager) {
|
||||
manager.LinkWaitableHolder(&this->waitable_holder);
|
||||
void LinkToWaitableManager(os::WaitableManagerType &manager) {
|
||||
os::LinkWaitableHolder(std::addressof(manager), std::addressof(this->waitable_holder));
|
||||
}
|
||||
|
||||
Handle GetHandle() const {
|
||||
|
@ -163,6 +163,8 @@ namespace ams::pm::impl {
|
|||
private:
|
||||
os::Mutex lock;
|
||||
public:
|
||||
constexpr ProcessList() : lock(false) { /* ... */ }
|
||||
|
||||
void Lock() {
|
||||
this->lock.Lock();
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ namespace ams::pm::impl {
|
|||
return process_info - GetPointer(this->process_info_storages[0]);
|
||||
}
|
||||
public:
|
||||
constexpr ProcessInfoAllocator() {
|
||||
constexpr ProcessInfoAllocator() : lock(false) {
|
||||
std::memset(this->process_info_storages, 0, sizeof(this->process_info_storages));
|
||||
std::memset(this->process_info_allocated, 0, sizeof(this->process_info_allocated));
|
||||
}
|
||||
|
@ -176,9 +176,9 @@ namespace ams::pm::impl {
|
|||
/* Process Tracking globals. */
|
||||
void ProcessTrackingMain(void *arg);
|
||||
|
||||
constexpr size_t ProcessTrackThreadStackSize = 0x4000;
|
||||
constexpr int ProcessTrackThreadPriority = 0x15;
|
||||
os::StaticThread<ProcessTrackThreadStackSize> g_process_track_thread(&ProcessTrackingMain, nullptr, ProcessTrackThreadPriority);
|
||||
constexpr int ProcessTrackThreadPriority = 21;
|
||||
os::ThreadType g_process_track_thread;
|
||||
alignas(os::ThreadStackAlignment) u8 g_process_track_thread_stack[16_KB];
|
||||
|
||||
/* Process lists. */
|
||||
ProcessList g_process_list;
|
||||
|
@ -190,15 +190,15 @@ namespace ams::pm::impl {
|
|||
ProcessInfoAllocator<MaxProcessCount> g_process_info_allocator;
|
||||
|
||||
/* Global events. */
|
||||
os::SystemEvent g_process_event;
|
||||
os::SystemEvent g_hook_to_create_process_event;
|
||||
os::SystemEvent g_hook_to_create_application_process_event;
|
||||
os::SystemEvent g_boot_finished_event;
|
||||
os::SystemEventType g_process_event;
|
||||
os::SystemEventType g_hook_to_create_process_event;
|
||||
os::SystemEventType g_hook_to_create_application_process_event;
|
||||
os::SystemEventType g_boot_finished_event;
|
||||
|
||||
/* Process Launch synchronization globals. */
|
||||
os::Mutex g_launch_program_lock;
|
||||
os::Event g_process_launch_start_event;
|
||||
os::Event g_process_launch_finish_event;
|
||||
os::Mutex g_launch_program_lock(false);
|
||||
os::Event g_process_launch_start_event(os::EventClearMode_AutoClear);
|
||||
os::Event g_process_launch_finish_event(os::EventClearMode_AutoClear);
|
||||
Result g_process_launch_result = ResultSuccess();
|
||||
LaunchProcessArgs g_process_launch_args = {};
|
||||
|
||||
|
@ -207,7 +207,7 @@ namespace ams::pm::impl {
|
|||
std::atomic<bool> g_application_hook;
|
||||
|
||||
/* Forward declarations. */
|
||||
Result LaunchProcess(os::WaitableManager &waitable_manager, const LaunchProcessArgs &args);
|
||||
Result LaunchProcess(os::WaitableManagerType &waitable_manager, const LaunchProcessArgs &args);
|
||||
void OnProcessSignaled(ProcessListAccessor &list, ProcessInfo *process_info);
|
||||
|
||||
/* Helpers. */
|
||||
|
@ -215,12 +215,14 @@ namespace ams::pm::impl {
|
|||
/* This is the main loop of the process tracking thread. */
|
||||
|
||||
/* Setup waitable manager. */
|
||||
os::WaitableManager process_waitable_manager;
|
||||
os::WaitableHolder start_event_holder(&g_process_launch_start_event);
|
||||
process_waitable_manager.LinkWaitableHolder(&start_event_holder);
|
||||
os::WaitableManagerType process_waitable_manager;
|
||||
os::WaitableHolderType start_event_holder;
|
||||
os::InitializeWaitableManager(std::addressof(process_waitable_manager));
|
||||
os::InitializeWaitableHolder(std::addressof(start_event_holder), g_process_launch_start_event.GetBase());
|
||||
os::LinkWaitableHolder(std::addressof(process_waitable_manager), std::addressof(start_event_holder));
|
||||
|
||||
while (true) {
|
||||
auto signaled_holder = process_waitable_manager.WaitAny();
|
||||
auto signaled_holder = os::WaitAny(std::addressof(process_waitable_manager));
|
||||
if (signaled_holder == &start_event_holder) {
|
||||
/* Launch start event signaled. */
|
||||
/* TryWait will clear signaled, preventing duplicate notifications. */
|
||||
|
@ -231,7 +233,7 @@ namespace ams::pm::impl {
|
|||
} else {
|
||||
/* Some process was signaled. */
|
||||
ProcessListAccessor list(g_process_list);
|
||||
OnProcessSignaled(list, reinterpret_cast<ProcessInfo *>(signaled_holder->GetUserData()));
|
||||
OnProcessSignaled(list, reinterpret_cast<ProcessInfo *>(os::GetWaitableHolderUserData(signaled_holder)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -275,7 +277,7 @@ namespace ams::pm::impl {
|
|||
g_process_info_allocator.FreeProcessInfo(process_info);
|
||||
}
|
||||
|
||||
Result LaunchProcess(os::WaitableManager &waitable_manager, const LaunchProcessArgs &args) {
|
||||
Result LaunchProcess(os::WaitableManagerType &waitable_manager, const LaunchProcessArgs &args) {
|
||||
/* Get Program Info. */
|
||||
ldr::ProgramInfo program_info;
|
||||
cfg::OverrideStatus override_status;
|
||||
|
@ -351,10 +353,10 @@ namespace ams::pm::impl {
|
|||
|
||||
/* Process hooks/signaling. */
|
||||
if (location.program_id == g_program_id_hook) {
|
||||
g_hook_to_create_process_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_hook_to_create_process_event));
|
||||
g_program_id_hook = ncm::InvalidProgramId;
|
||||
} else if (is_application && g_application_hook) {
|
||||
g_hook_to_create_application_process_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_hook_to_create_application_process_event));
|
||||
g_application_hook = false;
|
||||
} else if (!ShouldStartSuspended(args.flags)) {
|
||||
R_TRY(StartProcess(process_info, &program_info));
|
||||
|
@ -394,22 +396,22 @@ namespace ams::pm::impl {
|
|||
if (process_info->ShouldSignalOnDebugEvent()) {
|
||||
process_info->ClearSuspended();
|
||||
process_info->SetSuspendedStateChanged();
|
||||
g_process_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_process_event));
|
||||
} else if (hos::GetVersion() >= hos::Version_200 && process_info->ShouldSignalOnStart()) {
|
||||
process_info->SetStartedStateChanged();
|
||||
process_info->ClearSignalOnStart();
|
||||
g_process_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_process_event));
|
||||
}
|
||||
break;
|
||||
case svc::ProcessState_Crashed:
|
||||
process_info->SetExceptionOccurred();
|
||||
g_process_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_process_event));
|
||||
break;
|
||||
case svc::ProcessState_RunningAttached:
|
||||
if (process_info->ShouldSignalOnDebugEvent()) {
|
||||
process_info->ClearSuspended();
|
||||
process_info->SetSuspendedStateChanged();
|
||||
g_process_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_process_event));
|
||||
}
|
||||
break;
|
||||
case svc::ProcessState_Terminated:
|
||||
|
@ -417,7 +419,7 @@ namespace ams::pm::impl {
|
|||
process_info->Cleanup();
|
||||
|
||||
if (hos::GetVersion() < hos::Version_500 && process_info->ShouldSignalOnExit()) {
|
||||
g_process_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_process_event));
|
||||
} else {
|
||||
/* Handle the case where we need to keep the process alive some time longer. */
|
||||
if (hos::GetVersion() >= hos::Version_500 && process_info->ShouldSignalOnExit()) {
|
||||
|
@ -431,7 +433,7 @@ namespace ams::pm::impl {
|
|||
}
|
||||
|
||||
/* Signal. */
|
||||
g_process_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_process_event));
|
||||
} else {
|
||||
/* Actually delete process. */
|
||||
CleanupProcessInfo(list, process_info);
|
||||
|
@ -442,7 +444,7 @@ namespace ams::pm::impl {
|
|||
if (process_info->ShouldSignalOnDebugEvent()) {
|
||||
process_info->SetSuspended();
|
||||
process_info->SetSuspendedStateChanged();
|
||||
g_process_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_process_event));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -453,16 +455,19 @@ namespace ams::pm::impl {
|
|||
/* Initialization. */
|
||||
Result InitializeProcessManager() {
|
||||
/* Create events. */
|
||||
R_ABORT_UNLESS(g_process_event.InitializeAsInterProcessEvent());
|
||||
R_ABORT_UNLESS(g_hook_to_create_process_event.InitializeAsInterProcessEvent());
|
||||
R_ABORT_UNLESS(g_hook_to_create_application_process_event.InitializeAsInterProcessEvent());
|
||||
R_ABORT_UNLESS(g_boot_finished_event.InitializeAsInterProcessEvent());
|
||||
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_process_event), os::EventClearMode_AutoClear, true));
|
||||
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_process_event), os::EventClearMode_AutoClear, true));
|
||||
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_hook_to_create_application_process_event), os::EventClearMode_AutoClear, true));
|
||||
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_boot_finished_event), os::EventClearMode_AutoClear, true));
|
||||
|
||||
/* Initialize resource limits. */
|
||||
R_TRY(resource::InitializeResourceManager());
|
||||
|
||||
/* Create thread. */
|
||||
R_ABORT_UNLESS(os::CreateThread(std::addressof(g_process_track_thread), ProcessTrackingMain, nullptr, g_process_track_thread_stack, sizeof(g_process_track_thread_stack), ProcessTrackThreadPriority));
|
||||
|
||||
/* Start thread. */
|
||||
R_ABORT_UNLESS(g_process_track_thread.Start());
|
||||
os::StartThread(std::addressof(g_process_track_thread));
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -515,7 +520,7 @@ namespace ams::pm::impl {
|
|||
}
|
||||
|
||||
Result GetProcessEventHandle(Handle *out) {
|
||||
*out = g_process_event.GetReadableHandle();
|
||||
*out = os::GetReadableHandleOfSystemEvent(std::addressof(g_process_event));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -670,7 +675,7 @@ namespace ams::pm::impl {
|
|||
R_UNLESS(g_program_id_hook.compare_exchange_strong(old_value, program_id), pm::ResultDebugHookInUse());
|
||||
}
|
||||
|
||||
*out_hook = g_hook_to_create_process_event.GetReadableHandle();
|
||||
*out_hook = os::GetReadableHandleOfSystemEvent(std::addressof(g_hook_to_create_process_event));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -682,7 +687,7 @@ namespace ams::pm::impl {
|
|||
R_UNLESS(g_application_hook.compare_exchange_strong(old_value, true), pm::ResultDebugHookInUse());
|
||||
}
|
||||
|
||||
*out_hook = g_hook_to_create_application_process_event.GetReadableHandle();
|
||||
*out_hook = os::GetReadableHandleOfSystemEvent(std::addressof(g_hook_to_create_application_process_event));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
@ -702,7 +707,7 @@ namespace ams::pm::impl {
|
|||
if (!g_has_boot_finished) {
|
||||
boot2::LaunchPreSdCardBootProgramsAndBoot2();
|
||||
g_has_boot_finished = true;
|
||||
g_boot_finished_event.Signal();
|
||||
os::SignalSystemEvent(std::addressof(g_boot_finished_event));
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
@ -712,7 +717,7 @@ namespace ams::pm::impl {
|
|||
/* Nintendo only signals it in safe mode FIRM, and this function aborts on normal FIRM. */
|
||||
/* We will signal it always, but only allow this function to succeed on safe mode. */
|
||||
AMS_ABORT_UNLESS(spl::IsRecoveryBoot());
|
||||
*out = g_boot_finished_event.GetReadableHandle();
|
||||
*out = os::GetReadableHandleOfSystemEvent(std::addressof(g_boot_finished_event));
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace ams::pm::resource {
|
|||
constexpr size_t ExtraSystemMemorySizeAtmosphere500 = 33_MB; /* Applet pool is 0x20100000 */
|
||||
|
||||
/* Globals. */
|
||||
os::Mutex g_resource_limit_lock;
|
||||
os::Mutex g_resource_limit_lock(false);
|
||||
Handle g_resource_limit_handles[ResourceLimitGroup_Count];
|
||||
spl::MemoryArrangement g_memory_arrangement = spl::MemoryArrangement_Standard;
|
||||
u64 g_system_memory_boost_size = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue