mirror of https://github.com/dahall/Vanara.git
Finally a working solution for #176.
parent
17f615d839
commit
5806d373d3
|
@ -1226,9 +1226,9 @@ namespace Vanara.PInvoke
|
||||||
/// </list>
|
/// </list>
|
||||||
/// </para>
|
/// </para>
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="mem">The memory allocated for the results in <paramref name="info"/>.</param>
|
|
||||||
/// <param name="info">
|
/// <param name="info">
|
||||||
/// An array of <c>SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX</c> pointers. If the function fails, the contents of this buffer are undefined.
|
/// A safe handle that holds an array of <c>SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX</c> pointers. If the function fails, the
|
||||||
|
/// contents of this buffer are undefined.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// <para>
|
/// <para>
|
||||||
|
@ -1237,26 +1237,17 @@ namespace Vanara.PInvoke
|
||||||
/// </para>
|
/// </para>
|
||||||
/// <para>If the function fails, the return value has error information.</para>
|
/// <para>If the function fails, the return value has error information.</para>
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public static unsafe Win32Error GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP RelationshipType, out SafeCoTaskMemHandle mem, out RefEnumerator<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX> info)
|
public static unsafe Win32Error GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP RelationshipType, out SafeSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_List info)
|
||||||
{
|
{
|
||||||
info = default;
|
info = default;
|
||||||
mem = default;
|
|
||||||
uint sz = 0;
|
uint sz = 0;
|
||||||
var err = BoolToLastErr(GetLogicalProcessorInformationEx(RelationshipType, IntPtr.Zero, ref sz) || sz > 0);
|
var err = BoolToLastErr(GetLogicalProcessorInformationEx(RelationshipType, IntPtr.Zero, ref sz) || sz > 0);
|
||||||
if (err.Failed && err != Win32Error.ERROR_INSUFFICIENT_BUFFER) return err;
|
if (err.Failed && err != Win32Error.ERROR_INSUFFICIENT_BUFFER) return err;
|
||||||
mem = new SafeCoTaskMemHandle(sz);
|
var iinfo = new SafeSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_List(sz);
|
||||||
err = BoolToLastErr(GetLogicalProcessorInformationEx(RelationshipType, mem, ref sz));
|
if ((err = BoolToLastErr(GetLogicalProcessorInformationEx(RelationshipType, iinfo, ref sz))).Succeeded)
|
||||||
if (err.Succeeded)
|
info = iinfo;
|
||||||
{
|
else
|
||||||
var ret = new List<IntPtr>();
|
iinfo.Dispose();
|
||||||
for (IntPtr pCurrent = mem, pEnd = pCurrent.Offset(sz); pCurrent.ToInt64() < pEnd.ToInt64() && pCurrent != IntPtr.Zero;)
|
|
||||||
{
|
|
||||||
ret.Add(pCurrent);
|
|
||||||
pCurrent = pCurrent.Offset(pCurrent.ToStructure<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>().Size);
|
|
||||||
}
|
|
||||||
mem.Write(ret, true, (int)sz);
|
|
||||||
info = new RefEnumerator<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>((SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)mem.DangerousGetHandle().Offset(sz), ret.Count);
|
|
||||||
}
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2798,12 +2789,10 @@ namespace Vanara.PInvoke
|
||||||
public PROCESSOR_CACHE_TYPE Type;
|
public PROCESSOR_CACHE_TYPE Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Describes cache attributes. This structure is used with the GetLogicalProcessorInformationEx function.</summary>
|
||||||
/// <para>Describes cache attributes. This structure is used with the GetLogicalProcessorInformationEx function.</para>
|
|
||||||
/// </summary>
|
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_cache_relationship typedef struct _CACHE_RELATIONSHIP { BYTE
|
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_cache_relationship typedef struct _CACHE_RELATIONSHIP { BYTE
|
||||||
// Level; BYTE Associativity; WORD LineSize; DWORD CacheSize; PROCESSOR_CACHE_TYPE Type; BYTE Reserved[20]; GROUP_AFFINITY GroupMask;
|
// Level; BYTE Associativity; WORD LineSize; DWORD CacheSize; PROCESSOR_CACHE_TYPE Type; BYTE Reserved[20]; GROUP_AFFINITY
|
||||||
// } CACHE_RELATIONSHIP, *PCACHE_RELATIONSHIP;
|
// GroupMask; } CACHE_RELATIONSHIP, *PCACHE_RELATIONSHIP;
|
||||||
[PInvokeData("winnt.h", MSDNShortId = "f8fe521b-02d6-4c58-8ef8-653280add111")]
|
[PInvokeData("winnt.h", MSDNShortId = "f8fe521b-02d6-4c58-8ef8-653280add111")]
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||||
public struct CACHE_RELATIONSHIP
|
public struct CACHE_RELATIONSHIP
|
||||||
|
@ -2831,85 +2820,61 @@ namespace Vanara.PInvoke
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte Level;
|
public byte Level;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>The cache associativity. If this member is CACHE_FULLY_ASSOCIATIVE (0xFF), the cache is fully associative.</summary>
|
||||||
/// <para>The cache associativity. If this member is CACHE_FULLY_ASSOCIATIVE (0xFF), the cache is fully associative.</para>
|
|
||||||
/// </summary>
|
|
||||||
public byte Associativity;
|
public byte Associativity;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>The cache line size, in bytes.</summary>
|
||||||
/// <para>The cache line size, in bytes.</para>
|
|
||||||
/// </summary>
|
|
||||||
public ushort LineSize;
|
public ushort LineSize;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>The cache size, in bytes.</summary>
|
||||||
/// <para>The cache size, in bytes.</para>
|
|
||||||
/// </summary>
|
|
||||||
public uint CacheSize;
|
public uint CacheSize;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>The cache type. This member is a PROCESSOR_CACHE_TYPE value.</summary>
|
||||||
/// <para>The cache type. This member is a PROCESSOR_CACHE_TYPE value.</para>
|
|
||||||
/// </summary>
|
|
||||||
public PROCESSOR_CACHE_TYPE Type;
|
public PROCESSOR_CACHE_TYPE Type;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>This member is reserved.</summary>
|
||||||
/// <para>This member is reserved.</para>
|
|
||||||
/// </summary>
|
|
||||||
private readonly uint Reserved1;
|
private readonly uint Reserved1;
|
||||||
|
|
||||||
private readonly uint Reserved2;
|
private readonly uint Reserved2;
|
||||||
private readonly uint Reserved3;
|
private readonly uint Reserved3;
|
||||||
private readonly uint Reserved4;
|
private readonly uint Reserved4;
|
||||||
private readonly uint Reserved5;
|
private readonly uint Reserved5;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>A GROUP_AFFINITY structure that specifies a group number and processor affinity within the group.</summary>
|
||||||
/// <para>A GROUP_AFFINITY structure that specifies a group number and processor affinity within the group.</para>
|
|
||||||
/// </summary>
|
|
||||||
public GROUP_AFFINITY GroupMask;
|
public GROUP_AFFINITY GroupMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Represents information about processor groups. This structure is used with the GetLogicalProcessorInformationEx function.</para>
|
/// Represents information about processor groups. This structure is used with the GetLogicalProcessorInformationEx function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_group_relationship typedef struct _GROUP_RELATIONSHIP { WORD
|
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_group_relationship typedef struct _GROUP_RELATIONSHIP { WORD
|
||||||
// MaximumGroupCount; WORD ActiveGroupCount; BYTE Reserved[20]; PROCESSOR_GROUP_INFO GroupInfo[ANYSIZE_ARRAY]; } GROUP_RELATIONSHIP, *PGROUP_RELATIONSHIP;
|
// MaximumGroupCount; WORD ActiveGroupCount; BYTE Reserved[20]; PROCESSOR_GROUP_INFO GroupInfo[ANYSIZE_ARRAY]; } GROUP_RELATIONSHIP, *PGROUP_RELATIONSHIP;
|
||||||
[PInvokeData("winnt.h", MSDNShortId = "3529ddef-04c5-4573-877d-c225da684e38")]
|
[PInvokeData("winnt.h", MSDNShortId = "3529ddef-04c5-4573-877d-c225da684e38")]
|
||||||
|
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<GROUP_RELATIONSHIP>), nameof(ActiveGroupCount))]
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||||
public struct GROUP_RELATIONSHIP
|
public struct GROUP_RELATIONSHIP
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>The maximum number of processor groups on the system.</summary>
|
||||||
/// <para>The maximum number of processor groups on the system.</para>
|
|
||||||
/// </summary>
|
|
||||||
public ushort MaximumGroupCount;
|
public ushort MaximumGroupCount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>
|
|
||||||
/// The number of active groups on the system. This member indicates the number of PROCESSOR_GROUP_INFO structures in the
|
/// The number of active groups on the system. This member indicates the number of PROCESSOR_GROUP_INFO structures in the
|
||||||
/// <c>GroupInfo</c> array.
|
/// <c>GroupInfo</c> array.
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ushort ActiveGroupCount;
|
public ushort ActiveGroupCount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>This member is reserved.</summary>
|
||||||
/// <para>This member is reserved.</para>
|
|
||||||
/// </summary>
|
|
||||||
private readonly uint Reserved1;
|
private readonly uint Reserved1;
|
||||||
|
|
||||||
private readonly uint Reserved2;
|
private readonly uint Reserved2;
|
||||||
private readonly uint Reserved3;
|
private readonly uint Reserved3;
|
||||||
private readonly uint Reserved4;
|
private readonly uint Reserved4;
|
||||||
private readonly uint Reserved5;
|
private readonly uint Reserved5;
|
||||||
private PROCESSOR_GROUP_INFO _GroupInfo;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>
|
|
||||||
/// An array of PROCESSOR_GROUP_INFO structures. Each structure represents the number and affinity of processors in an active
|
/// An array of PROCESSOR_GROUP_INFO structures. Each structure represents the number and affinity of processors in an active
|
||||||
/// group on the system.
|
/// group on the system.
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PROCESSOR_GROUP_INFO[] GroupInfo
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||||
{
|
public PROCESSOR_GROUP_INFO[] GroupInfo;
|
||||||
get { unsafe { fixed (void* p = &_GroupInfo) { return ((IntPtr)p).ToArray<PROCESSOR_GROUP_INFO>(ActiveGroupCount); } } }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3038,34 +3003,25 @@ namespace Vanara.PInvoke
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>
|
|
||||||
/// Represents information about a NUMA node in a processor group. This structure is used with the GetLogicalProcessorInformationEx function.
|
/// Represents information about a NUMA node in a processor group. This structure is used with the GetLogicalProcessorInformationEx function.
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_numa_node_relationship typedef struct _NUMA_NODE_RELATIONSHIP
|
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_numa_node_relationship typedef struct
|
||||||
// { DWORD NodeNumber; BYTE Reserved[20]; GROUP_AFFINITY GroupMask; } NUMA_NODE_RELATIONSHIP, *PNUMA_NODE_RELATIONSHIP;
|
// _NUMA_NODE_RELATIONSHIP { DWORD NodeNumber; BYTE Reserved[20]; GROUP_AFFINITY GroupMask; } NUMA_NODE_RELATIONSHIP, *PNUMA_NODE_RELATIONSHIP;
|
||||||
[PInvokeData("winnt.h", MSDNShortId = "a4e4c994-c4af-4b4f-8684-6037bcba35a9")]
|
[PInvokeData("winnt.h", MSDNShortId = "a4e4c994-c4af-4b4f-8684-6037bcba35a9")]
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||||
public struct NUMA_NODE_RELATIONSHIP
|
public struct NUMA_NODE_RELATIONSHIP
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>The number of the NUMA node.</summary>
|
||||||
/// <para>The number of the NUMA node.</para>
|
|
||||||
/// </summary>
|
|
||||||
public uint NodeNumber;
|
public uint NodeNumber;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>This member is reserved.</summary>
|
||||||
/// <para>This member is reserved.</para>
|
|
||||||
/// </summary>
|
|
||||||
private readonly uint Reserved1;
|
private readonly uint Reserved1;
|
||||||
|
|
||||||
private readonly uint Reserved2;
|
private readonly uint Reserved2;
|
||||||
private readonly uint Reserved3;
|
private readonly uint Reserved3;
|
||||||
private readonly uint Reserved4;
|
private readonly uint Reserved4;
|
||||||
private readonly uint Reserved5;
|
private readonly uint Reserved5;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>A GROUP_AFFINITY structure that specifies a group number and processor affinity within the group.</summary>
|
||||||
/// <para>A GROUP_AFFINITY structure that specifies a group number and processor affinity within the group.</para>
|
|
||||||
/// </summary>
|
|
||||||
public GROUP_AFFINITY GroupMask;
|
public GROUP_AFFINITY GroupMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3243,30 +3199,21 @@ namespace Vanara.PInvoke
|
||||||
public static readonly OSVERSIONINFOEX Default = new OSVERSIONINFOEX { dwOSVersionInfoSize = (uint)Marshal.SizeOf(typeof(OSVERSIONINFOEX)) };
|
public static readonly OSVERSIONINFOEX Default = new OSVERSIONINFOEX { dwOSVersionInfoSize = (uint)Marshal.SizeOf(typeof(OSVERSIONINFOEX)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Represents the number and affinity of processors in a processor group.</summary>
|
||||||
/// <para>Represents the number and affinity of processors in a processor group.</para>
|
|
||||||
/// </summary>
|
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_processor_group_info typedef struct _PROCESSOR_GROUP_INFO {
|
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_processor_group_info typedef struct _PROCESSOR_GROUP_INFO {
|
||||||
// BYTE MaximumProcessorCount; BYTE ActiveProcessorCount; BYTE Reserved[38]; KAFFINITY ActiveProcessorMask; } PROCESSOR_GROUP_INFO, *PPROCESSOR_GROUP_INFO;
|
// BYTE MaximumProcessorCount; BYTE ActiveProcessorCount; BYTE Reserved[38]; KAFFINITY ActiveProcessorMask; } PROCESSOR_GROUP_INFO, *PPROCESSOR_GROUP_INFO;
|
||||||
[PInvokeData("winnt.h", MSDNShortId = "6ff9cc3c-34e7-4dc4-94cd-6ed278dfaa03")]
|
[PInvokeData("winnt.h", MSDNShortId = "6ff9cc3c-34e7-4dc4-94cd-6ed278dfaa03")]
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||||
public struct PROCESSOR_GROUP_INFO
|
public struct PROCESSOR_GROUP_INFO
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>The maximum number of processors in the group.</summary>
|
||||||
/// <para>The maximum number of processors in the group.</para>
|
|
||||||
/// </summary>
|
|
||||||
public byte MaximumProcessorCount;
|
public byte MaximumProcessorCount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>The number of active processors in the group.</summary>
|
||||||
/// <para>The number of active processors in the group.</para>
|
|
||||||
/// </summary>
|
|
||||||
public byte ActiveProcessorCount;
|
public byte ActiveProcessorCount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>This member is reserved.</summary>
|
||||||
/// <para>This member is reserved.</para>
|
|
||||||
/// </summary>
|
|
||||||
private readonly ushort Reserved1;
|
private readonly ushort Reserved1;
|
||||||
|
|
||||||
private readonly uint Reserved2;
|
private readonly uint Reserved2;
|
||||||
private readonly uint Reserved3;
|
private readonly uint Reserved3;
|
||||||
private readonly uint Reserved4;
|
private readonly uint Reserved4;
|
||||||
|
@ -3277,9 +3224,7 @@ namespace Vanara.PInvoke
|
||||||
private readonly uint Reserved9;
|
private readonly uint Reserved9;
|
||||||
private readonly uint Reserved10;
|
private readonly uint Reserved10;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>A bitmap that specifies the affinity for zero or more active processors within the group.</summary>
|
||||||
/// <para>A bitmap that specifies the affinity for zero or more active processors within the group.</para>
|
|
||||||
/// </summary>
|
|
||||||
public UIntPtr ActiveProcessorMask;
|
public UIntPtr ActiveProcessorMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3305,6 +3250,7 @@ namespace Vanara.PInvoke
|
||||||
// { BYTE Flags; BYTE EfficiencyClass; BYTE Reserved[20]; WORD GroupCount; GROUP_AFFINITY GroupMask[ANYSIZE_ARRAY]; }
|
// { BYTE Flags; BYTE EfficiencyClass; BYTE Reserved[20]; WORD GroupCount; GROUP_AFFINITY GroupMask[ANYSIZE_ARRAY]; }
|
||||||
// PROCESSOR_RELATIONSHIP, *PPROCESSOR_RELATIONSHIP;
|
// PROCESSOR_RELATIONSHIP, *PPROCESSOR_RELATIONSHIP;
|
||||||
[PInvokeData("winnt.h", MSDNShortId = "1efda80d-cf5b-4312-801a-ea3585b152ac")]
|
[PInvokeData("winnt.h", MSDNShortId = "1efda80d-cf5b-4312-801a-ea3585b152ac")]
|
||||||
|
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<PROCESSOR_RELATIONSHIP>), nameof(GroupCount))]
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||||
public struct PROCESSOR_RELATIONSHIP
|
public struct PROCESSOR_RELATIONSHIP
|
||||||
{
|
{
|
||||||
|
@ -3335,32 +3281,23 @@ namespace Vanara.PInvoke
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte EfficiencyClass;
|
public byte EfficiencyClass;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>This member is reserved.</summary>
|
||||||
/// <para>This member is reserved.</para>
|
|
||||||
/// </summary>
|
|
||||||
private readonly ushort Reserved1;
|
private readonly ushort Reserved1;
|
||||||
|
|
||||||
private readonly uint Reserved2;
|
private readonly uint Reserved2;
|
||||||
private readonly uint Reserved3;
|
private readonly uint Reserved3;
|
||||||
private readonly uint Reserved4;
|
private readonly uint Reserved4;
|
||||||
private readonly uint Reserved5;
|
private readonly uint Reserved5;
|
||||||
private readonly ushort Reserved6;
|
private readonly ushort Reserved6;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>This member specifies the number of entries in the <c>GroupMask</c> array. For more information, see Remarks.</summary>
|
||||||
/// <para>This member specifies the number of entries in the <c>GroupMask</c> array. For more information, see Remarks.</para>
|
|
||||||
/// </summary>
|
|
||||||
public ushort GroupCount;
|
public ushort GroupCount;
|
||||||
|
|
||||||
private GROUP_AFFINITY _GroupMask;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An array of GROUP_AFFINITY structures. The <c>GroupCount</c> member specifies the number of structures in the array. Each
|
/// An array of GROUP_AFFINITY structures. The <c>GroupCount</c> member specifies the number of structures in the array. Each
|
||||||
/// structure in the array specifies a group number and processor affinity within the group.
|
/// structure in the array specifies a group number and processor affinity within the group.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GROUP_AFFINITY[] GroupMask
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||||
{
|
public GROUP_AFFINITY[] GroupMask;
|
||||||
get { unsafe { fixed (void* p = &_GroupMask) { return ((IntPtr)p).ToArray<GROUP_AFFINITY>(GroupCount); } } }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3583,17 +3520,15 @@ namespace Vanara.PInvoke
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>
|
|
||||||
/// Contains information about the relationships of logical processors and related hardware. The GetLogicalProcessorInformationEx
|
/// Contains information about the relationships of logical processors and related hardware. The GetLogicalProcessorInformationEx
|
||||||
/// function uses this structure.
|
/// function uses this structure.
|
||||||
/// </para>
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_system_logical_processor_information_ex typedef struct
|
// https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_system_logical_processor_information_ex typedef struct
|
||||||
// _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX { LOGICAL_PROCESSOR_RELATIONSHIP Relationship; DWORD Size; union { PROCESSOR_RELATIONSHIP
|
// _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX { LOGICAL_PROCESSOR_RELATIONSHIP Relationship; DWORD Size; union { PROCESSOR_RELATIONSHIP
|
||||||
// Processor; NUMA_NODE_RELATIONSHIP NumaNode; CACHE_RELATIONSHIP Cache; GROUP_RELATIONSHIP Group; } DUMMYUNIONNAME; }
|
// Processor; NUMA_NODE_RELATIONSHIP NumaNode; CACHE_RELATIONSHIP Cache; GROUP_RELATIONSHIP Group; } DUMMYUNIONNAME; }
|
||||||
// SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX;
|
// SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX;
|
||||||
[PInvokeData("winnt.h", MSDNShortId = "6ff16cda-c1dc-4d5c-ac60-756653cd6b07")]
|
[PInvokeData("winnt.h", MSDNShortId = "6ff16cda-c1dc-4d5c-ac60-756653cd6b07")]
|
||||||
[StructLayout(LayoutKind.Sequential), DebuggerDisplay("{DebugString}")]
|
[StructLayout(LayoutKind.Sequential, Size = 76)]
|
||||||
public struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
|
public struct SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3630,57 +3565,44 @@ namespace Vanara.PInvoke
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
|
public LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>The size of the structure.</summary>
|
||||||
/// <para>The size of the structure.</para>
|
|
||||||
/// </summary>
|
|
||||||
public uint Size;
|
public uint Size;
|
||||||
|
|
||||||
/// <summary>The relationship union.</summary>
|
/// <summary>The relationship union.</summary>
|
||||||
public ProcessorRelationUnion RelationUnion;
|
private readonly ulong dummy;
|
||||||
|
|
||||||
/// <summary>Union tied to the relationship.</summary>
|
/// <summary>
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
/// A NUMA_NODE_RELATIONSHIP structure that describes a NUMA node. This structure contains valid data only if the
|
||||||
public struct ProcessorRelationUnion
|
/// <c>Relationship</c> member is <c>RelationNumaNode</c>.
|
||||||
|
/// </summary>
|
||||||
|
public NUMA_NODE_RELATIONSHIP NumaNode => GetField<NUMA_NODE_RELATIONSHIP>(LOGICAL_PROCESSOR_RELATIONSHIP.RelationNumaNode);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A CACHE_RELATIONSHIP structure that describes cache attributes. This structure contains valid data only if the
|
||||||
|
/// <c>Relationship</c> member is <c>RelationCache</c>.
|
||||||
|
/// </summary>
|
||||||
|
public CACHE_RELATIONSHIP Cache => GetField<CACHE_RELATIONSHIP>(LOGICAL_PROCESSOR_RELATIONSHIP.RelationCache);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A PROCESSOR_RELATIONSHIP structure that describes processor affinity. This structure contains valid data only if the
|
||||||
|
/// <c>Relationship</c> member is <c>RelationProcessorCore</c> or <c>RelationProcessorPackage</c>.
|
||||||
|
/// </summary>
|
||||||
|
public PROCESSOR_RELATIONSHIP Processor => GetField<PROCESSOR_RELATIONSHIP>(LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore, LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorPackage);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A GROUP_RELATIONSHIP structure that contains information about the processor groups. This structure contains valid data
|
||||||
|
/// only if the <c>Relationship</c> member is <c>RelationGroup</c>.
|
||||||
|
/// </summary>
|
||||||
|
public GROUP_RELATIONSHIP Group => GetField<GROUP_RELATIONSHIP>(LOGICAL_PROCESSOR_RELATIONSHIP.RelationGroup);
|
||||||
|
|
||||||
|
private T GetField<T>(params LOGICAL_PROCESSOR_RELATIONSHIP[] r)
|
||||||
{
|
{
|
||||||
/// <summary>
|
if (!r.Contains(Relationship))
|
||||||
/// A PROCESSOR_RELATIONSHIP structure that describes processor affinity. This structure contains valid data only if the
|
return default;
|
||||||
/// <c>Relationship</c> member is <c>RelationProcessorCore</c> or <c>RelationProcessorPackage</c>.
|
unsafe
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(0)] public PROCESSOR_RELATIONSHIP Processor;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A NUMA_NODE_RELATIONSHIP structure that describes a NUMA node. This structure contains valid data only if the
|
|
||||||
/// <c>Relationship</c> member is <c>RelationNumaNode</c>.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(0)] public NUMA_NODE_RELATIONSHIP NumaNode;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A CACHE_RELATIONSHIP structure that describes cache attributes. This structure contains valid data only if the
|
|
||||||
/// <c>Relationship</c> member is <c>RelationCache</c>.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(0)] public CACHE_RELATIONSHIP Cache;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A GROUP_RELATIONSHIP structure that contains information about the processor groups. This structure contains valid data
|
|
||||||
/// only if the <c>Relationship</c> member is <c>RelationGroup</c>.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(0)] public GROUP_RELATIONSHIP Group;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal string DebugString
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
uint c = Relationship switch
|
fixed (void* p = &dummy)
|
||||||
{
|
return ((IntPtr)p).ToStructure<T>();
|
||||||
LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore => RelationUnion.Processor.GroupCount,
|
|
||||||
LOGICAL_PROCESSOR_RELATIONSHIP.RelationNumaNode => RelationUnion.NumaNode.NodeNumber,
|
|
||||||
LOGICAL_PROCESSOR_RELATIONSHIP.RelationCache => RelationUnion.Cache.CacheSize,
|
|
||||||
LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorPackage => RelationUnion.Processor.GroupCount,
|
|
||||||
LOGICAL_PROCESSOR_RELATIONSHIP.RelationGroup => RelationUnion.Group.ActiveGroupCount,
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
return $"{Relationship}, Size={Size}, Count={c}";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3693,5 +3615,39 @@ namespace Vanara.PInvoke
|
||||||
/// <summary>The cycle time for a processor.</summary>
|
/// <summary>The cycle time for a processor.</summary>
|
||||||
public ulong CycleTime;
|
public ulong CycleTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Holds a list of <see cref="SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX"/> structures retrived from <see cref="GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP, IntPtr, ref uint)"/>.</summary>
|
||||||
|
public class SafeSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_List : SafeMemoryHandle<CoTaskMemoryMethods>
|
||||||
|
{
|
||||||
|
internal SafeSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_List(SizeT size) : base(size)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Gets the number of elements available.</summary>
|
||||||
|
/// <value>The number of elements available.</value>
|
||||||
|
public int Count => Items.Count;
|
||||||
|
|
||||||
|
/// <summary>Gets a reference to a <see cref="SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX"/> at the specified index.</summary>
|
||||||
|
/// <param name="index">The index.</param>
|
||||||
|
/// <returns>A reference to <see cref="SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX"/>.</returns>
|
||||||
|
public unsafe SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* this[int index] => (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(void*)Items[index];
|
||||||
|
|
||||||
|
/// <summary>Move to next element.</summary>
|
||||||
|
private List<IntPtr> Items
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var ret = new List<IntPtr>();
|
||||||
|
for (IntPtr pCurrent = handle, pEnd = pCurrent.Offset(sz); pCurrent != IntPtr.Zero && pCurrent.ToInt64() < pEnd.ToInt64();)
|
||||||
|
{
|
||||||
|
var cSz = pCurrent.ToStructure<SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>().Size;
|
||||||
|
if (cSz == 0) break;
|
||||||
|
ret.Add(pCurrent);
|
||||||
|
pCurrent = pCurrent.Offset(cSz);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -57,26 +57,27 @@ namespace Vanara.PInvoke.Tests
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
Assert.That(GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP.RelationGroup, out var mem, out var info), ResultIs.Successful);
|
Assert.That(GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP.RelationGroup, out var info), ResultIs.Successful);
|
||||||
using (mem)
|
using (info)
|
||||||
{
|
{
|
||||||
Assert.That(info.Count, Is.GreaterThan(0));
|
Assert.That(info.Count, Is.GreaterThan(0));
|
||||||
for (int i = 0; i < info.Count; i++)
|
for (int i = 0; i < info.Count; i++)
|
||||||
{
|
{
|
||||||
switch (info[i].Relationship)
|
var pr = info[i];
|
||||||
|
switch (pr->Relationship)
|
||||||
{
|
{
|
||||||
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationNumaNode:
|
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationNumaNode:
|
||||||
info[i].RelationUnion.NumaNode.WriteValues();
|
pr->NumaNode.WriteValues();
|
||||||
break;
|
break;
|
||||||
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationCache:
|
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationCache:
|
||||||
info[i].RelationUnion.Cache.WriteValues();
|
pr->Cache.WriteValues();
|
||||||
break;
|
break;
|
||||||
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore:
|
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore:
|
||||||
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorPackage:
|
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorPackage:
|
||||||
info[i].RelationUnion.Processor.WriteValues();
|
pr->Processor.WriteValues();
|
||||||
break;
|
break;
|
||||||
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationGroup:
|
case LOGICAL_PROCESSOR_RELATIONSHIP.RelationGroup:
|
||||||
info[i].RelationUnion.Group.WriteValues();
|
pr->Group.WriteValues();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue