Cleanup thread affinity and support > 64 threads.
This commit is contained in:
@@ -127,21 +127,17 @@ internal class CpuGroup : IGroup
|
||||
|
||||
for (int i = 0; i < ThreadAffinity.ProcessorGroupCount; i++)
|
||||
{
|
||||
for (int j = 0; j < 64; j++)
|
||||
for (int j = 0; j < 192; j++)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ThreadAffinity.IsValid(GroupAffinity.Single((ushort)i, j)))
|
||||
continue;
|
||||
|
||||
var cpuid = CpuId.Get(i, j);
|
||||
if (cpuid != null)
|
||||
threads.Add(cpuid);
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
// All cores found.
|
||||
break;
|
||||
// Continue...
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,4 +207,4 @@ internal class CpuGroup : IGroup
|
||||
r.AppendLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,6 @@ internal static class OpCode
|
||||
else
|
||||
{
|
||||
rdTscCode = Rdtsc64;
|
||||
|
||||
cpuidCode = Software.OperatingSystem.IsUnix ? CpuId64Linux : CpuId64Windows;
|
||||
}
|
||||
|
||||
@@ -299,4 +298,4 @@ internal static class OpCode
|
||||
ThreadAffinity.Set(previousAffinity);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,34 +27,6 @@ internal static class ThreadAffinity
|
||||
/// </summary>
|
||||
public static int ProcessorGroupCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the <paramref name="affinity"/> is valid.
|
||||
/// </summary>
|
||||
/// <param name="affinity">The affinity.</param>
|
||||
/// <returns><c>true</c> if the specified affinity is valid; otherwise, <c>false</c>.</returns>
|
||||
public static bool IsValid(GroupAffinity affinity)
|
||||
{
|
||||
if (Software.OperatingSystem.IsUnix)
|
||||
{
|
||||
if (affinity.Group > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
UIntPtr uIntPtrMask;
|
||||
try
|
||||
{
|
||||
uIntPtrMask = (UIntPtr)affinity.Mask;
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the processor group affinity for the current thread.
|
||||
/// </summary>
|
||||
@@ -75,33 +47,23 @@ internal static class ThreadAffinity
|
||||
return GroupAffinity.Undefined;
|
||||
|
||||
ulong mask = affinity.Mask;
|
||||
if (LibC.sched_setaffinity(0, (IntPtr)8, ref mask) != 0)
|
||||
return GroupAffinity.Undefined;
|
||||
|
||||
return new GroupAffinity(0, result);
|
||||
return LibC.sched_setaffinity(0, (IntPtr)8, ref mask) != 0
|
||||
? GroupAffinity.Undefined
|
||||
: new GroupAffinity(0, result);
|
||||
}
|
||||
|
||||
UIntPtr uIntPtrMask;
|
||||
try
|
||||
{
|
||||
uIntPtrMask = (UIntPtr)affinity.Mask;
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
ulong maxValue = IntPtr.Size == 8 ? ulong.MaxValue : uint.MaxValue;
|
||||
if (affinity.Mask > maxValue)
|
||||
throw new ArgumentOutOfRangeException(nameof(affinity));
|
||||
}
|
||||
|
||||
var groupAffinity = new Kernel32.GROUP_AFFINITY { Group = affinity.Group, Mask = uIntPtrMask };
|
||||
var groupAffinity = new Kernel32.GROUP_AFFINITY { Group = affinity.Group, Mask = (UIntPtr)affinity.Mask };
|
||||
|
||||
IntPtr currentThread = Kernel32.GetCurrentThread();
|
||||
|
||||
if (Kernel32.SetThreadGroupAffinity(currentThread,
|
||||
ref groupAffinity,
|
||||
out Kernel32.GROUP_AFFINITY previousGroupAffinity))
|
||||
{
|
||||
return new GroupAffinity(previousGroupAffinity.Group, (ulong)previousGroupAffinity.Mask);
|
||||
}
|
||||
|
||||
return GroupAffinity.Undefined;
|
||||
return Kernel32.SetThreadGroupAffinity(currentThread,
|
||||
ref groupAffinity,
|
||||
out Kernel32.GROUP_AFFINITY previousGroupAffinity)
|
||||
? new GroupAffinity(previousGroupAffinity.Group, (ulong)previousGroupAffinity.Mask)
|
||||
: GroupAffinity.Undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user