// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // ExecutionResource.h // // Part of the ConcRT Resource Manager -- this header file contains the internal definition for the // execution resource. // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #pragma once namespace Concurrency { namespace details { #pragma warning(push) #pragma warning(disable: 4265) // non-virtual destructor in base class /// /// An abstraction for an execution resource -- an entity on top of which a single thread of execution (of whatever /// type) runs. /// class ExecutionResource final : public IExecutionResource { public: /// /// Constructs a new execution resource. /// /// /// The scheduler proxy this resource is created for. A scheduler proxy holds RM data associated with an instance of /// a scheduler. /// /// /// The processor node that this resource belongs to. The processor node is one among the nodes allocated to the /// scheduler proxy. /// /// /// The index into the array of cores for the processor node specified. /// ExecutionResource(SchedulerProxy *pSchedulerProxy, SchedulerNode* pNode, unsigned int coreIndex); /// /// Constructs a new execution resource. /// /// /// The scheduler proxy this resource is created for. A scheduler proxy holds RM data associated with an instance of /// a scheduler. /// /// The parent execution resource representing this thread /// scheduler proxy. /// ExecutionResource(SchedulerProxy * pSchedulerProxy, ExecutionResource * pParentExecutionResource); /// /// Destroys an execution resource. /// ~ExecutionResource() { ASSERT(m_numThreadSubscriptions == 0); } /// /// Returns a unique identifier for the node that the given execution resource belongs to. The identifier returned /// will fall in the range [0, nodeCount] where nodeCount is the value returned from Concurrency::GetProcessorNodeCount. /// virtual unsigned int GetNodeId() const { return m_nodeId; } /// /// Returns a unique identifier for the execution resource that this execution resource runs atop. /// virtual unsigned int GetExecutionResourceId() const { return m_executionResourceId; } /// /// Called to indicate that a scheduler is done with an execution resource and wishes to return it to the resource manager. /// /// /// The scheduler making the request to remove this execution resource. /// virtual void Remove(IScheduler *pScheduler); /// /// Returns the subscription level on the core that this execution resource represents /// /// /// A current subscription level of the underlying execution resource. /// virtual unsigned int CurrentSubscriptionLevel() const; // ************************************************** // Internal // ************************************************** /// /// Returns a pointer to the scheduler proxy this execution resource was created by. /// SchedulerProxy * GetSchedulerProxy() { return m_pSchedulerProxy; } /// /// Returns the core index into the array of cores, for the node that this execution resource is part of. /// unsigned int GetCoreIndex() { return m_coreIndex; } /// /// Retrieves a virtual processor root that contains this execution resource, if any. /// VirtualProcessorRoot * GetVirtualProcessorRoot() { return m_pVirtualProcessorRoot; } /// /// Set this execution resource as current on this thread /// void SetAsCurrent(); /// /// Clear the current execution resource on this thread. /// void ResetCurrent(); /// /// Initializes the execution resource as either standalone or belonging to virtual processor root. /// void MarkAsVirtualProcessorRoot(VirtualProcessorRoot * pVPRoot) { ASSERT(m_pVirtualProcessorRoot == NULL); m_pVirtualProcessorRoot = pVPRoot; } /// /// Increments the number of external threads that run on this execution resource as well as /// the number of fixed threads that are running on the underlying core. /// /// /// This information is used to validate matching SubscribeCurrentThread/Release calls, as well as /// to mark a core on which this resource runs as fixed (not-movable). /// void IncrementUseCounts(); /// /// Called to update the crucial counts, which must be done under the RM lock. /// void DecrementUseCounts(); protected: // Guards critical regions of the Execution Resource _NonReentrantLock m_lock; // The previous affinity of the external thread HardwareAffinity m_oldAffinity; // The scheduler proxy associated with the scheduler for which // this resource was created. SchedulerProxy * m_pSchedulerProxy; // Parent execution resource in the case of a nested subscribe ExecutionResource * m_pParentExecutionResource; // Virtual processor root that this execution resource is a part of, if any VirtualProcessorRoot * m_pVirtualProcessorRoot; // The value to use when external resource subscription of a virtual processor is removed size_t m_tlsResetValue; // The node to which this execution resource belongs. unsigned int m_nodeId; // The core index within this node. unsigned int m_coreIndex; // The hardware thread upon which this execution resource executes. unsigned int m_executionResourceId; // Number of subscription requests that have been received for this execution resource. unsigned int m_numThreadSubscriptions; private: template friend class List; // Intrusive links ExecutionResource * m_pPrev{}, * m_pNext{}; }; #pragma warning(pop) } // namespace details } // namespace Concurrency