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

📄 resourcemanager.h

📁 C语言库函数的原型,有用的拿去
💻 H
📖 第 1 页 / 共 3 页
字号:
        ///         ReleaseOnlyBorrowedCores - scheduler should release all its borrowed cores.
        /// </param>
        /// <param name="borrowedCoresReleased">
        ///     Tells whether a previous call to this API was made for the scheduler that successfully released borrowed cores. If this is true
        ///     the scheduler should only have owned cores.
        /// </param>
        bool ReleaseSchedulerResources(SchedulerProxy *pSchedulerProxy, unsigned int numberToFree, bool borrowedCoresReleased = false);

        /// <summary>
        ///     Called to claim back any previously released cores that were not allocated to a different scheduler. If released
        ///     cores were allocated (stolen), the proxy needs to notify its scheduler to give up the related virtual processor
        ///     roots.
        /// <summary>
        void RestoreSchedulerResources(SchedulerProxy * pSchedulerProxy);

        /// <summary>
        ///     Called to allocate a single resource from the current scheduler proxy to accomodate an external thread during
        ///     thread subscription. This function is called only if there are cores above minimum that this proxy can replace
        ///     with the external thread.
        /// <summary>
        unsigned int ReleaseSchedulerResourceAboveMin(SchedulerProxy * pSchedulerProxy);

        /// <summary>
        ///     Starts up the dynamic RM worker thread if it is on standby, or creates a thread if one is not already created.
        ///     The worker thread wakes up at fixed intervals and load balances resources among schedulers, until it it put on standby.
        /// </summary>
        void CreateDynamicRMWorker();

        /// <summary>
        ///     Routine that performs dynamic resource management among existing schedulers at fixed time intervals.
        /// </summary>
        void DynamicResourceManager();

        /// <summary>
        ///     Performs a dynamic resource allocation based on feedback from hill climbing.
        /// </summary>
        void DoCoreMigration();

        /// <summary>
        ///     When the number of schedulers in the RM goes from 2 to 1, this routine is invoked to make sure the remaining scheduler
        ///     has its desired number of cores, before putting the dynamic RM worker on standby. It is also called when there is just
        ///     one scheduler with external subscribed threads that it removes -> there is a chance that this move may allow us to allocate
        ///     more vprocs.
        /// </summary>
        bool DistributeCoresToSurvivingScheduler();

        /// <summary>
        ///     This API is called by the dynamic RM worker thread when it starts up, and right after its state changed to
        ///     LoadBalance after being on Standby for a while. We need to find the existing schedulers, and discard the
        ///     statistics they have collected so far if any. Either we've never collected statistics for this scheduler before,
        ///     or too much/too little time has passed since we last collected statistics, and this information cannot be trusted.
        /// </summary>
        void DiscardExistingSchedulerStatistics();

        /// <summary>
        ///     Ensures that the memory buffers needed for static and dynamic RM are of the right size, and initializes them.
        /// </summary>
        void InitializeRMBuffers();

        /// <summary>
        ///     Populates data needed for allocation (static or dynamic).
        /// </summary>
        void PopulateCommonAllocationData(unsigned int index, SchedulerProxy * pSchedulerProxy, AllocationData * pAllocationData);

        /// <summary>
        ///     Captures data needed for static allocation, for all existing schedulers. This includes determining which
        ///     cores on a scheduler are idle.
        ///     A number of preprocessing steps are are also preformed before we are ready to allocate cores for a new scheduler.
        ///
        ///     - If a borrowed core is now in use by the other scheduler(s) that own that core, it is taken away.
        ///     - If the scheduler with the borrowed core is now the only scheduler using the core, it is not considered borrowed any more.
        /// </summary>
        void SetupStaticAllocationData(SchedulerProxy * pNewProxy, bool fNeedsExternalThreadAllocation);

        /// <summary>
        ///     Captures data needed for dynamic allocation for all existing schedulers. This includes gathering statistics
        ///     and invoking a per scheduler hill climbing instance, to get a suggested future allocation. Also, determines how may
        ///     idle cores a scheduler has.
        /// </summary>
        void PopulateDynamicAllocationData();

        /// <summary>
        ///     Resets state that was set on the global cores during static or dynamic allocation.
        /// </summary>
        void ResetGlobalState();

        /// <summary>
        ///     Toggles the idle state on a core and updates tracking counts.
        /// </summary>
        void ToggleRMIdleState(SchedulerNode * pAllocatedNode, SchedulerCore * pAllocatedCore,
                                GlobalNode * pGlobalNode, GlobalCore * pGlobalCore, AllocationData * pDRMData);

        /// <summary>
        ///     A number of preprocessing steps are preformed before we are ready to migrate cores. They include handling of borrowed, idle,
        ///     and shared cores, as follows:
        ///
        ///     - If a borrowed core is now in use by the other scheduler(s) that own that core, it is taken away.
        ///     - If the scheduler with the borrowed core is now the only scheduler using the core, it is not considered borrowed anymore.
        ///     - If hill climbing has suggested an allocation increase for a scheduler that has idle cores, or an allocation decrease that
        ///         does not take away all its idle cores, the RM overrides it, setting the suggested allocation for that scheduler to
        ///         max(minCores, allocatedCores - idleCores).
        ///
        ///       The new value of suggested allocation is used for the following:
        ///     - If the suggested allocation is less than the current allocation for a scheduler that has shared cores (cores oversubscribed
        ///         with a different scheduler), those cores are taken away here, since we want to minimize sharing.
        /// </summary>
        void PreProcessDynamicAllocationData();

        /// <summary>
        ///     Preprocessing steps for borrowed cores - both static and dynamic allocation start out with a call to this API.
        /// </summary>
        void HandleBorrowedCores(SchedulerProxy * pSchedulerProxy, AllocationData * pAllocationData);

        /// <summary>
        ///     Preprocessing steps for shared cores - this is used during dynamic core migration.
        /// </summary>
        void HandleSharedCores(SchedulerProxy * pSchedulerProxy, DynamicAllocationData * pAllocationData);

        /// <summary>
        ///     This routine increases the suggested allocation to desired, for schedulers with the following characteristics:
        ///     1) Hill climbing has *not* recommended an allocation decrease.
        ///     2) They are using all the cores allocated to them (no idle cores).
        ///     In the second round of core migration, we try to satisfy these schedulers' desired allocation.
        /// </summary>
        void IncreaseFullyLoadedSchedulerAllocations();

        /// <summary>
        ///     Decides on the number of additional cores to give a set of schedulers, given what the schedulers need and what is available.
        /// </summary>
        unsigned int AdjustDynamicAllocation(unsigned int coresAvailable, unsigned int coresNeeded, unsigned int numReceivers);

        /// <summary>
        ///     Initializes receiving proxy data in preparation for core transfer. Calcuates the number of partially filled nodes
        ///     for schedulers that are receiving cores, and sorts the receiving proxy data in increasing order of partial nodes.
        /// </summary>
        /// <returns>
        ///     Number of recivers that still need cores (allocation field of the receiving proxy data > 0).
        /// </returns>
        unsigned int PrepareReceiversForCoreTransfer(unsigned int numReceivers);

        /// <summary>
        ///     Assigns one core at a time to a partially filled node on a receiving scheduler proxy, if possible
        /// </summary>
        bool FindCoreForPartiallyFilledNode(unsigned int& unusedCoreQuota,
                                            unsigned int& usedCoreQuota,
                                            DynamicAllocationData * pReceivingProxyData,
                                            unsigned int numGivers);

        /// <summary>
        ///     Attempts to assign cores to a receiver on a single empty node, taking cores from multiple givers if necessary.
        /// </summary>
        unsigned int FindBestFitExclusiveAllocation(unsigned int& unusedCoreQuota,
                                                    unsigned int& usedCoreQuota,
                                                    DynamicAllocationData * pReceivingProxyData,
                                                    unsigned int remainingReceivers,
                                                    unsigned int numGivers);

        /// <summary>
        ///     Distributes unused cores and cores from scheduler proxies that are willing to give up cores to scheduler proxies that
        ///     need cores.
        /// </summary>
        void DistributeExclusiveCores(unsigned int totalCoresNeeded,
                                      unsigned int unusedCoreQuota,
                                      unsigned int usedCoreQuota,
                                      unsigned int numReceivers,
                                      unsigned int numGivers);

        /// <summary>
        ///     Attempts to assign cores to a receiver on a single empty node, using idle cores.
        /// </summary>
        unsigned int FindBestFitIdleAllocation(unsigned int idleCoresAvailable, DynamicAllocationData * pReceivingProxyData, unsigned int remainingReceivers);

        /// <summary>
        ///     Distributes idle cores to scheduler proxies that need cores.
        /// </summary>
        void DistributeIdleCores(unsigned int totalCoresAvailable, unsigned int numReceivers);

        /// <summary>
        ///     Assigns a fixed number of unused or idle cores to a scheduler from a given node.
        /// </summary>
        void DynamicAssignCores(SchedulerProxy * pReceivingProxy, unsigned int nodeIndex, unsigned int numCoresToMigrate, bool fIdle);

        /// <summary>
        ///     Transfers a fixed number of cores from one scheduler to another.
        /// </summary>
        void DynamicMigrateCores(DynamicAllocationData * pGivingProxyData, SchedulerProxy * pReceivingProxy, unsigned int nodeIndex, unsigned int numCoresToMigrate);

#if defined (CONCRT_TRACING)

        /// <summary>
        ///     Captures the initial state of the global map at the beginning of core migration, each cycle.
        /// </summary>
        void TraceInitialDRMState();

        /// <summary>
        ///     Captures data relating to an action during DRM preprocessing.
        /// </summary>
        void TracePreProcessingAction(SchedulerProxy * pProxy, unsigned int nodeIndex, unsigned int coreIndex,
                                      bool fMarkedAsOwned, bool fBorrowedCoreRemoved, bool fSharedCoreRemoved, bool fIdleCore);

        /// <summary>
        ///     Captures data relating to an action during DRM core migration.
        /// </summary>
        void TraceCoreMigrationAction(SchedulerProxy * pGiver, SchedulerProxy * pReceiver, unsigned int round, unsigned int nodeIndex,
                                      unsigned int coreIndex, bool fUnusedCoreMigration, bool fIdleCoreSharing, bool fBorrowedByGiver,
                                      bool fIdleOnGiver);

        /// <summary>
        ///     Dumps allocations, for existing scheduler proxies, and a newly allocated scheduler proxy, if specified.
        /// </summary>
        void DumpAllocations(SchedulerProxy *pSchedulerProxy = NULL);

        /// <summary>
        ///     Dumps the state of the global nodes in the RM - system wide view of resource allocation.
        /// </summary>
        void DumpGlobalNodes();

#endif
        /// <summary>
        ///     Performs borrowed core validation. A core can be borrowed by only one scheduler at a time.
        /// </summary>
        void ValidateBorrowedCores();

        /// <summary>
        ///     Performs state validations during dynamic core migration.
        /// </summary>
        void ValidateDRMSchedulerState();

        /// <summary>
        ///     Main thread procedure for the dynamic RM worker thread.
        /// </summary>
        /// <param name="lpParameter">
        ///     Resource manager pointer passed to the worker thread.
        /// </param>
        /// <returns>
        ///     Status on thread exit.
        /// </returns>
        static DWORD CALLBACK DynamicRMThreadProc(LPVOID lpParameter);

        /// <summary>
        ///     Given a set of scaled floating point allocations that add up to nSum, rounds them to integers.
        /// </summary>
        static void RoundUpScaledAllocations(AllocationData ** ppData, unsigned int count, unsigned int nSum);
    };
} // namespace details
} // namespace Concurrency

⌨️ 快捷键说明

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