os: refactor/rewrite entire namespace.

This commit is contained in:
Michael Scire 2020-04-08 02:21:35 -07:00
parent 6193283f03
commit 065485b971
181 changed files with 5353 additions and 1929 deletions

View file

@ -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();
}