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

📄 rminternal.h

📁 C语言库函数的原型,有用的拿去
💻 H
📖 第 1 页 / 共 2 页
字号:
// ==++==
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// rminternal.h
//
// Main internal header file for ConcRT's Resource Manager.
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

#pragma once

namespace Concurrency
{
namespace details
{
    // The lowest two bits are used to determine the type of the pointer stored in the
    // execution resource TLS slot (created in the RM).
    static const size_t TlsResourceBitMask = 0x3;
    static const size_t TlsResourceInResource = 0x0;
    static const size_t TlsResourceInProxy = 0x1;
    static const size_t TlsResourceInUMSProxy = 0x2;

    // The RM has an array of processor nodes and cores representing the hardware topology on the machine.
    // Every scheduler that asks for an allocation, gets it's own copy of this array of nodes/cores once they
    // have been granted an allocation of cores by the RM, that is stored in the corresponding scheduler proxy.

    /// <summary>
    ///     An abstraction of a hardware affinity that understands how to deal with affinity on both Win7 and pre-Win7
    ///     platforms.
    /// </summary>
    struct HardwareAffinity
    {
    public:

        /// <summary>
        ///     Construct an empty affinity.
        /// </summary>
        HardwareAffinity()
        {
            memset(&m_affinity, 0, sizeof(m_affinity));
            m_affinity.Group = 0;
            m_affinity.Mask = 0;
        }

        /// <summary>
        ///     Construct a hardware affinity from a given thread.
        /// </summary>
        HardwareAffinity(HANDLE hThread);

        /// <summary>
        ///    Construct a Win7 understood affinity.
        /// </summary>
        HardwareAffinity(USHORT processorGroup, ULONG_PTR affinityMask) 
        {
            memset(&m_affinity, 0, sizeof(m_affinity));
            m_affinity.Group = processorGroup;
            m_affinity.Mask = affinityMask;
        }

        /// <summary>
        ///     Construct a pre-Win7 understood affinity.
        /// </summary>
        HardwareAffinity(DWORD_PTR affinityMask)
        {
            memset(&m_affinity, 0, sizeof(m_affinity));
            m_affinity.Group = 0;
            m_affinity.Mask = affinityMask;
        }

        /// <summary>
        ///     Copy construct an affinity.
        /// </summary>
        HardwareAffinity(const HardwareAffinity &src)
        {
            memcpy(&m_affinity, &src.m_affinity, sizeof(m_affinity));
        }

        /// <summary>
        ///     Compare two affinities
        /// </summary>
        bool operator==(const HardwareAffinity &rhs)
        {
            return (rhs.m_affinity.Group == m_affinity.Group && rhs.m_affinity.Mask == m_affinity.Mask);
        }

        /// <summary>
        ///     Compare two affinities
        /// </summary>
        bool operator!=(const HardwareAffinity &rhs)
        {
            return !operator==(rhs);
        }

        /// <summary>
        ///     Copy an affinity.
        /// </summary>
        HardwareAffinity& operator=(const HardwareAffinity &rhs)
        {
            m_affinity.Group = rhs.m_affinity.Group;
            m_affinity.Mask = rhs.m_affinity.Mask;
            return *this;
        }

        /// <summary>
        ///     Applies this hardware affinity to a thread.
        /// </summary>
        /// <param name="hThread">
        ///     The thread handle to which to apply this affinity.
        /// </param>
        void ApplyTo(HANDLE hThread);

        /// <summary>
        ///     Initializes the SetThreadGroupAffinity function for Win 7 and higher.
        /// </summary>
        static void InitializeSetThreadGroupAffinityFn();

    private:

        // A pointer to a kernel32 function that exists only on Win7 and higher
        typedef BOOL (WINAPI *PFnSetThreadGroupAffinity)(HANDLE, PGROUP_AFFINITY, PGROUP_AFFINITY);
        static PFnSetThreadGroupAffinity s_pfnSetThreadGroupAffinity;

        // A pointer to a kernel32 function that exists only on Win7 and higher
        typedef BOOL (WINAPI *PFnGetThreadGroupAffinity)(HANDLE, PGROUP_AFFINITY);
        static PFnGetThreadGroupAffinity s_pfnGetThreadGroupAffinity;

        GROUP_AFFINITY m_affinity;

    };

    /// <summary>
    ///     Base class for description of a core or hardware thread.
    /// </summary>
    struct ProcessorCore
    {
        enum CoreState
        {
            // The core available for allocation
            Available = 0,

            // The core is allocated to a scheduler
            Allocated,

            // When cores are freed up from other schedulers, this will be the state they set their copy of the
            // core to, while setting the global copy to Available. This will enable them to track the cores they
            // have relinquished. If the new scheduler is not allocated this core, it will revert back to Allocated
            // for the scheduler proxy it came from.
            Stolen,

            // The core is reserved for a possible allocation
            Reserved,

            // A core is considered idle during dynamic core migration if the scheduler(s) that core is assigned
            // to, have all vprocs de-activated.
            Idle
        };

        // 'Available' means available for assignment to a scheduler during the allocation calculation.
        CoreState m_coreState;

        // The processor number in Win7 {group, processor number} id scheme.
        BYTE m_processorNumber;
    };

    /// <summary>
    ///     Representation of a processor core within the RM's global map of execution resources. Information in this struct
    ///     represents a systemwide view of the underlying hardware thread.
    /// </summary>
    struct GlobalCore : public ProcessorCore
    {
        // The number of schedulers that this core is assigned to.
        unsigned int m_useCount;

        // Used to send notifications to qualifying schedulers regarding external subscription level changes.
        LONG m_currentSubscriptionLevel;
        LONG m_previousSubscriptionLevel;

        // This field is used during core migration to represent the number of schedulers that this core has been allocated
        // to, that have also deactivated all virtual processors on the core, i.e. the number of schedulers that are 'idle'
        // with respect to this core. When this is equal to the use count, the core is considered 'idle'.
        unsigned int m_idleSchedulers;
    };

    /// <summary>
    ///     Representation of a processor core within a scheduler proxy's local map of execution resources. Information in this struct
    ///     represents the schedulers utilization of the underlying hardware thread.
    /// </summary>
    struct SchedulerCore : public ProcessorCore
    {
        // When virtual processor roots are created for a scheduler proxy, or external threads are subscribed, the corresponding
        // execution resources are inserted into this list.
        List<ExecutionResource, CollectionTypes::Count> m_resources;

        // This field represents the number of activated virtual processors and subscribed threads that a scheduler has
        // on this core at any time. When a virtual processor root is deactivated, or when a thread subscription is released
        // the count is decremented. The core is considered to be 'idle' in the scheduler it belongs to, if this value is 0.
        volatile LONG m_subscriptionLevel;

        // Used to send notifications to qualifying schedulers regarding external subscription level changes.
        LONG m_currentSubscriptionLevel;
        LONG m_previousSubscriptionLevel;

        // The number of threads that were assigned to this core through initial allocation or core migration.
        // Note that this is not necessarily equal to the number of roots in the m_resources list, since the list
        // includes oversubscribed vproc roots as well.
        unsigned int m_numAssignedThreads;

        // The total number of threads (running on vprocs and external) that require this core to be fixed.
        unsigned int m_numFixedThreads;

        // The number of external threads that run on this core.
        unsigned int m_numExternalThreads;

        // This is set to true for a scheduler proxy's core during static allocation or core migration if the subscription
        // level on the core is found to be 0 when the Dynamic RM worker is executing. The subscription value can change
        // as soon as it is captured, but the captured value is what is used for successive computation.
        bool m_fIdleDuringDRM;

        // This is set to true for a scheduler proxy's core during core migration, if this is an borrowed core.
        // An borrowed core is a core that is assigned to one or more different schedulers, but was found to be idle.
        // The RM temporarily assigns idle resources to schedulers that need them.
        bool m_fBorrowed;

        // This variable is set to true when a borrowed core is converted to a fixed core. When the core is unfixed,
        // it is marked borrowed again.
        bool m_fPreviouslyBorrowed;

        /// <summary>
        ///     Returns whether this core is fixed, i.e., cannot be removed by the RM.
        /// </summary>
        bool IsFixed()
        {
            return m_numFixedThreads > 0;
        }

        /// <summary>
        ///     Returns whether this core is idle, i.e., its subscription level was 0 at the time it was retreived by the RM.
        ///     Note that this state could change, but once we capture it, we consider it idle until the next time it is captured.
        /// </summary>
        bool IsIdle()
        {
            return m_fIdleDuringDRM;
        }

        /// <summary>
        ///     Returns whether this core is borrowed, i.e., it was temporarily lent to this scheduler due to the owning
        ///     scheduler being idle on this core.
        /// </summary>
        bool IsBorrowed()
        {
            return m_fBorrowed;
        }
    };

    /// <summary>
    ///     Base class for the description of a processor package or NUMA node.
    /// </summary>
    struct ProcessorNode
    {
        // affinity mask of node
        ULONG_PTR m_nodeAffinity;

        // total number of cores in the node
        unsigned int m_coreCount;

        // number of cores allocated to the scheduler proxy (this field is only applicable to a scheduler proxy's nodes)
        unsigned int m_allocatedCores;

        // A scratch field used during allocation. The allocation routine works by looking at cores with m_useCount=0,
        // grabs all it can, then looks at m_useCount=1, then m_useCount=2, etc... During an allocation attempt at a particular
        // use count, cores that are allocated at previous use counts are stored in m_allocatedCores, and cores available at the
        // current use count are stored in m_availableForAllocation. A subset of those may be allocated to the scheduler proxy,
        // and that number is added to m_allocatedCores before moving on.
        unsigned int m_availableForAllocation;

        // The group number in Win7 {group, mask} id scheme
        unsigned int m_processorGroup;

        // The node id which maps to a scheduler node id.
        unsigned int m_id;
    };

    /// <summary>
    ///     Representation of a processor node within a scheduler proxy's local map of execution resources. Information in this struct
    ///     represents the schedulers utilization of the underlying node.
    /// </summary>
    struct SchedulerNode : public ProcessorNode
    {
        // The number of allocated cores that are borrowed. An borrowed core is a core that is assigned to
        // one or more different schedulers, but was found to be idle. The RM temporarily assigns idle resources to
        // schedulers that need them.
        unsigned int m_numBorrowedCores;

        // The number of cores on this node that are considered fixed. Fixed cores cannot be removed by the RM during static/dynamic allocation.
        unsigned int m_numFixedCores;

        // The number of cores in this node for the scheduler in question that were found to be idle during the dynamic RM phase. This is

⌨️ 快捷键说明

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