private static bool GetCountsForGT64LPs(_LOGICAL_PROCESSOR_RELATIONSHIP aType, ref int aCount,
        ref LogicalProcessorInfo[] aProcessorList)
        {
            //----------------------------------------------
            // Intel Corporation
            // Copyright © 2009/2010 - All Rights Reserved
            // Department : SST/NTE
            // Written by : Bill Hines - [email protected]
            // Modified by : N/A
            // Date : 12/4/2009
            //----------------------------------------------
            bool rvReturnValue = false;
            switch (aType)
            {
                case _LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorPackage:
                    _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P[] oDataPPs = GetProcessorDataArray(aType);
                    aCount = 0;
                    if (oDataPPs != null)
                        aCount = oDataPPs.Length;
                    if (oDataPPs != null)
                    {
                        List<LogicalProcessorInfo> oList = new List<LogicalProcessorInfo>();
                        ushort CurrentGroup = oDataPPs[0].Processor.GroupMask[0].Group;
                        byte AbsoluteProcessorNumber = 0;
                        byte[] GroupProcessorNumberArray = new byte[NUM_PROCESSOR_GROUPS];
                        for (int i = 0; i < NUM_PROCESSOR_GROUPS; i++)
                            GroupProcessorNumberArray[i] = 0;
                        foreach (_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P LPInfo in oDataPPs)
                        {
                            ushort Group = LPInfo.Processor.GroupMask[0].Group;
                            UIntPtr GroupMask = LPInfo.Processor.GroupMask[0].Mask;
                            ulong lg = 1;
                            uint LSHIFT = (uint)((UIntPtr.Size * 8) - 1);

                            for (int i = 0; i <= LSHIFT; i++)
                            {
                                if (((ulong)GroupMask & (ulong)(lg << i)) != 0)
                                {
                                    UIntPtr LPMask = (UIntPtr)((lg << i));
                                    oList.Add(new LogicalProcessorInfo(
                                    Group, GroupProcessorNumberArray[Group], AbsoluteProcessorNumber, LPMask));
                                    GroupProcessorNumberArray[Group]++;
                                    AbsoluteProcessorNumber++;
                                }
                            }
                        }
                        aProcessorList = oList.ToArray();
                        rvReturnValue = true;
                    }
                    else
                        rvReturnValue = false;
                    break;
                case _LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore:
                    _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P[] oDataCores = GetProcessorDataArray(aType);
                    aCount = 0;
                    if (oDataCores != null)
                    {
                        aCount = oDataCores.Length;
                        rvReturnValue = true;
                    }
                    else
                        rvReturnValue = false;
                    break;
                case _LOGICAL_PROCESSOR_RELATIONSHIP.RelationNumaNode:
                    _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P[] oDataNumaCores =
                    GetProcessorDataArray(_LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore);
                    _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_N[] oDataNuma = GetNumaDataArray(aType);
                    aCount = 0;
                    if ((oDataNumaCores != null) && (oDataNuma != null))
                    {
                        aCount = oDataNumaCores.Length;
                        byte[] NumaNodeCounts = new byte[oDataNuma.Length];
                        byte[] NumaIndexOffset = new byte[oDataNuma.Length];
                        for (int i = 0; i < NumaNodeCounts.Length; i++)
                        {
                            byte LPsInNode = (byte)CountNumberOfBitsSetInMask(oDataNuma[i].Numa.GroupMask.Mask);
                            NumaNodeCounts[i] += LPsInNode;
                        }
                        for (int i = 1; i < NumaIndexOffset.Length; i++)
                            NumaIndexOffset[i] += NumaNodeCounts[i - 1];
                        List<LogicalProcessorInfo> oList = new List<LogicalProcessorInfo>();
                        ushort CurrentGroup = oDataNuma[0].Numa.GroupMask.Group;

                        byte AbsoluteProcessorNumber = 0;
                        byte[] GroupProcessorNumberArray = new byte[NUM_PROCESSOR_GROUPS];
                        for (int i = 0; i < NUM_PROCESSOR_GROUPS; i++)
                            GroupProcessorNumberArray[i] = 0;
                        foreach (_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_N numaInfo in oDataNuma)
                        {
                            ushort Group = numaInfo.Numa.GroupMask.Group;
                            UIntPtr GroupMask = numaInfo.Numa.GroupMask.Mask;
                            ulong lg = 1;
                            uint LSHIFT = (uint)((UIntPtr.Size * 8) - 1);
                            for (int i = 0; i <= LSHIFT; i++)
                            {
                                if (((ulong)GroupMask & (ulong)(lg << i)) != 0)
                                {
                                    UIntPtr LPMask = (UIntPtr)((lg << i));
                                    oList.Insert((NumaIndexOffset[Group] + AbsoluteProcessorNumber),
                                    new LogicalProcessorInfo(
                                    Group,
                                    GroupProcessorNumberArray[Group],
                                    AbsoluteProcessorNumber,
                                    LPMask));
                                    GroupProcessorNumberArray[Group]++;
                                    AbsoluteProcessorNumber++;
                                }
                            }
                        }
                        aProcessorList = oList.ToArray();
                        rvReturnValue = true;
                    }
                    else
                        rvReturnValue = false;
                    break;
                default:
                    rvReturnValue = false;
                    break;
            }
            return rvReturnValue;
        }
        private static bool GetLogicalProcessorInformationExWrapper(_LOGICAL_PROCESSOR_RELATIONSHIP _LOGICAL_PROCESSOR_RELATIONSHIP, _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P[] oDummy, ref uint returnLength)
        {
            bool ret = true;

            #if false // DEBUG
            const int PKG_COUNT = 2;
            const int CORES_PER_PKG = 18;
            const int THREADS_PER_CORE = 2;
            switch (_LOGICAL_PROCESSOR_RELATIONSHIP)
            {
                case ProcessorQueryAndControl._LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorPackage:
                    {
                        Func<ushort, ulong, _PROCESSOR_RELATIONSHIP> CreateProcessor = (group, mask) =>
                            {
                                _PROCESSOR_RELATIONSHIP p = new _PROCESSOR_RELATIONSHIP();
                                p.Flags = 0;
                                p.GroupCount = 1;
                                p.GroupMask = new _GROUP_AFFINITY[1];
                                p.GroupMask[0].Mask = new UIntPtr(mask);
                                p.GroupMask[0].Group = group;
                                return p;
                            };

                        if (oDummy != null && oDummy.Length >= PKG_COUNT)
                        {
                            oDummy[0].Relationship = _LOGICAL_PROCESSOR_RELATIONSHIP;
                            //oDummy[0].Processor = CreateProcessor(0, 0xFFFF);
                            oDummy[0].Processor = CreateProcessor(0, 0xFFFFFFFFF);
                            oDummy[0].Size = (uint)Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P));

                            oDummy[1].Relationship = _LOGICAL_PROCESSOR_RELATIONSHIP;
                            //oDummy[1].Processor = CreateProcessor(0, 0xFFFF0000);
                            oDummy[1].Processor = CreateProcessor(1, 0xFFFFFFFFF);
                            oDummy[1].Size = (uint)Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P));

                            /*
                            oDummy[2].Relationship = _LOGICAL_PROCESSOR_RELATIONSHIP;
                            //oDummy[2].Processor = CreateProcessor(0, 0xFFFF00000000);
                            oDummy[2].Processor = CreateProcessor(1, 0x3FFFFFFF);
                            oDummy[2].Size = (uint)Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P));

                            oDummy[3].Relationship = _LOGICAL_PROCESSOR_RELATIONSHIP;
                            //oDummy[3].Processor = CreateProcessor(0, 0xFFFF000000000000);
                            oDummy[3].Processor = CreateProcessor(1, 0xFFFFFFFC00000000);
                            oDummy[3].Size = (uint)Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P));
                            */
                            returnLength = (uint)(oDummy.Length * Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P)));
                            ret = true;
                        }
                        else
                        {
                            returnLength = (uint)(PKG_COUNT * Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P)));
                            ret = false;
                        }
                    }
                    break;
                case ProcessorQueryAndControl._LOGICAL_PROCESSOR_RELATIONSHIP.RelationProcessorCore:
                    {
                        //oDummy = new _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P[PKG_COUNT * CORES_PER_PKG];

                        Func<ushort, ulong, _PROCESSOR_RELATIONSHIP> CreateCore = (group, mask) =>
                        {
                            _PROCESSOR_RELATIONSHIP p = new _PROCESSOR_RELATIONSHIP();
                            p.Flags = 1;
                            p.GroupCount = 1;
                            p.GroupMask = new _GROUP_AFFINITY[1];
                            p.GroupMask[0].Mask = new UIntPtr(mask);
                            p.GroupMask[0].Group = group;
                            return p;
                        };

                        if (oDummy != null && oDummy.Length >= (PKG_COUNT * CORES_PER_PKG))
                        {
                            for (int i = 0; i < (2 * CORES_PER_PKG); i++)
                            {
                                oDummy[i].Relationship = _LOGICAL_PROCESSOR_RELATIONSHIP;
                                oDummy[i].Processor = CreateCore((ushort)((i * 2) / 64), (0x3UL << ((i * 2) % 64)));
                                oDummy[i].Size = (uint)Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P));
                            }

                            for (int i = 0; i < (2 * CORES_PER_PKG); i++)
                            {
                                oDummy[35 - i].Relationship = _LOGICAL_PROCESSOR_RELATIONSHIP;
                                oDummy[35 - i].Processor = CreateCore((ushort)((i * 2) / 64), (0xC000000000000000UL >> ((i * 2) % 64)));
                                oDummy[35 - i].Size = (uint)Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P));
                            }

                            returnLength = (uint)(oDummy.Length * Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P)));
                            ret = true;
                        }
                        else
                        {
                            returnLength = (uint)(PKG_COUNT * CORES_PER_PKG * Marshal.SizeOf(typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P)));
                            ret = false;
                        }
                    }
                    break;
                default:
                    throw new ArgumentException();
            }

            #else
            ret = GetLogicalProcessorInformationEx(_LOGICAL_PROCESSOR_RELATIONSHIP, oDummy, ref returnLength);
            #endif
            try
            {
                if (oDummy != null)
                {
                    int index = 0;
                    foreach (_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P s in oDummy)
                    {
                        ErrorLog.WriteLine(_LOGICAL_PROCESSOR_RELATIONSHIP.ToString() + " - " + index++ + ": ");
                        _PROCESSOR_RELATIONSHIP pr = s.Processor;
                        _LOGICAL_PROCESSOR_RELATIONSHIP lpr = s.Relationship;
                        ErrorLog.WriteLine("  Size: " + s.Size);
                        ErrorLog.WriteLine("  Flags: " + pr.Flags);
                        ErrorLog.WriteLine("  GroupCount: " + pr.GroupCount);
                        foreach (_GROUP_AFFINITY ga in pr.GroupMask)
                        {
                            ErrorLog.WriteLine("  GroupMask: ");
                            ErrorLog.WriteLine("    Group: " + ga.Group.ToString("X2"));
                            ErrorLog.WriteLine("    Mask: " + ((ulong)ga.Mask).ToString("X2"));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return ret;
        }
 private static _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P[] GetProcessorDataArray(_LOGICAL_PROCESSOR_RELATIONSHIP aType)
 {
     //----------------------------------------------
     // Intel Corporation
     // Copyright © 2009/2010 - All Rights Reserved
     // Department : SST/NTE
     // Written by : Bill Hines - [email protected]
     // Modified by : N/A
     // Date : 12/4/2009
     //----------------------------------------------
     // Get Number of Elements that Exist
     //----------------------------------------------
     uint returnLength = 0;
     _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P[] oDummy = null;
     bool bResult = GetLogicalProcessorInformationExWrapper(
     aType, oDummy, ref returnLength);
     if (bResult) return null;
     //----------------------------------------------
     // Making sure that the error code that we
     // got back isn't that there is insufficient
     // space in the buffer.
     //----------------------------------------------
     int iError = Marshal.GetLastWin32Error();
     if (iError != ERROR_INSUFFICIENT_BUFFER)
         return null;
     //----------------------------------------------
     // Now that we know how much space we should
     // reserve, we're going to reserve it and call
     // GetLogicalProcessorInformationEx again.
     //----------------------------------------------
     uint iBaseSize = (uint)Marshal.SizeOf(
     typeof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P));
     uint iNumberOfElements = returnLength / iBaseSize;
     _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P[] oData =
     new _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX_P[iNumberOfElements];
     uint iAllocatedSize = iNumberOfElements * iBaseSize;
     //----------------------------------------------
     // Get The Requested Data
     //----------------------------------------------
     if (!GetLogicalProcessorInformationExWrapper(
     aType, oData, ref iAllocatedSize))
         return null;
     else
         return oData;
 }