# HG changeset patch # User moel.mich # Date 1288822066 0 # Node ID bddc6e01840aaf1be03034172c127364e424325c # Parent 9bf70d316cea371f1ebd3add52c398b2c078aa3c Added CPUID support for Linux. diff -r 9bf70d316cea -r bddc6e01840a Hardware/CPU/AMD0FCPU.cs --- a/Hardware/CPU/AMD0FCPU.cs Mon Nov 01 20:44:21 2010 +0000 +++ b/Hardware/CPU/AMD0FCPU.cs Wed Nov 03 22:07:46 2010 +0000 @@ -146,7 +146,7 @@ uint eax, edx; if (Ring0.RdmsrTx(FIDVID_STATUS, out eax, out edx, - (UIntPtr)(1L << cpuid[i][0].Thread))) { + 1UL << cpuid[i][0].Thread)) { // CurrFID can be found in eax bits 0-5, MaxFID in 16-21 // 8-13 hold StartFID, we don't use that here. double curMP = 0.5 * ((eax & 0x3F) + 8); diff -r 9bf70d316cea -r bddc6e01840a Hardware/CPU/AMD10CPU.cs --- a/Hardware/CPU/AMD10CPU.cs Mon Nov 01 20:44:21 2010 +0000 +++ b/Hardware/CPU/AMD10CPU.cs Wed Nov 03 22:07:46 2010 +0000 @@ -87,10 +87,8 @@ ActivateSensor(coreClocks[i]); } - // set affinity to the first thread for all frequency estimations - IntPtr thread = NativeMethods.GetCurrentThread(); - UIntPtr mask = NativeMethods.SetThreadAffinityMask(thread, - (UIntPtr)(1L << cpuid[0][0].Thread)); + // set affinity to the first thread for all frequency estimations + ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread); uint ctlEax, ctlEdx; Ring0.Rdmsr(PERF_CTL_0, out ctlEax, out ctlEdx); @@ -104,7 +102,7 @@ Ring0.Wrmsr(PERF_CTR_0, ctrEax, ctrEdx); // restore the thread affinity. - NativeMethods.SetThreadAffinityMask(thread, mask); + ThreadAffinity.Set(mask); Update(); } @@ -208,7 +206,7 @@ uint curEax, curEdx; if (Ring0.RdmsrTx(COFVID_STATUS, out curEax, out curEdx, - (UIntPtr)(1L << cpuid[i][0].Thread))) + 1UL << cpuid[i][0].Thread)) { // 8:6 CpuDid: current core divisor ID // 5:0 CpuFid: current core frequency ID @@ -232,16 +230,5 @@ } } } - - private static class NativeMethods { - private const string KERNEL = "kernel32.dll"; - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern UIntPtr - SetThreadAffinityMask(IntPtr handle, UIntPtr mask); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern IntPtr GetCurrentThread(); - } } } diff -r 9bf70d316cea -r bddc6e01840a Hardware/CPU/CPUGroup.cs --- a/Hardware/CPU/CPUGroup.cs Mon Nov 01 20:44:21 2010 +0000 +++ b/Hardware/CPU/CPUGroup.cs Wed Nov 03 22:07:46 2010 +0000 @@ -101,10 +101,6 @@ } public CPUGroup(ISettings settings) { - // No implementation for cpuid on Unix systems - int p = (int)Environment.OSVersion.Platform; - if ((p == 4) || (p == 128)) - return; CPUID[][] processorThreads = GetProcessorThreads(); this.threads = new CPUID[processorThreads.Length][][]; diff -r 9bf70d316cea -r bddc6e01840a Hardware/CPU/CPUID.cs --- a/Hardware/CPU/CPUID.cs Mon Nov 01 20:44:21 2010 +0000 +++ b/Hardware/CPU/CPUID.cs Wed Nov 03 22:07:46 2010 +0000 @@ -105,7 +105,7 @@ if (thread >= 32) throw new ArgumentOutOfRangeException("thread"); - UIntPtr mask = (UIntPtr)(1L << thread); + ulong mask = 1UL << thread; if (Opcode.CpuidTx(CPUID_0, 0, out eax, out ebx, out ecx, out edx, mask)) { diff -r 9bf70d316cea -r bddc6e01840a Hardware/CPU/GenericCPU.cs --- a/Hardware/CPU/GenericCPU.cs Mon Nov 01 20:44:21 2010 +0000 +++ b/Hardware/CPU/GenericCPU.cs Wed Nov 03 22:07:46 2010 +0000 @@ -130,8 +130,12 @@ } if (hasTimeStampCounter) { + ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread); + estimatedTimeStampCounterFrequency = - EstimateTimeStampCounterFrequency(); + EstimateTimeStampCounterFrequency(); + + ThreadAffinity.Set(mask); } else { estimatedTimeStampCounterFrequency = 0; } @@ -139,7 +143,7 @@ timeStampCounterFrequency = estimatedTimeStampCounterFrequency; } - private static double EstimateTimeStampCounterFrequency() { + private static double EstimateTimeStampCounterFrequency() { // preload the function EstimateTimeStampCounterFrequency(0); EstimateTimeStampCounterFrequency(0); @@ -148,6 +152,7 @@ List estimatedFrequency = new List(3); for (int i = 0; i < 3; i++) estimatedFrequency.Add(1e-6 * EstimateTimeStampCounterFrequency(0.025)); + estimatedFrequency.Sort(); return estimatedFrequency[1]; } @@ -156,7 +161,6 @@ long ticks = (long)(timeWindow * Stopwatch.Frequency); ulong countBegin, countEnd; - Thread.BeginThreadAffinity(); long timeBegin = Stopwatch.GetTimestamp() + (long)Math.Ceiling(0.001 * ticks); long timeEnd = timeBegin + ticks; @@ -164,7 +168,6 @@ countBegin = Opcode.Rdtsc(); while (Stopwatch.GetTimestamp() < timeEnd) { } countEnd = Opcode.Rdtsc(); - Thread.EndThreadAffinity(); return (((double)(countEnd - countBegin)) * Stopwatch.Frequency) / (timeEnd - timeBegin); @@ -173,7 +176,7 @@ private static void AppendMSRData(StringBuilder r, uint msr, int thread) { uint eax, edx; - if (Ring0.RdmsrTx(msr, out eax, out edx, (UIntPtr)(1L << thread))) { + if (Ring0.RdmsrTx(msr, out eax, out edx, 1UL << thread)) { r.Append(" "); r.Append((msr).ToString("X8", CultureInfo.InvariantCulture)); r.Append(" "); @@ -264,9 +267,7 @@ if (hasTimeStampCounter && isInvariantTimeStampCounter) { // make sure always the same thread is used - IntPtr thread = NativeMethods.GetCurrentThread(); - UIntPtr mask = NativeMethods.SetThreadAffinityMask(thread, - (UIntPtr)(1L << cpuid[0][0].Thread)); + ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread); // read time before and after getting the TSC to estimate the error long firstTime = Stopwatch.GetTimestamp(); @@ -274,7 +275,7 @@ long time = Stopwatch.GetTimestamp(); // restore the thread affinity mask - NativeMethods.SetThreadAffinityMask(thread, mask); + ThreadAffinity.Set(mask); double delta = ((double)(time - lastTime)) / Stopwatch.Frequency; double error = ((double)(time - firstTime)) / Stopwatch.Frequency; @@ -304,16 +305,5 @@ totalLoad.Value = cpuLoad.GetTotalLoad(); } } - - private static class NativeMethods { - private const string KERNEL = "kernel32.dll"; - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern UIntPtr - SetThreadAffinityMask(IntPtr handle, UIntPtr mask); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern IntPtr GetCurrentThread(); - } } } diff -r 9bf70d316cea -r bddc6e01840a Hardware/CPU/IntelCPU.cs --- a/Hardware/CPU/IntelCPU.cs Mon Nov 01 20:44:21 2010 +0000 +++ b/Hardware/CPU/IntelCPU.cs Wed Nov 03 22:07:46 2010 +0000 @@ -118,7 +118,7 @@ tjMax = new float[coreCount]; for (int i = 0; i < coreCount; i++) { if (Ring0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax, - out edx, (UIntPtr)(1L << cpuid[i][0].Thread))) { + out edx, 1UL << cpuid[i][0].Thread)) { tjMax[i] = (eax >> 16) & 0xFF; } else { tjMax[i] = 100; @@ -217,7 +217,7 @@ uint eax, edx; if (Ring0.RdmsrTx( IA32_THERM_STATUS_MSR, out eax, out edx, - (UIntPtr)(1L << cpuid[i][0].Thread))) { + 1UL << cpuid[i][0].Thread)) { // if reading is valid if ((eax & 0x80000000) != 0) { // get the dist from tjMax from bits 22:16 @@ -237,7 +237,7 @@ for (int i = 0; i < coreClocks.Length; i++) { System.Threading.Thread.Sleep(1); if (Ring0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx, - (UIntPtr)(1L << cpuid[i][0].Thread))) + 1UL << cpuid[i][0].Thread)) { newBusClock = TimeStampCounterFrequency / timeStampCounterMultiplier; diff -r 9bf70d316cea -r bddc6e01840a Hardware/Opcode.cs --- a/Hardware/Opcode.cs Mon Nov 01 20:44:21 2010 +0000 +++ b/Hardware/Opcode.cs Wed Nov 03 22:07:46 2010 +0000 @@ -37,17 +37,17 @@ using System; using System.Runtime.InteropServices; +using Mono.Unix.Native; namespace OpenHardwareMonitor.Hardware { internal static class Opcode { + private static IntPtr codeBuffer; + private static ulong size; - public static void Open() { - // No implementation for Unix systems + public static void Open() { int p = (int)Environment.OSVersion.Platform; - if ((p == 4) || (p == 128)) - return; - + byte[] rdtscCode; byte[] cpuidCode; if (IntPtr.Size == 4) { @@ -55,13 +55,25 @@ cpuidCode = CPUID_32; } else { rdtscCode = RDTSC_64; - cpuidCode = CPUID_64; + + if ((p == 4) || (p == 128)) { // Unix + cpuidCode = CPUID_64_LINUX; + } else { // Windows + cpuidCode = CPUID_64_WINDOWS; + } } - - codeBuffer = NativeMethods.VirtualAlloc(IntPtr.Zero, - (UIntPtr)(rdtscCode.Length + cpuidCode.Length), - AllocationType.COMMIT | AllocationType.RESERVE, - MemoryProtection.EXECUTE_READWRITE); + + size = (ulong)(rdtscCode.Length + cpuidCode.Length); + + if ((p == 4) || (p == 128)) { // Unix + codeBuffer = Syscall.mmap(IntPtr.Zero, size, + MmapProts.PROT_READ | MmapProts.PROT_WRITE | MmapProts.PROT_EXEC, + MmapFlags.MAP_ANONYMOUS | MmapFlags.MAP_PRIVATE, -1, 0); + } else { // Windows + codeBuffer = NativeMethods.VirtualAlloc(IntPtr.Zero, + (UIntPtr)size, AllocationType.COMMIT | AllocationType.RESERVE, + MemoryProtection.EXECUTE_READWRITE); + } Marshal.Copy(rdtscCode, 0, codeBuffer, rdtscCode.Length); @@ -72,15 +84,20 @@ Marshal.Copy(cpuidCode, 0, cpuidAddress, cpuidCode.Length); Cpuid = Marshal.GetDelegateForFunctionPointer( - cpuidAddress, typeof(CpuidDelegate)) as CpuidDelegate; + cpuidAddress, typeof(CpuidDelegate)) as CpuidDelegate; } public static void Close() { Rdtsc = null; Cpuid = null; - - NativeMethods.VirtualFree(codeBuffer, UIntPtr.Zero, - FreeType.RELEASE); + + int p = (int)Environment.OSVersion.Platform; + if ((p == 4) || (p == 128)) { // Unix + Syscall.munmap(codeBuffer, size); + } else { // Windows + NativeMethods.VirtualFree(codeBuffer, UIntPtr.Zero, + FreeType.RELEASE); + } } [UnmanagedFunctionPointer(CallingConvention.StdCall)] @@ -99,8 +116,8 @@ private static readonly byte[] RDTSC_64 = new byte[] { 0x0F, 0x31, // rdtsc - 0x48, 0xC1, 0xE2, 0x20, // shl rdx,20h - 0x48, 0x0B, 0xC2, // or rax,rdx + 0x48, 0xC1, 0xE2, 0x20, // shl rdx, 20h + 0x48, 0x0B, 0xC2, // or rax, rdx 0xC3 // ret }; @@ -125,71 +142,83 @@ private static readonly byte[] CPUID_32 = new byte[] { 0x55, // push ebp - 0x8B, 0xEC, // mov ebp,esp - 0x83, 0xEC, 0x10, // sub esp,10h - 0x8B, 0x45, 0x08, // mov eax,dword ptr [ebp+8] - 0x8B, 0x4D, 0x0C, // mov ecx,dword ptr [ebp+0Ch] + 0x8B, 0xEC, // mov ebp, esp + 0x83, 0xEC, 0x10, // sub esp, 10h + 0x8B, 0x45, 0x08, // mov eax, dword ptr [ebp+8] + 0x8B, 0x4D, 0x0C, // mov ecx, dword ptr [ebp+0Ch] 0x53, // push ebx 0x0F, 0xA2, // cpuid 0x56, // push esi - 0x8D, 0x75, 0xF0, // lea esi,[info] - 0x89, 0x06, // mov dword ptr [esi],eax - 0x8B, 0x45, 0x10, // mov eax,dword ptr [eax] - 0x89, 0x5E, 0x04, // mov dword ptr [esi+4],ebx - 0x89, 0x4E, 0x08, // mov dword ptr [esi+8],ecx - 0x89, 0x56, 0x0C, // mov dword ptr [esi+0Ch],edx - 0x8B, 0x4D, 0xF0, // mov ecx,dword ptr [info] - 0x89, 0x08, // mov dword ptr [eax],ecx - 0x8B, 0x45, 0x14, // mov eax,dword ptr [ebx] - 0x8B, 0x4D, 0xF4, // mov ecx,dword ptr [ebp-0Ch] - 0x89, 0x08, // mov dword ptr [eax],ecx - 0x8B, 0x45, 0x18, // mov eax,dword ptr [ecx] - 0x8B, 0x4D, 0xF8, // mov ecx,dword ptr [ebp-8] - 0x89, 0x08, // mov dword ptr [eax],ecx - 0x8B, 0x45, 0x1C, // mov eax,dword ptr [edx] - 0x8B, 0x4D, 0xFC, // mov ecx,dword ptr [ebp-4] + 0x8D, 0x75, 0xF0, // lea esi, [info] + 0x89, 0x06, // mov dword ptr [esi],eax + 0x8B, 0x45, 0x10, // mov eax, dword ptr [eax] + 0x89, 0x5E, 0x04, // mov dword ptr [esi+4], ebx + 0x89, 0x4E, 0x08, // mov dword ptr [esi+8], ecx + 0x89, 0x56, 0x0C, // mov dword ptr [esi+0Ch], edx + 0x8B, 0x4D, 0xF0, // mov ecx, dword ptr [info] + 0x89, 0x08, // mov dword ptr [eax], ecx + 0x8B, 0x45, 0x14, // mov eax, dword ptr [ebx] + 0x8B, 0x4D, 0xF4, // mov ecx, dword ptr [ebp-0Ch] + 0x89, 0x08, // mov dword ptr [eax], ecx + 0x8B, 0x45, 0x18, // mov eax, dword ptr [ecx] + 0x8B, 0x4D, 0xF8, // mov ecx, dword ptr [ebp-8] + 0x89, 0x08, // mov dword ptr [eax], ecx + 0x8B, 0x45, 0x1C, // mov eax, dword ptr [edx] + 0x8B, 0x4D, 0xFC, // mov ecx, dword ptr [ebp-4] 0x5E, // pop esi - 0x89, 0x08, // mov dword ptr [eax],ecx + 0x89, 0x08, // mov dword ptr [eax], ecx 0x5B, // pop ebx 0xC9, // leave 0xC2, 0x18, 0x00 // ret 18h }; - private static readonly byte[] CPUID_64 = new byte[] { - 0x48, 0x89, 0x5C, 0x24, 0x08, // mov qword ptr [rsp+8],rbx - 0x8B, 0xC1, // mov eax,ecx - 0x8B, 0xCA, // mov ecx,edx - 0x0F, 0xA2, // cpuid - 0x41, 0x89, 0x00, // mov dword ptr [r8],eax - 0x48, 0x8B, 0x44, 0x24, 0x28, // mov rax,qword ptr [ecx] - 0x41, 0x89, 0x19, // mov dword ptr [r9],ebx - 0x48, 0x8B, 0x5C, 0x24, 0x08, // mov rbx,qword ptr [rsp+8] - 0x89, 0x08, // mov dword ptr [rax],ecx - 0x48, 0x8B, 0x44, 0x24, 0x30, // mov rax,qword ptr [rsp+30h] - 0x89, 0x10, // mov dword ptr [rax],edx + private static readonly byte[] CPUID_64_WINDOWS = new byte[] { + 0x48, 0x89, 0x5C, 0x24, 0x08, // mov qword ptr [rsp+8], rbx + 0x8B, 0xC1, // mov eax, ecx + 0x8B, 0xCA, // mov ecx, edx + 0x0F, 0xA2, // cpuid + 0x41, 0x89, 0x00, // mov dword ptr [r8], eax + 0x48, 0x8B, 0x44, 0x24, 0x28, // mov rax, qword ptr [rsp+28h] + 0x41, 0x89, 0x19, // mov dword ptr [r9], ebx + 0x48, 0x8B, 0x5C, 0x24, 0x08, // mov rbx, qword ptr [rsp+8] + 0x89, 0x08, // mov dword ptr [rax], ecx + 0x48, 0x8B, 0x44, 0x24, 0x30, // mov rax, qword ptr [rsp+30h] + 0x89, 0x10, // mov dword ptr [rax], edx 0xC3 // ret }; + + private static readonly byte[] CPUID_64_LINUX = new byte[] { + 0x49, 0x89, 0xD2, // mov r10, rdx + 0x49, 0x89, 0xCB, // mov r11, rcx + 0x53, // push rbx + 0x89, 0xF8, // mov eax, edi + 0x89, 0xF1, // mov ecx, esi + 0x0F, 0xA2, // cpuid + 0x41, 0x89, 0x02, // mov dword ptr [r10], eax + 0x41, 0x89, 0x1B, // mov dword ptr [r11], ebx + 0x41, 0x89, 0x08, // mov dword ptr [r8], ecx + 0x41, 0x89, 0x11, // mov dword ptr [r9], edx + 0x5B, // pop rbx + 0xC3, // ret + }; public static bool CpuidTx(uint index, uint ecxValue, out uint eax, out uint ebx, out uint ecx, out uint edx, - UIntPtr threadAffinityMask) { + ulong threadAffinityMask) { + + ulong mask = ThreadAffinity.Set(threadAffinityMask); - IntPtr thread = NativeMethods.GetCurrentThread(); - UIntPtr mask = NativeMethods.SetThreadAffinityMask(thread, - threadAffinityMask); - - if (mask == UIntPtr.Zero) { + if (mask == 0) { eax = ebx = ecx = edx = 0; return false; - } + } Cpuid(index, ecxValue, out eax, out ebx, out ecx, out edx); - NativeMethods.SetThreadAffinityMask(thread, mask); - + ThreadAffinity.Set(mask); return true; } - + [Flags()] public enum AllocationType : uint { COMMIT = 0x1000, @@ -222,7 +251,7 @@ RELEASE = 0x8000 } - private static class NativeMethods { + private static class NativeMethods { private const string KERNEL = "kernel32.dll"; [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] @@ -231,14 +260,7 @@ [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] public static extern bool VirtualFree(IntPtr lpAddress, UIntPtr dwSize, - FreeType dwFreeType); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern UIntPtr - SetThreadAffinityMask(IntPtr handle, UIntPtr mask); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern IntPtr GetCurrentThread(); + FreeType dwFreeType); } } } diff -r 9bf70d316cea -r bddc6e01840a Hardware/Ring0.cs --- a/Hardware/Ring0.cs Mon Nov 01 20:44:21 2010 +0000 +++ b/Hardware/Ring0.cs Wed Nov 03 22:07:46 2010 +0000 @@ -95,6 +95,11 @@ } public static void Open() { + // No implementation for Unix systems + int p = (int)Environment.OSVersion.Platform; + if ((p == 4) || (p == 128)) + return; + if (driver != null) return; @@ -170,15 +175,13 @@ } public static bool RdmsrTx(uint index, out uint eax, out uint edx, - UIntPtr threadAffinityMask) + ulong threadAffinityMask) { - IntPtr thread = NativeMethods.GetCurrentThread(); - UIntPtr mask = NativeMethods.SetThreadAffinityMask(thread, - threadAffinityMask); + ulong mask = ThreadAffinity.Set(threadAffinityMask); bool result = Rdmsr(index, out eax, out edx); - NativeMethods.SetThreadAffinityMask(thread, mask); + ThreadAffinity.Set(mask); return result; } @@ -276,16 +279,5 @@ return driver.DeviceIOControl(IOCTL_OLS_WRITE_PCI_CONFIG, input); } - - private static class NativeMethods { - private const string KERNEL = "kernel32.dll"; - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern UIntPtr - SetThreadAffinityMask(IntPtr handle, UIntPtr mask); - - [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] - public static extern IntPtr GetCurrentThread(); - } } } diff -r 9bf70d316cea -r bddc6e01840a Hardware/ThreadAffinity.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Hardware/ThreadAffinity.cs Wed Nov 03 22:07:46 2010 +0000 @@ -0,0 +1,87 @@ +/* + + Version: MPL 1.1/GPL 2.0/LGPL 2.1 + + The contents of this file are subject to the Mozilla Public License Version + 1.1 (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" basis, + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + for the specific language governing rights and limitations under the License. + + The Original Code is the Open Hardware Monitor code. + + The Initial Developer of the Original Code is + Michael Möller . + Portions created by the Initial Developer are Copyright (C) 2010 + the Initial Developer. All Rights Reserved. + + Contributor(s): + + Alternatively, the contents of this file may be used under the terms of + either the GNU General Public License Version 2 or later (the "GPL"), or + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + in which case the provisions of the GPL or the LGPL are applicable instead + of those above. If you wish to allow use of your version of this file only + under the terms of either the GPL or the LGPL, and not to allow others to + use your version of this file under the terms of the MPL, indicate your + decision by deleting the provisions above and replace them with the notice + and other provisions required by the GPL or the LGPL. If you do not delete + the provisions above, a recipient may use your version of this file under + the terms of any one of the MPL, the GPL or the LGPL. + +*/ + +using System; +using System.Runtime.InteropServices; + +namespace OpenHardwareMonitor.Hardware { + + internal static class ThreadAffinity { + + public static ulong Set(ulong mask) { + if (mask == 0) + return 0; + + int p = (int)Environment.OSVersion.Platform; + if ((p == 4) || (p == 128)) { // Unix + 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 { // Windows + return (ulong)NativeMethods.SetThreadAffinityMask( + NativeMethods.GetCurrentThread(), (UIntPtr)mask); + } + } + + private static class NativeMethods { + private const string KERNEL = "kernel32.dll"; + + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] + public static extern UIntPtr + SetThreadAffinityMask(IntPtr handle, UIntPtr mask); + + [DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)] + public static extern IntPtr GetCurrentThread(); + + private const string LIBC = "libc"; + + [DllImport(LIBC)] + public static extern int sched_getaffinity(int pid, IntPtr maskSize, + ref ulong mask); + + [DllImport(LIBC)] + public static extern int sched_setaffinity(int pid, IntPtr maskSize, + ref ulong mask); + } + } +} + diff -r 9bf70d316cea -r bddc6e01840a OpenHardwareMonitorLib.csproj --- a/OpenHardwareMonitorLib.csproj Mon Nov 01 20:44:21 2010 +0000 +++ b/OpenHardwareMonitorLib.csproj Wed Nov 03 22:07:46 2010 +0000 @@ -1,4 +1,4 @@ - + Debug @@ -41,7 +41,6 @@ prompt 4 AllRules.ruleset - false none @@ -55,6 +54,7 @@ + @@ -117,6 +117,7 @@ +