Last active
February 24, 2021 15:15
-
-
Save seif/664bf7c2c7f860df5a2652611dd59cce to your computer and use it in GitHub Desktop.
Get real number of cpus on machine, ignoring any quotas/limits.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Utilities | |
{ | |
using System; | |
using System.Diagnostics; | |
using System.Runtime.InteropServices; | |
public static class Machine | |
{ | |
private const int MaximumNumberOfCpus = 128; | |
private static int? _processorCount; | |
/// <summary> | |
/// Returns the actual processor counts on the machine. | |
/// This was needed in docker because Environment.ProcessorCount was returning the cpu value taking into account | |
/// CPU limits set. | |
/// In order to check how many cpus actually exist on the machine, we loop from 0 to 127, asking libc to give us | |
/// the affinity of the current process to the cpuIndex. If the operation succeeds and we get a result, cpu exists | |
/// if it returns -1 then the operatin failed and cpu doesn't exist. | |
/// </summary> | |
public static int ProcessorCount | |
{ | |
get | |
{ | |
if (_processorCount.HasValue) | |
{ | |
return _processorCount.Value; | |
} | |
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) | |
{ | |
_processorCount = Environment.ProcessorCount; | |
return Environment.ProcessorCount; | |
} | |
else | |
{ | |
ulong count = 0; | |
ulong result = 0; | |
while (LibC.sched_getaffinity(Process.GetCurrentProcess().Id, (IntPtr)count, ref result) != 0 && count < MaximumNumberOfCpus) | |
{ | |
count++; | |
} | |
_processorCount = Math.Max((int)count, 1); | |
} | |
return _processorCount.Value; | |
} | |
} | |
} | |
internal static class LibC | |
{ | |
private const string DllName = "libc"; | |
/// <summary> | |
/// Calls libc sched_getaffinity https://linux.die.net/man/2/sched_getaffinity | |
/// </summary> | |
/// <param name="pid">The pid to get the affinity for</param> | |
/// <param name="cpuSetSize">Value passed is the index of the cpu</param> | |
/// <param name="affinityResult">The affinity of the current process to the cpu specified</param> | |
/// <returns>-1 on error, 0 on success</returns> | |
[DllImport(DllName)] | |
internal static extern int sched_getaffinity(int pid, IntPtr cpuSetSize, ref ulong affinityResult); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment