From 39e9d2f7c28a22c6d582d1409e821e2c26ad1df7 Mon Sep 17 00:00:00 2001 From: William LaFrance Date: Thu, 8 Oct 2026 21:30:14 -0500 Subject: [PATCH 1/2] Stop the idle loop in Main from polling every millisecond The loop that waits for Program.Exit used Task.Delay(1) followed by Task.Yield(), which woke the thread pool about a thousand times a second. An idle atlasd (no clients connected) used about 32% of a core on macOS/.NET 10; with a 250ms delay it uses about 1.3%. Shutdown reacts within 250ms. Co-Authored-By: Claude Sonnet 5.5 --- src/Atlasd/Program.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Atlasd/Program.cs b/src/Atlasd/Program.cs index 32cbd4d5..24ccdd50 100644 --- a/src/Atlasd/Program.cs +++ b/src/Atlasd/Program.cs @@ -60,8 +60,7 @@ public static async Task Main(string[] args) while (!Exit) { - await Task.Delay(1); - await Task.Yield(); + await Task.Delay(250); } return ExitCode; From c63c4c677ab05cd8452b75d61b1c778022ea9948 Mon Sep 17 00:00:00 2001 From: William LaFrance Date: Thu, 8 Oct 2026 21:39:58 -0500 Subject: [PATCH 2/2] Check the null and ping timers once a second instead of ten times NullTimer sends SID_NULL every 60 seconds and PingTimer sends SID_PING every 180 seconds, but both fired every 100ms, and PingTimer reads a setting and allocates a message and a Random on every tick. A one second period is still far finer than the intervals they enforce. Idle atlasd (no clients, 250ms idle loop) went from about 1.5% of a core to about 0.5%. Co-Authored-By: Claude Sonnet 5.5 --- src/Atlasd/Battlenet/Common.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Atlasd/Battlenet/Common.cs b/src/Atlasd/Battlenet/Common.cs index f8318235..0505fb82 100644 --- a/src/Atlasd/Battlenet/Common.cs +++ b/src/Atlasd/Battlenet/Common.cs @@ -111,8 +111,8 @@ public static void Initialize() DefaultPort = 6112; InitializeListener(); - NullTimer = new Timer(ProcessNullTimer, ActiveGameStates, 100, 100); - PingTimer = new Timer(ProcessPingTimer, ActiveGameStates, 100, 100); + NullTimer = new Timer(ProcessNullTimer, ActiveGameStates, 1000, 1000); + PingTimer = new Timer(ProcessPingTimer, ActiveGameStates, 1000, 1000); ScheduledShutdown = new ShutdownEvent(null, true, DateTime.MinValue, null);