1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-11-23 04:12:02 +00:00

strat: statically allocate additional threads

This commit is contained in:
Michael Scire 2019-10-18 20:31:15 -07:00 committed by SciresM
parent fbb5730369
commit 535e49a38d
17 changed files with 123 additions and 42 deletions

View file

@ -30,6 +30,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;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x4000 #define INNER_HEAP_SIZE 0x4000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;

View file

@ -30,6 +30,11 @@ namespace sts::dmnt::cheat::impl {
/* Manager class. */ /* Manager class. */
class CheatProcessManager { class CheatProcessManager {
private:
static constexpr size_t ThreadStackSize = 0x4000;
static constexpr int DetectThreadPriority = 39;
static constexpr int VirtualMachineThreadPriority = 48;
static constexpr int DebugEventsThreadPriority = 24;
private: private:
os::Mutex cheat_lock; os::Mutex cheat_lock;
os::Event debug_events_event; /* Autoclear. */ os::Event debug_events_event; /* Autoclear. */
@ -47,6 +52,10 @@ namespace sts::dmnt::cheat::impl {
bool should_save_cheat_toggles = false; bool should_save_cheat_toggles = false;
CheatEntry cheat_entries[MaxCheatCount] = {}; CheatEntry cheat_entries[MaxCheatCount] = {};
std::map<u64, FrozenAddressValue> frozen_addresses_map; std::map<u64, FrozenAddressValue> frozen_addresses_map;
alignas(0x1000) u8 detect_thread_stack[ThreadStackSize] = {};
alignas(0x1000) u8 debug_events_thread_stack[ThreadStackSize] = {};
alignas(0x1000) u8 vm_thread_stack[ThreadStackSize] = {};
private: private:
static void DetectLaunchThread(void *_this); static void DetectLaunchThread(void *_this);
static void VirtualMachineThread(void *_this); static void VirtualMachineThread(void *_this);
@ -200,9 +209,9 @@ namespace sts::dmnt::cheat::impl {
} }
/* Spawn application detection thread, spawn cheat vm thread. */ /* Spawn application detection thread, spawn cheat vm thread. */
R_ASSERT(this->detect_thread.Initialize(&CheatProcessManager::DetectLaunchThread, this, 0x4000, 39)); R_ASSERT(this->detect_thread.Initialize(&CheatProcessManager::DetectLaunchThread, this, this->detect_thread_stack, ThreadStackSize, DetectThreadPriority));
R_ASSERT(this->vm_thread.Initialize(&CheatProcessManager::VirtualMachineThread, this, 0x4000, 48)); R_ASSERT(this->vm_thread.Initialize(&CheatProcessManager::VirtualMachineThread, this, this->vm_thread_stack, ThreadStackSize, VirtualMachineThreadPriority));
R_ASSERT(this->debug_events_thread.Initialize(&CheatProcessManager::DebugEventsThread, this, 0x4000, 24)); R_ASSERT(this->debug_events_thread.Initialize(&CheatProcessManager::DebugEventsThread, this, this->debug_events_thread_stack, ThreadStackSize, DebugEventsThreadPriority));
/* Start threads. */ /* Start threads. */
R_ASSERT(this->detect_thread.Start()); R_ASSERT(this->detect_thread.Start());

View file

@ -25,10 +25,14 @@ namespace sts::dmnt::cheat::impl {
class DebugEventsManager { class DebugEventsManager {
public: public:
static constexpr size_t NumCores = 4; static constexpr size_t NumCores = 4;
static constexpr size_t ThreadStackSize = 0x1000;
static constexpr size_t ThreadPriority = 24;
private: private:
std::array<os::MessageQueue, NumCores> message_queues; std::array<os::MessageQueue, NumCores> message_queues;
std::array<os::Thread, NumCores> threads; std::array<os::Thread, NumCores> threads;
os::Event continued_event; os::Event continued_event;
alignas(0x1000) u8 thread_stacks[NumCores][ThreadStackSize];
private: private:
static void PerCoreThreadFunction(void *_this) { static void PerCoreThreadFunction(void *_this) {
/* This thread will wait on the appropriate message queue. */ /* This thread will wait on the appropriate message queue. */
@ -88,10 +92,10 @@ namespace sts::dmnt::cheat::impl {
} }
public: public:
DebugEventsManager() : message_queues{os::MessageQueue(1), os::MessageQueue(1), os::MessageQueue(1), os::MessageQueue(1)} { DebugEventsManager() : message_queues{os::MessageQueue(1), os::MessageQueue(1), os::MessageQueue(1), os::MessageQueue(1)}, thread_stacks{} {
for (size_t i = 0; i < NumCores; i++) { for (size_t i = 0; i < NumCores; i++) {
/* Create thread. */ /* Create thread. */
R_ASSERT(this->threads[i].Initialize(&DebugEventsManager::PerCoreThreadFunction, reinterpret_cast<void *>(this), 0x1000, 24, i)); R_ASSERT(this->threads[i].Initialize(&DebugEventsManager::PerCoreThreadFunction, reinterpret_cast<void *>(this), this->thread_stacks[i], ThreadStackSize, ThreadPriority, i));
/* Set core mask. */ /* Set core mask. */
R_ASSERT(svcSetThreadCoreMask(this->threads[i].GetHandle(), i, (1u << i))); R_ASSERT(svcSetThreadCoreMask(this->threads[i].GetHandle(), i, (1u << i)));

View file

@ -31,9 +31,10 @@ 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;
u32 __nx_fsdev_direntry_cache_size = 1;
/* TODO: Evaluate how much this can be reduced by. */ /* TODO: Evaluate how much this can be reduced by. */
#define INNER_HEAP_SIZE 0xC0000 #define INNER_HEAP_SIZE 0x20000
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];
@ -118,6 +119,14 @@ namespace {
g_server_manager.LoopProcess(); g_server_manager.LoopProcess();
} }
constexpr size_t TotalThreads = DebugMonitorMaxSessions + 1;
static_assert(TotalThreads >= 1, "TotalThreads");
constexpr size_t NumExtraThreads = TotalThreads - 1;
constexpr size_t ThreadStackSize = 0x4000;
alignas(0x1000) u8 g_extra_thread_stacks[NumExtraThreads][ThreadStackSize];
os::Thread g_extra_threads[NumExtraThreads];
} }
int main(int argc, char **argv) int main(int argc, char **argv)
@ -130,25 +139,19 @@ int main(int argc, char **argv)
/* Loop forever, servicing our services. */ /* Loop forever, servicing our services. */
/* Nintendo loops four threads processing on the manager -- we'll loop an extra fifth for our cheat service. */ /* Nintendo loops four threads processing on the manager -- we'll loop an extra fifth for our cheat service. */
{ {
constexpr size_t TotalThreads = DebugMonitorMaxSessions + 1;
constexpr size_t NumExtraThreads = TotalThreads - 1;
static_assert(TotalThreads >= 1, "TotalThreads");
os::Thread extra_threads[NumExtraThreads];
/* Initialize threads. */ /* Initialize threads. */
if constexpr (NumExtraThreads > 0) { if constexpr (NumExtraThreads > 0) {
constexpr size_t ThreadStackSize = 0x4000;
const u32 priority = os::GetCurrentThreadPriority(); const u32 priority = os::GetCurrentThreadPriority();
for (size_t i = 0; i < NumExtraThreads; i++) { for (size_t i = 0; i < NumExtraThreads; i++) {
R_ASSERT(extra_threads[i].Initialize(LoopServerThread, nullptr, ThreadStackSize, priority)); R_ASSERT(g_extra_threads[i].Initialize(LoopServerThread, nullptr, g_extra_thread_stacks[i], ThreadStackSize, priority));
} }
} }
/* Start extra threads. */ /* Start extra threads. */
if constexpr (NumExtraThreads > 0) { if constexpr (NumExtraThreads > 0) {
for (size_t i = 0; i < NumExtraThreads; i++) { for (size_t i = 0; i < NumExtraThreads; i++) {
R_ASSERT(extra_threads[i].Start()); R_ASSERT(g_extra_threads[i].Start());
} }
} }
@ -158,7 +161,7 @@ int main(int argc, char **argv)
/* Wait for extra threads to finish. */ /* Wait for extra threads to finish. */
if constexpr (NumExtraThreads > 0) { if constexpr (NumExtraThreads > 0) {
for (size_t i = 0; i < NumExtraThreads; i++) { for (size_t i = 0; i < NumExtraThreads; i++) {
R_ASSERT(extra_threads[i].Join()); R_ASSERT(g_extra_threads[i].Join());
} }
} }
} }

View file

@ -32,8 +32,9 @@ 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;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x2A0000 #define INNER_HEAP_SIZE 0x240000
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];

View file

@ -45,7 +45,7 @@ namespace sts::fatal::srv {
public: public:
TaskThread() { /* ... */ } TaskThread() { /* ... */ }
void StartTask(ITask *task) { void StartTask(ITask *task) {
R_ASSERT(this->thread.Initialize(&RunTaskImpl, task, task->GetStackSize(), TaskThreadPriority)); R_ASSERT(this->thread.Initialize(&RunTaskImpl, task, task->GetStack(), task->GetStackSize(), TaskThreadPriority));
R_ASSERT(this->thread.Start()); R_ASSERT(this->thread.Start());
} }
}; };

View file

@ -22,8 +22,6 @@
namespace sts::fatal::srv { namespace sts::fatal::srv {
class ITask { class ITask {
public:
static constexpr size_t DefaultStackSize = 0x1000;
protected: protected:
const ThrowContext *context = nullptr; const ThrowContext *context = nullptr;
public: public:
@ -32,14 +30,30 @@ namespace sts::fatal::srv {
} }
virtual Result Run() = 0; virtual Result Run() = 0;
virtual const char *GetName() const = 0; virtual const char *GetName() const = 0;
virtual u8 *GetStack() = 0;
virtual size_t GetStackSize() const = 0;
};
virtual size_t GetStackSize() const { template<size_t _StackSize>
return DefaultStackSize; class ITaskWithStack : public ITask {
public:
static constexpr size_t StackSize = _StackSize;
static_assert(util::IsAligned(StackSize, 0x1000), "StackSize alignment");
protected:
alignas(0x1000) u8 stack_mem[StackSize] = {};
public:
virtual u8 *GetStack() override final {
return this->stack_mem;
}
virtual size_t GetStackSize() const override final {
return StackSize;
} }
}; };
using ITaskWithDefaultStack = ITaskWithStack<0x2000>;
void RunTasks(const ThrowContext *ctx); void RunTasks(const ThrowContext *ctx);
} }

View file

@ -22,7 +22,7 @@ namespace sts::fatal::srv {
namespace { namespace {
/* Task definition. */ /* Task definition. */
class AdjustClockTask : public ITask { class AdjustClockTask : public ITaskWithDefaultStack {
private: private:
Result AdjustClockForModule(PcvModule module, u32 hz); Result AdjustClockForModule(PcvModule module, u32 hz);
Result AdjustClock(); Result AdjustClock();

View file

@ -53,7 +53,7 @@ namespace sts::fatal::srv {
} }
/* Task definition. */ /* Task definition. */
class ErrorReportTask : public ITask { class ErrorReportTask : public ITaskWithDefaultStack {
private: private:
void SaveReportToSdCard(); void SaveReportToSdCard();
public: public:

View file

@ -22,7 +22,7 @@ namespace sts::fatal::srv {
namespace { namespace {
/* Task types. */ /* Task types. */
class PowerControlTask : public ITask { class PowerControlTask : public ITaskWithDefaultStack {
private: private:
bool TryShutdown(); bool TryShutdown();
void MonitorBatteryState(); void MonitorBatteryState();
@ -33,7 +33,7 @@ namespace sts::fatal::srv {
} }
}; };
class PowerButtonObserveTask : public ITask { class PowerButtonObserveTask : public ITaskWithDefaultStack {
private: private:
void WaitForPowerButton(); void WaitForPowerButton();
public: public:
@ -43,7 +43,7 @@ namespace sts::fatal::srv {
} }
}; };
class StateTransitionStopTask : public ITask { class StateTransitionStopTask : public ITaskWithDefaultStack {
public: public:
virtual Result Run() override; virtual Result Run() override;
virtual const char *GetName() const override { virtual const char *GetName() const override {

View file

@ -53,7 +53,7 @@ namespace sts::fatal::srv {
} }
/* Task definitions. */ /* Task definitions. */
class ShowFatalTask : public ITask { class ShowFatalTask : public ITaskWithStack<0x8000> {
private: private:
ViDisplay display; ViDisplay display;
ViLayer layer; ViLayer layer;
@ -69,12 +69,9 @@ namespace sts::fatal::srv {
virtual const char *GetName() const override { virtual const char *GetName() const override {
return "ShowFatal"; return "ShowFatal";
} }
virtual size_t GetStackSize() const override {
return 0x8000;
}
}; };
class BacklightControlTask : public ITask { class BacklightControlTask : public ITaskWithDefaultStack {
private: private:
void TurnOnBacklight(); void TurnOnBacklight();
public: public:

View file

@ -21,7 +21,7 @@ namespace sts::fatal::srv {
namespace { namespace {
/* Task definition. */ /* Task definition. */
class StopSoundTask : public ITask { class StopSoundTask : public ITaskWithDefaultStack {
private: private:
void StopSound(); void StopSound();
public: public:

View file

@ -20,13 +20,61 @@
namespace sts::os { namespace sts::os {
class Thread { class Thread {
NON_COPYABLE(Thread);
NON_MOVEABLE(Thread);
private: private:
::Thread thr = {}; ::Thread thr;
public: public:
Thread() {} constexpr Thread() : thr{} { /* ... */ }
Result Initialize(ThreadFunc entry, void *arg, void *stack_mem, size_t stack_sz, int prio, int cpuid = -2) {
return threadCreate(&this->thr, entry, arg, stack_mem, stack_sz, prio, cpuid);
}
Result Initialize(ThreadFunc entry, void *arg, size_t stack_sz, int prio, int cpuid = -2) { Result Initialize(ThreadFunc entry, void *arg, size_t stack_sz, int prio, int cpuid = -2) {
return threadCreate(&this->thr, entry, arg, stack_sz, prio, cpuid); return threadCreate(&this->thr, entry, arg, nullptr, stack_sz, prio, cpuid);
}
Handle GetHandle() const {
return this->thr.handle;
}
Result Start() {
return threadStart(&this->thr);
}
Result Wait() {
return threadWaitForExit(&this->thr);
}
Result Join() {
R_TRY(threadWaitForExit(&this->thr));
R_TRY(threadClose(&this->thr));
return ResultSuccess;
}
Result CancelSynchronization() {
return svcCancelSynchronization(this->thr.handle);
}
};
template<size_t StackSize>
class StaticThread {
NON_COPYABLE(StaticThread);
NON_MOVEABLE(StaticThread);
static_assert(util::IsAligned(StackSize, 0x1000), "StaticThread must have aligned resource size");
private:
alignas(0x1000) u8 stack_mem[StackSize];
::Thread thr;
public:
constexpr StaticThread() : stack_mem{}, thr{} { /* ... */ }
constexpr StaticThread(ThreadFunc entry, void *arg, int prio, int cpuid = -2) : StaticThread() {
R_ASSERT(this->Initialize(entry, arg, prio, cpuid));
}
Result Initialize(ThreadFunc entry, void *arg, int prio, int cpuid = -2) {
return threadCreate(&this->thr, entry, arg, this->stack_mem, StackSize, prio, cpuid);
} }
Handle GetHandle() const { Handle GetHandle() const {

View file

@ -32,6 +32,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;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x4000 #define INNER_HEAP_SIZE 0x4000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;

View file

@ -182,7 +182,11 @@ namespace sts::pm::impl {
}; };
/* Process Tracking globals. */ /* Process Tracking globals. */
os::Thread g_process_track_thread; void ProcessTrackingMain(void *arg);
constexpr size_t ProcessTrackThreadStackSize = 0x4000;
constexpr int ProcessTrackThreadPriority = 0x15;
os::StaticThread<ProcessTrackThreadStackSize> g_process_track_thread(&ProcessTrackingMain, nullptr, ProcessTrackThreadPriority);
/* Process lists. */ /* Process lists. */
ProcessList g_process_list; ProcessList g_process_list;
@ -468,8 +472,6 @@ namespace sts::pm::impl {
R_TRY(resource::InitializeResourceManager()); R_TRY(resource::InitializeResourceManager());
/* Start thread. */ /* Start thread. */
/* TODO: Allocate thread stack resources statically, will require PR to libnx. */
R_ASSERT(g_process_track_thread.Initialize(&ProcessTrackingMain, nullptr, 0x4000, 0x15));
R_ASSERT(g_process_track_thread.Start()); R_ASSERT(g_process_track_thread.Start());
return ResultSuccess; return ResultSuccess;

View file

@ -36,10 +36,9 @@ 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;
u32 __nx_fsdev_direntry_cache_size = 1;
/* TODO: Statically allocate PM resource thread stack, reduce this. */ #define INNER_HEAP_SIZE 0x4000
/* TODO: Determine what the minimum consistent value for this is (dump heap at runtime). */
#define INNER_HEAP_SIZE 0xC000
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];

View file

@ -32,6 +32,8 @@ extern "C" {
extern u32 __start__; extern u32 __start__;
u32 __nx_applet_type = AppletType_None; u32 __nx_applet_type = AppletType_None;
u32 __nx_fs_num_sessions = 1;
u32 __nx_fsdev_direntry_cache_size = 1;
#define INNER_HEAP_SIZE 0x4000 #define INNER_HEAP_SIZE 0x4000
size_t nx_inner_heap_size = INNER_HEAP_SIZE; size_t nx_inner_heap_size = INNER_HEAP_SIZE;