From d9cdfc536071bf65dfa6c166f4cf94c27a751f9e Mon Sep 17 00:00:00 2001 From: zznty <94796179+zznty@users.noreply.github.com> Date: Fri, 30 Aug 2024 00:14:01 +0700 Subject: [PATCH] use dotnet thread pool for keen parallel cringe --- CringeLauncher/Launcher.cs | 23 +++++--- CringeLauncher/Utils/ThreadPoolScheduler.cs | 60 +++++++++++++++++++++ 2 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 CringeLauncher/Utils/ThreadPoolScheduler.cs diff --git a/CringeLauncher/Launcher.cs b/CringeLauncher/Launcher.cs index c60e71f..ac94204 100644 --- a/CringeLauncher/Launcher.cs +++ b/CringeLauncher/Launcher.cs @@ -1,4 +1,5 @@ -using HarmonyLib; +using CringeLauncher.Utils; +using HarmonyLib; using Sandbox; using Sandbox.Engine.Multiplayer; using Sandbox.Engine.Networking; @@ -71,7 +72,8 @@ public class Launcher : IDisposable PluginLoader.Main.Instance.Splash?.SetBarValue(.75f); SpaceEngineersGame.SetupPerGameSettings(); ConfigureSettings(); - MySandboxGame.InitMultithreading(); + // MySandboxGame.InitMultithreading(); + InitThreadPool(); PluginLoader.Main.Instance.Splash?.SetBarValue(.85f); MyVRage.Platform.System.OnThreadpoolInitialized(); InitRender(); @@ -80,15 +82,20 @@ public class Launcher : IDisposable _game = new(args); PluginLoader.Main.Instance.Splash?.SetText("Launching..."); } - + public void Run() => _game?.Run(); -#region Keen shit + #region Keen shit -private static void ConfigureSettings() -{ - MyPlatformGameSettings.ENABLE_LOGOS = false; -} + private static void InitThreadPool() + { + ParallelTasks.Parallel.Scheduler = new ThreadPoolScheduler(); + } + + private static void ConfigureSettings() + { + MyPlatformGameSettings.ENABLE_LOGOS = false; + } private static void InitTexts() { diff --git a/CringeLauncher/Utils/ThreadPoolScheduler.cs b/CringeLauncher/Utils/ThreadPoolScheduler.cs new file mode 100644 index 0000000..8d1ded7 --- /dev/null +++ b/CringeLauncher/Utils/ThreadPoolScheduler.cs @@ -0,0 +1,60 @@ +using System.Diagnostics; +using System.Reflection; +using HarmonyLib; +using Havok; +using ParallelTasks; +using CringeTask = ParallelTasks.Task; + +namespace CringeLauncher.Utils; + +public class ThreadPoolScheduler : IWorkScheduler +{ + public void Schedule(CringeTask item) + { + ThreadPool.UnsafeQueueUserWorkItem(new ThreadPoolWorkItemTask(item), false); + } + + public bool WaitForTasksToFinish(TimeSpan waitTimeout) => true; + + public void ScheduleOnEachWorker(Action action) + { + } + + public int ReadAndClearExecutionTime() => 0; + + public void SuspendThreads(TimeSpan waitTimeout) + { + } + + public void ResumeThreads() + { + } + + public int ThreadCount { get; } = ThreadPool.ThreadCount; +} + +[HarmonyPatch] +internal class ThreadPoolWorkItemTask(CringeTask task) : IThreadPoolWorkItem +{ + public void Execute() + { + if (HkBaseSystem.IsInitialized && !HkBaseSystem.IsThreadInitialized) + HkBaseSystem.InitThread(Thread.CurrentThread.Name); + + task.Execute(); + } + + private static MethodBase TargetMethod() + { + var type = Type.GetType("System.Threading.PortableThreadPool+WorkerThread, System.Private.CoreLib", true); + return AccessTools.DeclaredMethod(type, "WorkerThreadStart"); + } + + private static void Postfix() + { + if (!HkBaseSystem.IsInitialized || !HkBaseSystem.IsThreadInitialized) return; + + HkBaseSystem.QuitThread(); + Debug.WriteLine($"Hk Shutdown for {Thread.CurrentThread.Name}"); + } +} \ No newline at end of file