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

📄 resourcemanager.h

📁 C语言库函数的原型,有用的拿去
💻 H
📖 第 1 页 / 共 3 页
字号:
// ==++==
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// ResourceManager.h
//
// Implementation of IResourceManager.
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

#pragma once 

namespace Concurrency
{
namespace details
{
    class ResourceManager : public Concurrency::IResourceManager
    {
    public:
        /// <summary>
        ///     Increments the reference count on a resource manager.
        /// </summary>
        /// <returns>
        ///     Returns the resulting reference count.
        /// </returns>
        virtual unsigned int Reference();

        /// <summary>
        ///     Decrements the reference count on a resource manager.
        /// </summary>
        /// <returns>
        ///     Returns the resulting reference count.
        /// </returns>
        virtual unsigned int Release();

        /// <summary>
        ///     Associates an IScheduler with the ISchedulerProxy that represents the part
        ///     of IResourceManager associated with the IScheduler.
        /// </summary>
        /// <param name="pScheduler">
        ///     The scheduler to be associated.
        /// </param>
        /// <param name="version">
        ///     The version of the RM<->Scheduler communication channel that is being utilized.
        /// </param>
        virtual ISchedulerProxy * RegisterScheduler(IScheduler *pScheduler, unsigned int version);

        /// <summary>
        ///     Creates an instance of the resource manager.
        /// </summary>
        static ResourceManager* CreateSingleton();

        /// <summary>
        ///     Returns the OS version.
        /// </summary>
        static IResourceManager::OSVersion Version();

        /// <summary>
        ///     Returns whether we must work around a Win7 RTM UMS bug.
        /// </summary>
        static bool RequireUMSWorkaround()
        {
            return s_fRequireUMSWorkaround;
        }

        /// <summary>
        ///     Returns the number of nodes (processor packages or NUMA nodes)
        /// </summary>
        static unsigned int GetNodeCount();

        /// <summary>
        ///     Returns the number of cores.
        /// </summary>
        static unsigned int GetCoreCount();

        /// <summary>
        ///     Returns a pointer to the manager of factories for thread proxies.
        /// </summary>
        ThreadProxyFactoryManager * GetThreadProxyFactoryManager() { return &m_threadProxyFactoryManager; }

        /// <summary>
        ///     These APIs return unique identifiers for use by schedulers, execution contexts and thread proxies.
        /// </summary>
        static unsigned int GetSchedulerId() { return InterlockedIncrement(&s_schedulerIdCount); }
        static unsigned int GetExecutionContextId() { return InterlockedIncrement(&s_executionContextIdCount); }
        static unsigned int GetThreadProxyId() { return InterlockedIncrement(&s_threadProxyIdCount); }

        /// <summary>
        ///     Creates UMS background threads.
        /// </summary>
        void CreateUMSBackgroundThreads();

        /// <summary>
        ///     Returns an instance of the UMS background poller thread.
        /// </summary>
        UMSBackgroundPoller *GetUMSBackgroundPoller() { return m_pUMSPoller; }

        /// <summary>
        ///     Returns an instance of transmogrificator.
        /// </summary>
        Transmogrificator *GetTransmogrificator() { return m_pTransmogrificator; }

        /// <summary>
        ///     The main allocation routine that allocates cores for a newly created scheduler proxy.
        /// </summary>
        ExecutionResource * PerformAllocation(SchedulerProxy *pSchedulerProxy, bool doExternalThreadAllocation);

        /// <summary>
        ///     This API registers the current thread with the resource manager, associating it with this scheduler proxy,
        ///     and returns an instance of IExecutionResource back to the scheduler, for bookkeeping and maintenance.
        /// </summary>
        ExecutionResource * SubscribeCurrentThread(SchedulerProxy *pSchedulerProxy);

        /// <summary>
        ///     The allocation routine that allocates a single core for a newly registered external thread.
        /// </summary>
        ExecutionResource * PerformExternalThreadAllocation(SchedulerProxy *pSchedulerProxy);

        /// <summary>
        ///     Removes an execution resource that was created for an external thread.
        /// </summary>
        void RemoveExecutionResource(ExecutionResource * pExecutionResource);

        /// <summary>
        ///     Called in order to notify the resource manager that the given scheduler is shutting down.  This
        ///     will cause the resource manager to immediately reclaim all resources granted to the scheduler.
        /// </summary>
        void Shutdown(SchedulerProxy *pProxy);

        /// <summary>
        ///     Called by a scheduler in order make an initial request for an allocation of virtual processors.  The request
        ///     is driven by policies within the scheduler queried via the IScheduler::GetPolicy method.  If the request
        ///     can be satisfied via the rules of allocation, it is communicated to the scheduler as a call to
        ///     IScheduler::AddVirtualProcessors.
        /// </summary>
        /// <param name="pProxy">
        ///     The scheduler proxy that is making the allocation request.
        /// </param>
        /// <param name="doSubscribeCurrentThread">
        ///     Whether to subscribe the current thread and account for it during resource allocation.
        /// </param>
        /// <returns>
        ///     The IExecutionResource instance representing current thread if doSubscribeCurrentThread was true; NULL otherwise.
        /// </returns>
        IExecutionResource * RequestInitialVirtualProcessors(SchedulerProxy *pProxy, bool doSubscribeCurrentThread);

        /// <summary>
        ///     Debug CRT test hook to create artificial topologies. With the retail CRT, this API simply returns.
        /// </summary>
        virtual void CreateNodeTopology(unsigned int nodeCount, unsigned int *pCoreCount, unsigned int **pNodeDistance, unsigned int *pProcessorGroups);

        /// <summary>
        ///     The API returns after ensuring that all store buffers on processors that are running threads from this process,
        ///     are flushed. It does this by either calling a Win32 API that explictly does this on versions of Windows that
        ///     support the functionality, or by changing the protection on a page that is locked into the working set, forcing
        ///     a TB flush on all processors in question.
        /// </summary>
        void FlushStoreBuffers();

        /// <summary>
        ///     Returns the TLS slot where information about an execution resource is supposed to be stored.
        /// </summary>
        /// <remarks>
        ///     Used to check whether SubscribeCurrentThread already has an execution resource on which it is running.
        /// </remarks>
        DWORD GetExecutionResourceTls() const
        {
            return m_threadProxyFactoryManager.GetExecutionResourceTls();
        }

        /// <summary>
        ///     Decrements the use count on a particular global core. Used for removal of external threads.
        /// </summary>
        void DecrementCoreUseCount(unsigned int nodeId, unsigned int coreIndex)
        {
            // NOTE: Caller is responsible for holding the RM lock!
            GlobalCore * pGlobalCore = &(m_pGlobalNodes[nodeId].m_pCores[coreIndex]);
            pGlobalCore->m_useCount--;
        }

        /// <summary>
        ///     Returns the current thread's node id and core id (relative to that node).
        /// </summary>
        unsigned int GetCurrentNodeAndCore(unsigned int * pCore);

        /// <summary>
        ///     Returns the global subscription level of the underlying core.
        /// </summary>
        unsigned int CurrentSubscriptionLevel(unsigned int nodeId, unsigned int coreIndex);

        /// <summary>
        ///     Returns true if there are any schedulers in the RM that need notifications sent, false, otherwise.
        /// </summary>
        bool SchedulersNeedNotifications()
        {
            return (m_numSchedulersNeedingNotifications > 0);
        }

        /// <summary>
        ///     Returns the number of schedulers that need core busy/idle notifications.
        /// </summary>
        unsigned int GetNumSchedulersForNotifications()
        {
            return m_numSchedulersNeedingNotifications;
        }

        /// <summary>
        ///     Wakes up the dynamic RM worker from a wait state.
        /// </summary>
        void WakeupDynamicRMWorker()
        {
            SetEvent(m_hDynamicRMEvent);
        }

        /// <summary>
        ///     Sends NotifyResourcesExternallyIdle/NotifyResourcesExternallyBusy notifications to the schedulers that
        ///     qualify for them, to let them know that the hardware resources allocated to them are in use or out of use
        ///     by other schedulers that share those resources.
        /// </summary>
        /// <param name ="pNewlyAllocatedProxy">
        ///     The newly allocated scheduler proxy, if one was just allocated.
        /// </param>
        void SendResourceNotifications(SchedulerProxy * pNewlyAllocatedProxy = NULL);

        /// <summary>
        ///     Inform the resource manager that termination is happening.
        /// </summary>
        static void SetTerminating()
        {
            InterlockedExchange(&s_terminating, 1);
        }

        /// <summary>
        ///     Queries the resource manager to determine if termination is happening.
        /// </summary>
        static bool IsTerminating()
        {
            return (s_terminating != 0);
        }

    private:

        // State that controls what the dynamic RM worker thread does.
        enum DynamicRMWorkerState

⌨️ 快捷键说明

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