diff --git a/SS14.Watchdog/Components/ProcessManagement/ProcessManagerBasic.cs b/SS14.Watchdog/Components/ProcessManagement/ProcessManagerBasic.cs index 96c396e..b907efb 100644 --- a/SS14.Watchdog/Components/ProcessManagement/ProcessManagerBasic.cs +++ b/SS14.Watchdog/Components/ProcessManagement/ProcessManagerBasic.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Dapper; @@ -9,6 +10,7 @@ using Microsoft.Extensions.Options; using SS14.Watchdog.Components.DataManagement; using SS14.Watchdog.Components.ServerManagement; +using SS14.Watchdog.Configuration; namespace SS14.Watchdog.Components.ProcessManagement; @@ -69,6 +71,14 @@ public Task StartServer(IServerInstance instance, ProcessStartDa if (process == null) throw new Exception("No process was started??"); + + if (instance.CpuCores != null) + { + var affinity = instance.CpuCores.Aggregate(0L, (mask, core) => mask | (1L << core)); + process.ProcessorAffinity = (IntPtr)affinity; + _logger.LogDebug("Set processor affinity to {Affinity} for process {Pid}", + affinity, process.Id); + } } catch (Exception e) { diff --git a/SS14.Watchdog/Components/ServerManagement/IServerInstance.cs b/SS14.Watchdog/Components/ServerManagement/IServerInstance.cs index 0a8db7e..6a839b2 100644 --- a/SS14.Watchdog/Components/ServerManagement/IServerInstance.cs +++ b/SS14.Watchdog/Components/ServerManagement/IServerInstance.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -36,6 +37,13 @@ public interface IServerInstance /// string InstanceDir { get; } + /// + /// List of CPU cores to use for the server process. + /// If set, the process will be restricted to run only on the specified CPU cores. + /// Example: [0, 1] means use cores 0 and 1. + /// + IReadOnlyList? CpuCores { get; } + /// /// Server has sent a ping to the watchdog confirming that it is, in fact, still alive. /// diff --git a/SS14.Watchdog/Components/ServerManagement/ServerInstance.cs b/SS14.Watchdog/Components/ServerManagement/ServerInstance.cs index e166c80..4ebd1d5 100644 --- a/SS14.Watchdog/Components/ServerManagement/ServerInstance.cs +++ b/SS14.Watchdog/Components/ServerManagement/ServerInstance.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Net.Http; using System.Security.Cryptography; @@ -63,6 +64,8 @@ public sealed partial class ServerInstance : IServerInstance private IProcessHandle? _runningServer; + public IReadOnlyList? CpuCores => _instanceConfig.CpuCores; + public ServerInstance(string key, InstanceConfiguration instanceConfig, IConfiguration configuration, diff --git a/SS14.Watchdog/Configuration/InstanceConfiguration.cs b/SS14.Watchdog/Configuration/InstanceConfiguration.cs index f5518e0..c7d0db9 100644 --- a/SS14.Watchdog/Configuration/InstanceConfiguration.cs +++ b/SS14.Watchdog/Configuration/InstanceConfiguration.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; using JetBrains.Annotations; using Microsoft.Diagnostics.NETCore.Client; @@ -47,5 +48,12 @@ public sealed class InstanceConfiguration /// [UsedImplicitly] public Dictionary EnvironmentVariables { get; set; } = new(); + + /// + /// List of CPU cores to use for the server process. + /// If set, the process will be restricted to run only on the specified CPU cores. + /// Example: [0, 1] means use cores 0 and 1. + /// + public List? CpuCores { get; set; } } }