From db36201a666f314e527cc98ef1462955a6234c00 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 14 Sep 2024 09:47:35 -0700 Subject: [PATCH] Adds configuration for multithreaded saves --- .../Server/Serialization/SerializationThreadWorker.cs | 8 ++------ Projects/Server/World/World.cs | 8 +++++++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Projects/Server/Serialization/SerializationThreadWorker.cs b/Projects/Server/Serialization/SerializationThreadWorker.cs index 6936603f9..d01dca470 100644 --- a/Projects/Server/Serialization/SerializationThreadWorker.cs +++ b/Projects/Server/Serialization/SerializationThreadWorker.cs @@ -22,6 +22,7 @@ namespace Server; public class SerializationThreadWorker { + private const int MinHeapSize = 1024 * 1024; // 1MB private readonly int _index; private readonly Thread _thread; private readonly AutoResetEvent _startEvent; // Main thread tells the thread to start working @@ -60,12 +61,7 @@ public void Exit() Sleep(); } - public void AllocateHeap() => _heap ??= GC.AllocateUninitializedArray(1024 * 1024); // 1MB - - public void DeallocateHeap() - { - _heap = null; - } + public void AllocateHeap() => _heap ??= GC.AllocateUninitializedArray(MinHeapSize); // 1MB [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Push(IGenericSerializable entity) => _entities.Enqueue(entity); diff --git a/Projects/Server/World/World.cs b/Projects/Server/World/World.cs index bc598c6c2..234c76d0b 100644 --- a/Projects/Server/World/World.cs +++ b/Projects/Server/World/World.cs @@ -45,7 +45,7 @@ public static class World private static readonly GenericEntityPersistence _guildPersistence = new("Guilds", 3, 1, 0x7FFFFFFF); private static int _threadId; - internal static readonly SerializationThreadWorker[] _threadWorkers = new SerializationThreadWorker[Math.Max(Environment.ProcessorCount - 1, 1)]; + internal static SerializationThreadWorker[] _threadWorkers; private static readonly ManualResetEvent _diskWriteHandle = new(true); private static readonly ConcurrentQueue _decayQueue = new(); @@ -88,6 +88,7 @@ public static Serial NewVirtual public static Dictionary Mobiles => _mobilePersistence.EntitiesBySerial; public static Dictionary Guilds => _guildPersistence.EntitiesBySerial; + public static bool UseMultiThreadedSaves { get; private set; } public static string SavePath { get; private set; } public static WorldState WorldState { get; private set; } public static bool Saving => WorldState == WorldState.Saving; @@ -101,6 +102,8 @@ public static void Configure() var savePath = ServerConfiguration.GetOrUpdateSetting("world.savePath", "Saves"); SavePath = PathUtility.GetFullPath(savePath); + + UseMultiThreadedSaves = ServerConfiguration.GetOrUpdateSetting("world.useMultithreadedSaves", true); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -204,6 +207,9 @@ public static void Load() ); // Create the serialization threads. + var threadCount = UseMultiThreadedSaves ? Math.Max(Environment.ProcessorCount - 1, 1) : 1; + _threadWorkers = new SerializationThreadWorker[threadCount]; + for (var i = 0; i < _threadWorkers.Length; i++) { _threadWorkers[i] = new SerializationThreadWorker(i);