From eda561298ef85aaba00ddec32ef0777fcfe1df6e Mon Sep 17 00:00:00 2001 From: L3tum <9307432+L3tum@users.noreply.github.com> Date: Thu, 22 Oct 2020 11:03:26 +0200 Subject: [PATCH] Fix: Support X86 Windows Environments in ThreadAffinity.cs Ref: #19 --- HardwareInformation.sln | 4 +- .../HardwareInformation.csproj | 2 + HardwareInformation/ThreadAffinity.cs | 194 ++++++++++-------- 3 files changed, 110 insertions(+), 90 deletions(-) diff --git a/HardwareInformation.sln b/HardwareInformation.sln index 9c0279b..7206308 100644 --- a/HardwareInformation.sln +++ b/HardwareInformation.sln @@ -20,10 +20,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E1B535FC-D186-47C7-AFE3-70BC051A7CF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E1B535FC-D186-47C7-AFE3-70BC051A7CF4}.Debug|Any CPU.Build.0 = Debug|Any CPU {E1B535FC-D186-47C7-AFE3-70BC051A7CF4}.Release|Any CPU.ActiveCfg = Release|Any CPU {E1B535FC-D186-47C7-AFE3-70BC051A7CF4}.Release|Any CPU.Build.0 = Release|Any CPU + {E1B535FC-D186-47C7-AFE3-70BC051A7CF4}.Debug|Any CPU.ActiveCfg = Debug|X86 + {E1B535FC-D186-47C7-AFE3-70BC051A7CF4}.Debug|Any CPU.Build.0 = Debug|X86 {B2FFFB2B-A4C7-4E38-A8FE-FF5467317FBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B2FFFB2B-A4C7-4E38-A8FE-FF5467317FBC}.Debug|Any CPU.Build.0 = Debug|Any CPU {B2FFFB2B-A4C7-4E38-A8FE-FF5467317FBC}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/HardwareInformation/HardwareInformation.csproj b/HardwareInformation/HardwareInformation.csproj index 62829ad..a8a97f4 100644 --- a/HardwareInformation/HardwareInformation.csproj +++ b/HardwareInformation/HardwareInformation.csproj @@ -12,6 +12,8 @@ false sgKey.snk .NET Standard 2 Cross-Platform Hardware Information Gatherer + Debug;Release + AnyCPU;X86 diff --git a/HardwareInformation/ThreadAffinity.cs b/HardwareInformation/ThreadAffinity.cs index e3ef487..003fbf4 100644 --- a/HardwareInformation/ThreadAffinity.cs +++ b/HardwareInformation/ThreadAffinity.cs @@ -9,119 +9,137 @@ namespace HardwareInformation { - internal static class ThreadAffinity - { - internal static ulong Set(ulong mask = 0xffffffffuL) - { - if (mask == 0) - return 0; + internal static class ThreadAffinity + { + internal static ulong Set(ulong mask = 0xffffffffuL) + { + if (mask == 0) + { + return 0; + } + + var x86Mask = (uint) mask; var returnMask = 0xffffffffuL; + // Unix/POSIX if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - // Unix/Posix - ulong result = 0; - if (NativeMethods.sched_getaffinity(0, (IntPtr) Marshal.SizeOf(result), - ref result) != 0) - return 0; - if (NativeMethods.sched_setaffinity(0, (IntPtr) Marshal.SizeOf(mask), - ref mask) != 0) - return 0; - return result; - } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + ulong result = 0; + if (NativeMethods.sched_getaffinity(0, (IntPtr) Marshal.SizeOf(result), + ref result) != 0) + { + return 0; + } + + if (NativeMethods.sched_setaffinity(0, (IntPtr) Marshal.SizeOf(mask), + ref mask) != 0) + { + return 0; + } + + return result; + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { // OSX return returnMask; } - + // Windows - var threads = Process.GetCurrentProcess().Threads; - - foreach (ProcessThread processThread in threads) - { - var threadId = NativeMethods.GetCurrentThreadId(); - - if (processThread.Id == threadId) - { - try - { - processThread.ProcessorAffinity = (IntPtr) mask; - } - catch (Win32Exception) - { - //Console.WriteLine("{0} with mask {1}", e.Message, GetIntBinaryString(mask)); - // Intentionally left blank - } - } - } - - //Console.WriteLine("Mask worked {0}", GetIntBinaryString(mask)); - - return returnMask; - } - - private static string GetIntBinaryString(ulong n) - { - var b = new char[64]; - var pos = 63; - var i = 0; - - while (i < 64) - { - if ((n & (1uL << i)) != 0) - { - b[pos] = '1'; - } - else - { - b[pos] = '0'; - } - - pos--; - i++; - } - - return new string(b); - } - - private static class NativeMethods - { - private const string KERNEL = "kernel32.dll"; - - private const string LIBC = "libc"; - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern int GetCurrentThreadId(); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern int GetLastError(); + var threads = Process.GetCurrentProcess().Threads; + + foreach (ProcessThread processThread in threads) + { + var threadId = NativeMethods.GetCurrentThreadId(); + + if (processThread.Id == threadId) + { + try + { + processThread.ProcessorAffinity = (IntPtr) (Environment.Is64BitProcess ? mask : x86Mask); + } + catch (Win32Exception) + { + //Console.WriteLine("{0} with mask {1}", e.Message, GetIntBinaryString(mask)); + // Intentionally left blank + } + catch (OverflowException) + { + // Intentionally left blank + } + + break; + } + } + + //Console.WriteLine("Mask worked {0}", GetIntBinaryString(mask)); + + return returnMask; + } + + private static string GetIntBinaryString(ulong n) + { + var b = new char[64]; + var pos = 63; + var i = 0; + + while (i < 64) + { + if ((n & (1uL << i)) != 0) + { + b[pos] = '1'; + } + else + { + b[pos] = '0'; + } + + pos--; + i++; + } + + return new string(b); + } + + private static class NativeMethods + { + private const string KERNEL = "kernel32.dll"; + + private const string LIBC = "libc"; + + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] + public static extern int GetCurrentThreadId(); + + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] + public static extern int GetLastError(); /// - /// If pid is zero, then the calling thread is used. + /// If pid is zero, then the calling thread is used. /// /// /// /// /// - [DllImport(LIBC)] - public static extern int sched_getaffinity(int pid, IntPtr maskSize, - ref ulong mask); + [DllImport(LIBC)] + public static extern int sched_getaffinity(int pid, IntPtr maskSize, + ref ulong mask); /// - /// If pid is zero, then the calling thread is used. + /// If pid is zero, then the calling thread is used. /// /// /// /// /// [DllImport(LIBC)] - public static extern int sched_setaffinity(int pid, IntPtr maskSize, - ref ulong mask); + public static extern int sched_setaffinity(int pid, IntPtr maskSize, + ref ulong mask); [DllImport(LIBC, CharSet = CharSet.Unicode)] - public static extern int sysctlbyname(string function, ref Int32 coreCount, ref Int32 length, int newP = 0, int newPLength = 0); - + public static extern int sysctlbyname(string function, ref int coreCount, ref int length, int newP = 0, + int newPLength = 0); } - } + } } \ No newline at end of file