From 63cbe9edaefc67e7da3cff92655dd389d758b482 Mon Sep 17 00:00:00 2001 From: Greg Date: Fri, 17 Feb 2023 16:30:32 -0700 Subject: [PATCH] Add thread pool --- Orbis Suite 3.0.sln | 19 ------ Playstation/OrbisLibAPI/Debug.cpp | 8 +-- Playstation/OrbisLibAPI/OrbisLibAPI.vcxproj | 2 + .../OrbisLibAPI/OrbisLibAPI.vcxproj.filters | 6 ++ Playstation/OrbisLibAPI/SocketListener.cpp | 48 +++---------- Playstation/OrbisLibAPI/SocketListener.h | 4 +- Playstation/OrbisLibAPI/SystemMonitor.cpp | 13 ++-- Playstation/OrbisLibAPI/SystemMonitor.h | 2 +- Playstation/OrbisLibAPI/ThreadPool.cpp | 67 +++++++++++++++++++ Playstation/OrbisLibAPI/ThreadPool.h | 23 +++++++ Playstation/OrbisLibAPI/Utilities.cpp | 19 ++++++ Playstation/OrbisLibAPI/Utilities.h | 1 + Playstation/OrbisLibAPI/Version.h | 22 +++--- Playstation/OrbisLibAPI/main.cpp | 32 +++------ 14 files changed, 156 insertions(+), 110 deletions(-) create mode 100644 Playstation/OrbisLibAPI/ThreadPool.cpp create mode 100644 Playstation/OrbisLibAPI/ThreadPool.h diff --git a/Orbis Suite 3.0.sln b/Orbis Suite 3.0.sln index 2bcdfb3..7b88266 100644 --- a/Orbis Suite 3.0.sln +++ b/Orbis Suite 3.0.sln @@ -51,8 +51,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrbisLib2", "Windows\Librar EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OrbisPeeknPoke", "Windows\OrbisPeeknPoke\OrbisPeeknPoke.csproj", "{90180080-9585-499C-99A8-6F4D1725CAF4}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OrbisMonitor", "Playstation\OrbisMonitor\OrbisMonitor.vcxproj", "{95716BEC-FF5A-4666-B8FE-547512CA38E0}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -257,22 +255,6 @@ Global {90180080-9585-499C-99A8-6F4D1725CAF4}.Release|x64.Build.0 = Release|Any CPU {90180080-9585-499C-99A8-6F4D1725CAF4}.Release|x86.ActiveCfg = Release|Any CPU {90180080-9585-499C-99A8-6F4D1725CAF4}.Release|x86.Build.0 = Release|Any CPU - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Debug|Any CPU.ActiveCfg = Debug|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Debug|Any CPU.Build.0 = Debug|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Debug|Win32.ActiveCfg = Debug|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Debug|Win32.Build.0 = Debug|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Debug|x64.ActiveCfg = Debug|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Debug|x64.Build.0 = Debug|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Debug|x86.ActiveCfg = Debug|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Debug|x86.Build.0 = Debug|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Release|Any CPU.ActiveCfg = Release|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Release|Any CPU.Build.0 = Release|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Release|Win32.ActiveCfg = Release|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Release|Win32.Build.0 = Release|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Release|x64.ActiveCfg = Release|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Release|x64.Build.0 = Release|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Release|x86.ActiveCfg = Release|x64 - {95716BEC-FF5A-4666-B8FE-547512CA38E0}.Release|x86.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -292,7 +274,6 @@ Global {F0E3446E-D9D7-4F44-AC98-797C5124BE91} = {8E8E4C8D-E3E1-4CB9-BD78-7ADAB2F2CF45} {75BA171D-708A-40AA-A27D-57150E5DFB7B} = {72E29C1E-8723-4885-A5ED-BD3A929D81B6} {90180080-9585-499C-99A8-6F4D1725CAF4} = {8F0E1457-FB1E-47A4-9DA8-74A6B757CAA4} - {95716BEC-FF5A-4666-B8FE-547512CA38E0} = {8E8E4C8D-E3E1-4CB9-BD78-7ADAB2F2CF45} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B6EE1D0-5ADF-44A2-B6EE-E5C8E110EE47} diff --git a/Playstation/OrbisLibAPI/Debug.cpp b/Playstation/OrbisLibAPI/Debug.cpp index 92d77cd..bf7926b 100644 --- a/Playstation/OrbisLibAPI/Debug.cpp +++ b/Playstation/OrbisLibAPI/Debug.cpp @@ -4,6 +4,7 @@ #include "GeneralIPC.h" #include "Events.h" #include +#include "ThreadPool.h" #define HelperPrxPath "/data/Orbis Suite/OrbisLibGeneralHelper.sprx" @@ -171,11 +172,6 @@ Thread_Exit: return nullptr; } -void* Debug::ProcessMonotorThreadHelper(void* tdParam) -{ - return ((Debug*)tdParam)->ProcessMonotorThread(); -} - void Debug::Attach(OrbisNetId Sock) { auto pid = RecieveInt(Sock); @@ -231,7 +227,7 @@ void Debug::Attach(OrbisNetId Sock) CurrentPID = pid; // Create thread to monitor the state of the running process. - scePthreadCreate(&ProcMonitorThreadHandle, NULL, &ProcessMonotorThreadHelper, this, "Process Monitor Thread"); + ThreadPool::QueueJob([this] { ProcessMonotorThread(); }); // release the lock. scePthreadMutexUnlock(&DebugMutex); diff --git a/Playstation/OrbisLibAPI/OrbisLibAPI.vcxproj b/Playstation/OrbisLibAPI/OrbisLibAPI.vcxproj index 0cf8919..5cd8719 100644 --- a/Playstation/OrbisLibAPI/OrbisLibAPI.vcxproj +++ b/Playstation/OrbisLibAPI/OrbisLibAPI.vcxproj @@ -79,6 +79,7 @@ del /s /q /f $(IntDir)\*.oelf + @@ -103,6 +104,7 @@ del /s /q /f $(IntDir)\*.oelf + diff --git a/Playstation/OrbisLibAPI/OrbisLibAPI.vcxproj.filters b/Playstation/OrbisLibAPI/OrbisLibAPI.vcxproj.filters index e449255..baa43f8 100644 --- a/Playstation/OrbisLibAPI/OrbisLibAPI.vcxproj.filters +++ b/Playstation/OrbisLibAPI/OrbisLibAPI.vcxproj.filters @@ -102,6 +102,9 @@ Source Files\API + + Source Files\Utilities + @@ -173,5 +176,8 @@ Header Files\API + + Header Files\Utilities + \ No newline at end of file diff --git a/Playstation/OrbisLibAPI/SocketListener.cpp b/Playstation/OrbisLibAPI/SocketListener.cpp index db7eddc..bd6a717 100644 --- a/Playstation/OrbisLibAPI/SocketListener.cpp +++ b/Playstation/OrbisLibAPI/SocketListener.cpp @@ -1,25 +1,8 @@ #include "Common.h" +#include "ThreadPool.h" #include "SocketListener.h" -void* SocketListener::ClientThread(void* tdParam) -{ - ClientThreadParams* Params = (ClientThreadParams*)tdParam; - SocketListener* socketListener = Params->socketListener; - OrbisNetId Sock = Params->Sock; - OrbisNetInAddr sin_addr = Params->sin_addr; - - socketListener->ClientCallBack(socketListener->tdParam, Sock, sin_addr); - - sceNetSocketClose(Sock); - delete Params; - - // Kill our thread and exit. - scePthreadDetach(scePthreadSelf()); - scePthreadExit(NULL); - return nullptr; -} - -void* SocketListener::DoWork() +void SocketListener::ListenThread() { OrbisNetSockaddrIn addr = { 0 }; addr.sin_family = ORBIS_NET_AF_INET; @@ -91,16 +74,11 @@ void* SocketListener::DoWork() int optval = 1; sceNetSetsockopt(ClientSocket, ORBIS_NET_SOL_SOCKET, ORBIS_NET_SO_NOSIGPIPE, &optval, sizeof(optval)); - // Set up thread params. - ClientThreadParams* Params = new ClientThreadParams(); - Params->socketListener = this; - Params->Sock = ClientSocket; - Params->sin_addr = ClientAddr.sin_addr; - - // Create Thread to handle connection. - OrbisPthread Thread; - scePthreadCreate(&Thread, NULL, &ClientThread, Params, "Client Thread"); - scePthreadDetach(Thread); + ThreadPool::QueueJob([=] + { + ClientCallBack(tdParam, ClientSocket, ClientAddr.sin_addr); + sceNetSocketClose(ClientSocket); + }); // Reset ClientSocket. ClientSocket = -1; @@ -116,15 +94,6 @@ Cleanup: // Clean up. sceNetSocketClose(this->Socket); - - // Kill our thread and exit. - scePthreadExit(NULL); - return nullptr; -} - -void* SocketListener::ListenThread(void* tdParam) -{ - return ((SocketListener*)tdParam)->DoWork(); } SocketListener::SocketListener(void(*ClientCallBack)(void* tdParam, OrbisNetId Sock, OrbisNetInAddr sin_addr), void* tdParam, unsigned short Port) @@ -135,7 +104,7 @@ SocketListener::SocketListener(void(*ClientCallBack)(void* tdParam, OrbisNetId S this->ThreadCleanedUp = false; this->Port = Port; - scePthreadCreate(&ListenThreadHandle, NULL, &ListenThread, this, "Listen Thread"); + ThreadPool::QueueJob([this] { ListenThread(); }); } SocketListener::~SocketListener() @@ -143,7 +112,6 @@ SocketListener::~SocketListener() klog("~Socket Listener.\n"); this->ServerRunning = false; - scePthreadJoin(ListenThreadHandle, nullptr); klog("Destruction sucessful.\n"); } \ No newline at end of file diff --git a/Playstation/OrbisLibAPI/SocketListener.h b/Playstation/OrbisLibAPI/SocketListener.h index 9669e37..285697b 100644 --- a/Playstation/OrbisLibAPI/SocketListener.h +++ b/Playstation/OrbisLibAPI/SocketListener.h @@ -12,11 +12,9 @@ private: unsigned short Port; OrbisPthread ListenThreadHandle; - void* DoWork(); - static void* ClientThread(void* tdParam); + void ListenThread(); void* tdParam; void(*ClientCallBack)(void* tdParam, OrbisNetId Sock, OrbisNetInAddr sin_addr); - static void* ListenThread(void* tdParam); public: struct ClientThreadParams diff --git a/Playstation/OrbisLibAPI/SystemMonitor.cpp b/Playstation/OrbisLibAPI/SystemMonitor.cpp index efe91c9..109d353 100644 --- a/Playstation/OrbisLibAPI/SystemMonitor.cpp +++ b/Playstation/OrbisLibAPI/SystemMonitor.cpp @@ -1,5 +1,6 @@ #include "Common.h" #include "SystemMonitor.h" +#include "ThreadPool.h" OrbisPthread SystemMonitor::ThreadId; int SystemMonitor::Thread_Count = 0; @@ -98,9 +99,9 @@ void SystemMonitor::Get_Page_Table_Stats(int vm, int type, int* Used, int* Free, *Total = _Total; } -void* SystemMonitor::MonitorThread(void* args) +void SystemMonitor::MonitorThread() { - //klog("[System Monitor] Thread Started\n"); + klog("[System Monitor] Thread Started\n"); unsigned int Idle_Thread_ID[8]; @@ -168,23 +169,17 @@ void* SystemMonitor::MonitorThread(void* args) sceKernelSleep(2); } - Should_Run_Thread = true; klog("[System Monitor] Thread Shutdown.\n"); - void* res; - scePthreadExit(res); - return res; } void SystemMonitor::Init() { klog("[System Monitor] Starting System Monitor Thread...\n"); - scePthreadCreate(&ThreadId, nullptr, MonitorThread, NULL, "System Monitor Thread"); - scePthreadDetach(ThreadId); + ThreadPool::QueueJob([] { MonitorThread(); }); } void SystemMonitor::Term() { Should_Run_Thread = false; - scePthreadJoin(ThreadId, nullptr); } \ No newline at end of file diff --git a/Playstation/OrbisLibAPI/SystemMonitor.h b/Playstation/OrbisLibAPI/SystemMonitor.h index 16f00e2..e3e306e 100644 --- a/Playstation/OrbisLibAPI/SystemMonitor.h +++ b/Playstation/OrbisLibAPI/SystemMonitor.h @@ -40,6 +40,6 @@ private: static void CalculateCpuUsage(unsigned int idle_tid[8], threadUsage* cur, threadUsage* prev, float usage_out[8]); static void Get_Page_Table_Stats(int vm, int type, int* Used, int* Free, int* Total); - static void* MonitorThread(void* args); + static void MonitorThread(); }; \ No newline at end of file diff --git a/Playstation/OrbisLibAPI/ThreadPool.cpp b/Playstation/OrbisLibAPI/ThreadPool.cpp new file mode 100644 index 0000000..46169b6 --- /dev/null +++ b/Playstation/OrbisLibAPI/ThreadPool.cpp @@ -0,0 +1,67 @@ +#include "Common.h" +#include "ThreadPool.h" + +bool ThreadPool::ShouldRun; +std::mutex ThreadPool::JobQueueMtx; +std::condition_variable ThreadPool::MtxCondition; +std::vector ThreadPool::ThreadsPool; +std::queue> ThreadPool::JobQueue; + +void ThreadPool::WorkingLoop() +{ + while (true) + { + std::function job; + { + std::unique_lock lock(JobQueueMtx); + MtxCondition.wait(lock, + [] + { + return !JobQueue.empty() || !ShouldRun; + }); + + if (!ShouldRun) + return; + + job = JobQueue.front(); + JobQueue.pop(); + } + job(); + } +} + +void ThreadPool::Init(int poolSize) +{ + ShouldRun = true; + ThreadsPool.resize(poolSize); + for (int i = 0; i < poolSize; i++) + { + ThreadsPool.at(i) = std::thread(WorkingLoop); + } +} + +void ThreadPool::Term() +{ + { + std::unique_lock lock(JobQueueMtx); + ShouldRun = false; + } + + MtxCondition.notify_all(); + + for (std::thread& activeThread : ThreadsPool) + { + activeThread.join(); + } + + ThreadsPool.clear(); +} + +void ThreadPool::QueueJob(const std::function& job) +{ + { + std::unique_lock lock(JobQueueMtx); + JobQueue.push(job); + } + MtxCondition.notify_one(); +} \ No newline at end of file diff --git a/Playstation/OrbisLibAPI/ThreadPool.h b/Playstation/OrbisLibAPI/ThreadPool.h new file mode 100644 index 0000000..81a2362 --- /dev/null +++ b/Playstation/OrbisLibAPI/ThreadPool.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include +#include +#include + +class ThreadPool +{ +public: + static void Init(int poolSize); + static void Term(); + static void QueueJob(const std::function& job); + +private: + static void WorkingLoop(); + + static bool ShouldRun; + static std::mutex JobQueueMtx; + static std::condition_variable MtxCondition; + static std::vector ThreadsPool; + static std::queue> JobQueue; +}; diff --git a/Playstation/OrbisLibAPI/Utilities.cpp b/Playstation/OrbisLibAPI/Utilities.cpp index 14661d2..c61c476 100644 --- a/Playstation/OrbisLibAPI/Utilities.cpp +++ b/Playstation/OrbisLibAPI/Utilities.cpp @@ -351,4 +351,23 @@ bool LinkDir(const char* Dir, const char* LinkedDir) } return true; +} + +bool LoadToolbox() +{ + // Mount data & hostapp into ShellUI sandbox + LinkDir("/data/", "/mnt/sandbox/NPXS20001_000/data"); + LinkDir("/hostapp/", "/mnt/sandbox/NPXS20001_000/hostapp"); + + auto handle = sys_sdk_proc_prx_load("SceShellUI", "/user/data/Orbis Toolbox/OrbisToolbox-2.0.sprx"); + if (handle > 0) { + klog("Orbis Toolbox loaded! %d\n", handle); + return true; + } + else + { + klog("error: %d\n", handle); + Notify("Failed to load Orbis Toolbox!"); + return false; + } } \ No newline at end of file diff --git a/Playstation/OrbisLibAPI/Utilities.h b/Playstation/OrbisLibAPI/Utilities.h index 5df6bc0..1e0fec2 100644 --- a/Playstation/OrbisLibAPI/Utilities.h +++ b/Playstation/OrbisLibAPI/Utilities.h @@ -37,3 +37,4 @@ struct kinfo_proc { void hexdump(void* ptr, int buflen); int GetProcessList(std::vector& ProcessList); bool LinkDir(const char* Dir, const char* LinkedDir); +bool LoadToolbox(); \ No newline at end of file diff --git a/Playstation/OrbisLibAPI/Version.h b/Playstation/OrbisLibAPI/Version.h index 0c023ef..3035a77 100644 --- a/Playstation/OrbisLibAPI/Version.h +++ b/Playstation/OrbisLibAPI/Version.h @@ -1,11 +1,11 @@ -#pragma once -#define ORBISLIB_MAJOR 3 -#define ORBISLIB_MINOR 0 -#define ORBISLIB_BUILDVERSION 1071 -#define stringify(a) stringify_(a) -#define stringify_(a) #a -#if defined(_DEBUG) -#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Dev Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__) -#else -#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__) -#endif +#pragma once +#define ORBISLIB_MAJOR 3 +#define ORBISLIB_MINOR 0 +#define ORBISLIB_BUILDVERSION 1089 +#define stringify(a) stringify_(a) +#define stringify_(a) #a +#if defined(_DEBUG) +#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Dev Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__) +#else +#define ORBISLIB_BUILDSTRING ("[OrbisLib Daemon " stringify(ORBISLIB_MAJOR) "." stringify(ORBISLIB_MINOR) "] Build " stringify(ORBISLIB_BUILDVERSION) " " __DATE__ " " __TIME__) +#endif diff --git a/Playstation/OrbisLibAPI/main.cpp b/Playstation/OrbisLibAPI/main.cpp index 4ff732a..5a3812b 100644 --- a/Playstation/OrbisLibAPI/main.cpp +++ b/Playstation/OrbisLibAPI/main.cpp @@ -4,6 +4,7 @@ #include "GoldHEN.h" #include "Events.h" #include +#include "ThreadPool.h" void exiting() { @@ -19,7 +20,7 @@ void exiting() API::Term(); // Terminate Thread Pool - + ThreadPool::Term(); } int main() @@ -49,41 +50,30 @@ int main() // Log the loaded version string. klog("\n%s\n\n", ORBISLIB_BUILDSTRING); + // Start up the thread pool. + ThreadPool::Init(100); + // Init a thread to monitor the system usage stats. // SystemMonitor::Init(); + // Set up the events. if (!Events::Init()) { Notify("Failed to init Events..."); sceSystemServiceLoadExec("exit", 0); return 0; } - - // Mount data & hostapp into ShellUI sandbox - LinkDir("/data/", "/mnt/sandbox/NPXS20001_000/data"); - LinkDir("/hostapp/", "/mnt/sandbox/NPXS20001_000/hostapp"); - -#define LOADTOOLBOX -#ifdef LOADTOOLBOX - auto handle = sys_sdk_proc_prx_load("SceShellUI", "/user/data/Orbis Toolbox/OrbisToolbox-2.0.sprx"); - if (handle > 0) { - klog("Orbis Toolbox loaded! %d\n", handle); - } - else + + // Load the tool box. + if (!LoadToolbox()) { - klog("error: %d\n", handle); - Notify("Failed to load Orbis Toolbox!"); + sceSystemServiceLoadExec("exit", 0); + return 0; } -#endif // start up the API. NOTE: this is blocking. API::Init(); - //#define KILLSHELLUI -#ifdef KILLSHELLUI - sceSystemServiceKillApp(sceLncUtilGetAppId("NPXS20001"), -1, 0, 0); -#endif - sceSystemServiceLoadExec("exit", 0); return 0;