From 18666a88c0584c470ab91f0734d0c1e3d8e93b1e Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 17 Apr 2020 01:06:07 -0700 Subject: [PATCH] ams: centralize system thread definitions --- libstratosphere/include/stratosphere.hpp | 3 + .../impl/ams_system_thread_definitions.hpp | 114 ++++++++++++++++++ .../fssystem_thread_priority_changer.hpp | 27 ++++- .../source/erpt/srv/erpt_srv_service.cpp | 5 +- .../fssystem_thread_priority_changer.cpp | 25 ++++ .../source/pgl/srv/pgl_srv_shell.cpp | 4 +- .../source/sf/hipc/sf_hipc_mitm_query_api.cpp | 4 +- 7 files changed, 171 insertions(+), 11 deletions(-) create mode 100644 libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp create mode 100644 libstratosphere/source/fssystem/fssystem_thread_priority_changer.cpp diff --git a/libstratosphere/include/stratosphere.hpp b/libstratosphere/include/stratosphere.hpp index 8aa4b363..a4c520b5 100644 --- a/libstratosphere/include/stratosphere.hpp +++ b/libstratosphere/include/stratosphere.hpp @@ -19,6 +19,9 @@ /* libvapours (pulls in util, svc, results). */ #include +/* Libstratosphere definitions. */ +#include + /* Libstratosphere-only utility. */ #include diff --git a/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp b/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp new file mode 100644 index 00000000..c627462e --- /dev/null +++ b/libstratosphere/include/stratosphere/ams/impl/ams_system_thread_definitions.hpp @@ -0,0 +1,114 @@ +/* + * 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 . + */ +#pragma once +#include + +namespace ams::impl { + + struct SystemThreadDefinition { + s32 priority; + const char *name; + }; + + #define AMS_DEFINE_SYSTEM_THREAD(__AMS_THREAD_PRIORITY__, __AMS_MODULE__, __AMS_THREAD_NAME__) \ + constexpr inline const ::ams::impl::SystemThreadDefinition SystemThreadDefinition##__AMS_MODULE__##__AMS_THREAD_NAME__ = { __AMS_THREAD_PRIORITY__, "ams." # __AMS_MODULE__ "." #__AMS_THREAD_NAME__ } + + /* sm. */ + AMS_DEFINE_SYSTEM_THREAD(-1, sm, Main); + + /* spl. */ + AMS_DEFINE_SYSTEM_THREAD(-1, spl, Main); + + /* Loader. */ + AMS_DEFINE_SYSTEM_THREAD(21, ldr, Main); + + /* Process Manager. */ + AMS_DEFINE_SYSTEM_THREAD(21, pm, Main); + AMS_DEFINE_SYSTEM_THREAD(21, pm, ProcessTrack); + + /* NCM. */ + AMS_DEFINE_SYSTEM_THREAD(21, ncm, MainWaitThreads); + AMS_DEFINE_SYSTEM_THREAD(21, ncm, ContentManagerServerIpcSession); + AMS_DEFINE_SYSTEM_THREAD(21, ncm, LocationResolverServerIpcSession); + + /* FS. */ + AMS_DEFINE_SYSTEM_THREAD(16, fs, WorkerThreadPool); + AMS_DEFINE_SYSTEM_THREAD(17, fs, Main); + AMS_DEFINE_SYSTEM_THREAD(17, fs, WorkerRealTimeAccess); + AMS_DEFINE_SYSTEM_THREAD(18, fs, WorkerNormalPriorityAccess); + AMS_DEFINE_SYSTEM_THREAD(19, fs, WorkerLowPriorityAccess); + AMS_DEFINE_SYSTEM_THREAD(30, fs, WorkerBackgroundAccess); + AMS_DEFINE_SYSTEM_THREAD(30, fs, PatrolReader); + + /* Boot. */ + AMS_DEFINE_SYSTEM_THREAD(-1, boot, Main); + + /* Mitm. */ + AMS_DEFINE_SYSTEM_THREAD(-7, mitm, InitializeThread); + AMS_DEFINE_SYSTEM_THREAD(-1, mitm_sf, QueryServerProcessThread); + AMS_DEFINE_SYSTEM_THREAD(16, mitm_fs, RomFileSystemInitializeThread); + AMS_DEFINE_SYSTEM_THREAD(21, mitm, DebugThrowThread); + + /* boot2. */ + AMS_DEFINE_SYSTEM_THREAD(20, boot2, Main); + + /* dmnt. */ + AMS_DEFINE_SYSTEM_THREAD(-3, dmnt, MultiCoreEventManager); + AMS_DEFINE_SYSTEM_THREAD(-1, dmnt, CheatDebugEvents); + AMS_DEFINE_SYSTEM_THREAD(-1, dmnt, MultiCoreBP); + AMS_DEFINE_SYSTEM_THREAD(11, dmnt, Main); + AMS_DEFINE_SYSTEM_THREAD(11, dmnt, Ipc); + AMS_DEFINE_SYSTEM_THREAD(11, dmnt, CheatDetect); + AMS_DEFINE_SYSTEM_THREAD(20, dmnt, CheatVirtualMachine); + + /* fatal */ + AMS_DEFINE_SYSTEM_THREAD(-13, fatal, Main); + AMS_DEFINE_SYSTEM_THREAD(-13, fatalsrv, FatalTaskThread); + AMS_DEFINE_SYSTEM_THREAD( 9, fatalsrv, IpcDispatcher); + + /* creport. */ + AMS_DEFINE_SYSTEM_THREAD(16, creport, Main); + + /* ro. */ + AMS_DEFINE_SYSTEM_THREAD(16, ro, Main); + + /* bpc. */ + AMS_DEFINE_SYSTEM_THREAD(4, bpc, IpcServer); + + /* hid. */ + AMS_DEFINE_SYSTEM_THREAD(-10, hid, IpcServer); + + /* ns.*/ + AMS_DEFINE_SYSTEM_THREAD(21, ns, ApplicationManagerIpcSession); + + /* settings. */ + AMS_DEFINE_SYSTEM_THREAD(21, settings, Main); + AMS_DEFINE_SYSTEM_THREAD(21, settings, IpcServer); + + /* erpt. */ + AMS_DEFINE_SYSTEM_THREAD(21, erpt, Main); + AMS_DEFINE_SYSTEM_THREAD(21, erpt, IpcServer); + + /* pgl. */ + AMS_DEFINE_SYSTEM_THREAD(21, pgl, Main); + AMS_DEFINE_SYSTEM_THREAD(21, pgl, ProcessControlTask); + + #undef AMS_DEFINE_SYSTEM_THREAD + +} + +#define AMS_GET_SYSTEM_THREAD_PRIORITY(__AMS_MODULE__, __AMS_THREAD_NAME__) ::ams::impl::SystemThreadDefinition##__AMS_MODULE__##__AMS_THREAD_NAME__.priority +#define AMS_GET_SYSTEM_THREAD_NAME(__AMS_MODULE__, __AMS_THREAD_NAME__) ::ams::impl::SystemThreadDefinition##__AMS_MODULE__##__AMS_THREAD_NAME__.name diff --git a/libstratosphere/include/stratosphere/fssystem/fssystem_thread_priority_changer.hpp b/libstratosphere/include/stratosphere/fssystem/fssystem_thread_priority_changer.hpp index 6b63537c..6b545b22 100644 --- a/libstratosphere/include/stratosphere/fssystem/fssystem_thread_priority_changer.hpp +++ b/libstratosphere/include/stratosphere/fssystem/fssystem_thread_priority_changer.hpp @@ -26,14 +26,33 @@ namespace ams::fssystem { Relative, }; private: - /* TODO */ + os::ThreadType *thread; + s32 priority; public: - ALWAYS_INLINE explicit ScopedThreadPriorityChanger(s32 priority, Mode mode) { - /* TODO */ + ALWAYS_INLINE explicit ScopedThreadPriorityChanger(s32 prio, Mode mode) : thread(os::GetCurrentThread()), priority(0) { + const auto result_priority = std::min((mode == Mode::Relative) ? os::GetThreadPriority(this->thread) + priority : priority, os::LowestSystemThreadPriority); + this->priority = os::ChangeThreadPriority(thread, result_priority); } ALWAYS_INLINE ~ScopedThreadPriorityChanger() { - /* TODO */ + os::ChangeThreadPriority(this->thread, this->priority); } }; + + class ScopedThreadPriorityChangerByAccessPriority { + public: + enum class AccessMode { + Read, + Write, + }; + private: + static s32 GetThreadPriorityByAccessPriority(AccessMode mode); + private: + ScopedThreadPriorityChanger scoped_changer; + public: + ALWAYS_INLINE explicit ScopedThreadPriorityChangerByAccessPriority(AccessMode mode) : scoped_changer(GetThreadPriorityByAccessPriority(mode), ScopedThreadPriorityChanger::Mode::Absolute) { + /* ... */ + } + }; + } diff --git a/libstratosphere/source/erpt/srv/erpt_srv_service.cpp b/libstratosphere/source/erpt/srv/erpt_srv_service.cpp index a1d08a28..b6fd8725 100644 --- a/libstratosphere/source/erpt/srv/erpt_srv_service.cpp +++ b/libstratosphere/source/erpt/srv/erpt_srv_service.cpp @@ -34,8 +34,6 @@ namespace ams::erpt::srv { constexpr inline size_t ErrorReportContextSessions = 10; constexpr inline size_t ErrorReportMaxSessions = ErrorReportReportSessions + ErrorReportContextSessions; - constexpr inline s32 ErrorReportServerThreadPriority = 21; - constexpr inline sm::ServiceName ErrorReportContextServiceName = sm::ServiceName::Encode("erpt:c"); constexpr inline sm::ServiceName ErrorReportReportServiceName = sm::ServiceName::Encode("erpt:r"); @@ -64,7 +62,8 @@ namespace ams::erpt::srv { this->ResumeProcessing(); - R_ABORT_UNLESS(os::CreateThread(std::addressof(this->thread), ThreadFunction, this, g_server_thread_stack, sizeof(g_server_thread_stack), ErrorReportServerThreadPriority)); + R_ABORT_UNLESS(os::CreateThread(std::addressof(this->thread), ThreadFunction, this, g_server_thread_stack, sizeof(g_server_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(erpt, IpcServer))); + os::SetThreadNamePointer(std::addressof(this->thread), AMS_GET_SYSTEM_THREAD_NAME(erpt, IpcServer)); os::StartThread(std::addressof(this->thread)); diff --git a/libstratosphere/source/fssystem/fssystem_thread_priority_changer.cpp b/libstratosphere/source/fssystem/fssystem_thread_priority_changer.cpp new file mode 100644 index 00000000..b6338db9 --- /dev/null +++ b/libstratosphere/source/fssystem/fssystem_thread_priority_changer.cpp @@ -0,0 +1,25 @@ +/* + * 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 . + */ +#include + +namespace ams::fssystem { + + s32 ScopedThreadPriorityChangerByAccessPriority::GetThreadPriorityByAccessPriority(AccessMode mode) { + /* TODO: Actually implement this for real. */ + return os::GetThreadPriority(os::GetCurrentThread()); + } + +} diff --git a/libstratosphere/source/pgl/srv/pgl_srv_shell.cpp b/libstratosphere/source/pgl/srv/pgl_srv_shell.cpp index 9529f26e..9ffbb85a 100644 --- a/libstratosphere/source/pgl/srv/pgl_srv_shell.cpp +++ b/libstratosphere/source/pgl/srv/pgl_srv_shell.cpp @@ -43,7 +43,6 @@ namespace ams::pgl::srv { bool g_enable_jit_debug = false; constexpr inline size_t ProcessControlTaskStackSize = 8_KB; - constexpr inline s32 ProcessControlTaskPriority = 21; os::ThreadType g_process_control_task_thread; alignas(os::ThreadStackAlignment) u8 g_process_control_task_stack[ProcessControlTaskStackSize]; @@ -322,7 +321,8 @@ namespace ams::pgl::srv { void InitializeProcessControlTask() { /* Create the task thread. */ - R_ABORT_UNLESS(os::CreateThread(std::addressof(g_process_control_task_thread), ProcessControlTask, nullptr, g_process_control_task_stack, sizeof(g_process_control_task_stack), ProcessControlTaskPriority)); + R_ABORT_UNLESS(os::CreateThread(std::addressof(g_process_control_task_thread), ProcessControlTask, nullptr, g_process_control_task_stack, sizeof(g_process_control_task_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(pgl, ProcessControlTask))); + os::SetThreadNamePointer(std::addressof(g_process_control_task_thread), AMS_GET_SYSTEM_THREAD_NAME(pgl, ProcessControlTask)); /* Retrieve settings. */ settings::fwdbg::GetSettingsItemValue(std::addressof(g_enable_jit_debug), sizeof(g_enable_jit_debug), "jit_debug", "enable_jit_debug"); diff --git a/libstratosphere/source/sf/hipc/sf_hipc_mitm_query_api.cpp b/libstratosphere/source/sf/hipc/sf_hipc_mitm_query_api.cpp index 85023c02..29b3e5c5 100644 --- a/libstratosphere/source/sf/hipc/sf_hipc_mitm_query_api.cpp +++ b/libstratosphere/source/sf/hipc/sf_hipc_mitm_query_api.cpp @@ -49,7 +49,6 @@ namespace ams::sf::hipc::impl { } constexpr size_t QueryServerProcessThreadStackSize = 0x4000; - constexpr s32 QueryServerProcessThreadPriority = -1; alignas(os::ThreadStackAlignment) u8 g_server_process_thread_stack[QueryServerProcessThreadStackSize]; os::ThreadType g_query_server_process_thread; @@ -70,7 +69,8 @@ namespace ams::sf::hipc::impl { R_ABORT_UNLESS(GetPointer(g_query_server_storage)->RegisterSession(query_handle, cmif::ServiceObjectHolder(std::make_shared(query_func)))); if (AMS_UNLIKELY(!g_registered_any)) { - R_ABORT_UNLESS(os::CreateThread(std::addressof(g_query_server_process_thread), &QueryServerProcessThreadMain, GetPointer(g_query_server_storage), g_server_process_thread_stack, sizeof(g_server_process_thread_stack), QueryServerProcessThreadPriority)); + R_ABORT_UNLESS(os::CreateThread(std::addressof(g_query_server_process_thread), &QueryServerProcessThreadMain, GetPointer(g_query_server_storage), g_server_process_thread_stack, sizeof(g_server_process_thread_stack), AMS_GET_SYSTEM_THREAD_PRIORITY(mitm_sf, QueryServerProcessThread))); + os::SetThreadNamePointer(std::addressof(g_query_server_process_thread), AMS_GET_SYSTEM_THREAD_NAME(mitm_sf, QueryServerProcessThread)); os::StartThread(std::addressof(g_query_server_process_thread)); g_registered_any = true; }