⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 resourcemanager.cpp

📁 C语言库函数的原型,有用的拿去
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            }

            pfnGetLogicalProcessorInformationEx((LOGICAL_PROCESSOR_RELATIONSHIP) RelationAll, NULL, &s_logicalProcessorInformationLength);

            if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
            {
                throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));
            }

            ASSERT(s_logicalProcessorInformationLength > 0);

            s_pSysInfo = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION) malloc(s_logicalProcessorInformationLength);

            if (s_pSysInfo == NULL)
            {
                throw std::bad_alloc();
            }

            if ( !pfnGetLogicalProcessorInformationEx((LOGICAL_PROCESSOR_RELATIONSHIP) RelationAll,
                (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) s_pSysInfo, &s_logicalProcessorInformationLength))
            {
                throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));
            }

            // Cast this buffer as a PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, which is needed for GetLogicalProcessorInformationEx
            PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX pSysInfoEx = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) s_pSysInfo;
            DWORD byteOffset = 0;
            s_packageCount = 0;
            s_nodeCount = 0;
            s_physicalProcessorCount = 0;

            // Traverse the processor information buffer to find s_nodeCount, s_packageCount and s_physicalProcessorCount.
            // It's possible for a package to contain multiple NUMA nodes.  In the case were we have more NUMA nodes than
            // packages, we will create one scheduling node pre NUMA node.  Otherwise, we create one scheduling node per
            // package
            while (byteOffset < s_logicalProcessorInformationLength)
            {
                if (pSysInfoEx->Relationship == RelationProcessorPackage)
                {
                    ++s_packageCount;
                }

                if (pSysInfoEx->Relationship == RelationNumaNode)
                {
                    ++s_nodeCount;
                }

                if (pSysInfoEx->Relationship == RelationProcessorCore)
                {
                    s_physicalProcessorCount += NumberOfBitsSet(pSysInfoEx->Processor.GroupMask[0].Mask);
                }

                byteOffset += pSysInfoEx->Size;
                pSysInfoEx = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) ((PBYTE)pSysInfoEx + pSysInfoEx->Size);
            }

            ASSERT(s_logicalProcessorInformationLength > 0);
            ASSERT(s_packageCount > 0);
            ASSERT(s_nodeCount > 0);

            if (!fSaveTopologyInfo)
            {
                free(s_pSysInfo);
                s_pSysInfo = NULL;
                s_logicalProcessorInformationLength = 0;
            }

            // Initialize function pointers to APIs that are only present on these operating systems and higher.
            InitializeSystemFunctionPointers();
        }
        else
        {
#ifdef  _M_IX86
            typedef BOOL (WINAPI *PFnGetLogicalProcessorInformation)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
            PFnGetLogicalProcessorInformation pfnGetLogicalProcessorInformation
                = (PFnGetLogicalProcessorInformation) GetProcAddress(GetModuleHandleW(L"kernel32.dll"),
                                                                     "GetLogicalProcessorInformation");
            if (pfnGetLogicalProcessorInformation == NULL)
            {
               throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));
            }

            pfnGetLogicalProcessorInformation(NULL, &s_logicalProcessorInformationLength);
#else
            GetLogicalProcessorInformation(NULL, &s_logicalProcessorInformationLength);
#endif
            if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
            {
                throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));
            }

            ASSERT(s_logicalProcessorInformationLength > 0);

            s_pSysInfo = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION) malloc(s_logicalProcessorInformationLength);

            if (s_pSysInfo == NULL)
            {
                throw std::bad_alloc();
            }

#ifdef  _M_IX86
            if (!pfnGetLogicalProcessorInformation(s_pSysInfo, &s_logicalProcessorInformationLength))
#else
            if (!GetLogicalProcessorInformation(s_pSysInfo, &s_logicalProcessorInformationLength))
#endif
            {
                throw scheduler_resource_allocation_error(HRESULT_FROM_WIN32(GetLastError()));
            }

            // Traverse the processor information buffer to find s_nodeCount and s_packageCount.
            // It's possible for a package to contain multiple NUMA nodes.  In the case were we have more NUMA nodes than
            // packages, we will create one scheduling node pre NUMA node.  Otherwise, we create one scheduling node per
            // package
            PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pSysInfo = s_pSysInfo;
            DWORD byteOffset = 0;
            s_packageCount = 0;
            s_nodeCount = 0;
            s_physicalProcessorCount = info.dwNumberOfProcessors;

            while (byteOffset < s_logicalProcessorInformationLength)
            {
                if (pSysInfo->Relationship == RelationProcessorPackage)
                {
                    ++s_packageCount;
                }

                if (pSysInfo->Relationship == RelationNumaNode)
                {
                    ++s_nodeCount;
                }

                byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
                ++pSysInfo; 
            }

            ASSERT(s_logicalProcessorInformationLength > 0);
            ASSERT(s_packageCount > 0);
            ASSERT(s_nodeCount > 0);

            if (!fSaveTopologyInfo)
            {
                free(s_pSysInfo);
                s_pSysInfo = NULL;
                s_logicalProcessorInformationLength = 0;
            }
        }

        if (s_version == ::Concurrency::IResourceManager::UmsThreadAwareOS)
        {
            UMS::Initialize();
        }

        ASSERT(s_physicalProcessorCount > 0 && s_physicalProcessorCount <= USHORT_MAX);
    }

    /// <summary>
    ///     Creates a structure of nodes and cores based on the machine topology.
    /// </summary>
    void ResourceManager::DetermineTopology()
    {
        ASSERT(m_pGlobalNodes == NULL);
        ASSERT(s_nodeCount > 0 && s_nodeCount <= INT_MAX);

        m_nodeCount = (s_nodeCount >= s_packageCount) ? s_nodeCount : s_packageCount;

        // There is some ambiguity around the behavior of this API for OSs < Vista. Set node count to
        // 1 for these OSs, as other areas of the implementation make assumptions around this.
        if (s_pSysInfo == NULL)
        {
            ASSERT(s_version == ::Concurrency::IResourceManager::XP || s_version == ::Concurrency::IResourceManager::Win2k3);
            ASSERT(m_nodeCount == 1);

            m_pGlobalNodes = new GlobalNode[m_nodeCount];
            memset(m_pGlobalNodes, 0, sizeof(GlobalNode));
            m_pSortedNodeOrder= new unsigned int[m_nodeCount];
            *m_pSortedNodeOrder = 0;

            m_pGlobalNodes->m_pCores = new GlobalCore[s_physicalProcessorCount];
            m_pGlobalNodes->m_coreCount = s_physicalProcessorCount;

            ULONG_PTR processAffinityMask = 0;
            ULONG_PTR systemAffinityMask = 0;

            BOOL retVal = GetProcessAffinityMask(GetCurrentProcess(), &processAffinityMask, &systemAffinityMask);
            ASSERT(retVal == TRUE);

            m_pGlobalNodes->m_nodeAffinity = processAffinityMask;

            memset(m_pGlobalNodes->m_pCores, 0, m_pGlobalNodes->m_coreCount * sizeof(GlobalCore));
            m_pGlobalNodes->m_processorGroup = 0;

            m_pGlobalNodes->m_pSortedCoreOrder = new unsigned int[m_pGlobalNodes->m_coreCount];

            for (unsigned int i = 0; i < m_pGlobalNodes->m_coreCount; ++i)
            {
                m_pGlobalNodes->m_pCores[i].m_processorNumber = (BYTE) i;
                m_pGlobalNodes->m_pSortedCoreOrder[i] = i;
            }
        }
        else
        {
            m_pGlobalNodes = new GlobalNode[m_nodeCount];
            memset(m_pGlobalNodes, 0, m_nodeCount * sizeof(GlobalNode));

            m_pSortedNodeOrder = new unsigned int[m_nodeCount];
            for (unsigned int i = 0; i < m_nodeCount; ++i)
            {
                m_pSortedNodeOrder[i] = i;
            }

            // Win7 or higher has a PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX structure to support > 64 cores
            if (s_version == ::Concurrency::IResourceManager::Win7OrLater || s_version == ::Concurrency::IResourceManager::UmsThreadAwareOS)
            {
                // Traverse the processor information buffer for a second time to populate the node structures.
                DWORD byteOffset = 0;
                PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX pSysInfoEx = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) s_pSysInfo;
                unsigned int index = 0;

                while (byteOffset < s_logicalProcessorInformationLength)
                {
                    switch (pSysInfoEx->Relationship)
                    {
                        case RelationProcessorCore:
                            break;

                        case RelationProcessorPackage:
                            {
                                // If this machine had more packages than NUMA nodes, we should create one scheduling node per package.
                                if (s_packageCount > s_nodeCount)
                                {
                                    ASSERT(pSysInfoEx->Processor.GroupCount == 1);
                                    m_pGlobalNodes[index].Initialize(index, pSysInfoEx->Processor.GroupMask[0].Group, pSysInfoEx->Processor.GroupMask[0].Mask);
                                    ++index;
                                }
                            }
                            break;
                        case RelationNumaNode:
                            {
                                // If this machine had more NUMA nodes than packages, we should create one scheduling node per NUMA node.
                                if (s_packageCount <= s_nodeCount)
                                {
                                    m_pGlobalNodes[index].Initialize(index, pSysInfoEx->NumaNode.GroupMask.Group, pSysInfoEx->NumaNode.GroupMask.Mask);
                                    ++index;
                                }
                            }
                            break;
                    }

                    byteOffset += pSysInfoEx->Size;
                    pSysInfoEx = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX) ((PBYTE)pSysInfoEx + pSysInfoEx->Size); 
                }

                ASSERT(index == m_nodeCount);
                free(s_pSysInfo);
                s_pSysInfo = NULL;
                s_logicalProcessorInformationLength = 0;
            }
            else
            {
                // Traverse the processor information buffer for a second time to populate the node structures.
                DWORD byteOffset = 0;
                PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pSysInfo = s_pSysInfo;
                unsigned int index = 0;

                while (byteOffset < s_logicalProcessorInformationLength)
                {
                    switch (pSysInfo->Relationship)
                    {
                        case RelationProcessorCore:
                            break;

                        case RelationProcessorPackage:
                            {
                                // If this machine had more packages than NUMA nodes, we should create one scheduling node per package.
                                if (s_packageCount > s_nodeCount)
                                {
                                    m_pGlobalNodes[index].Initialize(index, 0, pSysInfo->ProcessorMask);
                                    ++index;
                                }
                            }
                            break;

                        case RelationNumaNode:
                            {
                                // If this machine had more NUMA nodes than packages, we should create one scheduling node per NUMA node.
                                if (s_packageCount <= s_nodeCount)
                                {
                                    m_pGlobalNodes[index].Initialize(index, 0, pSysInfo->ProcessorMask);
                                    ++index;
                                }
                            }
                            break;
                    }

                    byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
                    ++pSysInfo; 
                }

                ASSERT(index == m_nodeCount);
                free(s_pSysInfo);
                s_pSysInfo = NULL;
                s_logicalProcessorInformationLength = 0;
            }
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -