📄 schedulerproxy.h
字号:
void SendCoreNotification(SchedulerCore * pCore, bool isBusyNotification);
/// <summary>
/// Removes a root from the scheduler proxy and destroys it. This API is called in response to a scheduler
/// informing the RM that it is done with a virtual processor root.
/// </summary>
void DestroyVirtualProcessorRoot(VirtualProcessorRoot * pRoot);
/// <summary>
/// Removes an execution resource from the scheduler proxy and destroys it. This API is called in response to a scheduler
/// informing the RM that it is done with an execution resource.
/// </summary>
void DestroyExecutionResource(ExecutionResource * pExecutionResource);
/// <summary>
/// Returns a hardware affinity for the given node. Note that a scheduler proxy may only be assigned a subset
/// of cores within a node -> the mask in the affinity reflects this subset.
/// </summary>
/// <returns>
/// An abstraction of the hardware affinity which can be applied to Win32 objects.
/// </returns>
HardwareAffinity GetNodeAffinity(unsigned int nodeId)
{
ASSERT(nodeId < m_nodeCount);
ASSERT(m_pAllocatedNodes[nodeId].m_id == nodeId);
return HardwareAffinity(m_pAllocatedNodes[nodeId].m_processorGroup, m_pAllocatedNodes[nodeId].m_nodeAffinity);
}
/// <summary>
/// Adds an execution resource to the list of resources that run on a particular core.
/// </summary>
void AddExecutionResource(ExecutionResource * pExecutionResource);
/// <summary>
/// Adds the execution resource to the list of subscribed threads
/// </summary>
void AddThreadSubscription(ExecutionResource * pExecutionResource);
/// <summary>
/// Removes the execution resource from the list of subscribed threads
/// </summary>
void RemoveThreadSubscription(ExecutionResource * pExecutionResource);
/// <summary>
/// Creates or reuses an execution resource for the thread subscription
/// </summary>
ExecutionResource * GetResourceForNewSubscription(ExecutionResource * pParentExecutionResource);
/// <summary>
/// This function retrieves the execution resource associated with this thread, if one exists,
/// and updates the reference count on it for better bookkeeping.
/// </summary>
/// <returns>
/// The ExecutionResource instance representing current thread in the runtime.
/// </returns>
ExecutionResource * ReferenceCurrentThreadExecutionResource();
/// <summary>
/// This function retrieves the execution resource associated with this thread, if one exists.
/// </summary>
/// <returns>
/// The ExecutionResource instance representing current thread in the runtime.
/// </returns>
ExecutionResource * GetCurrentThreadExecutionResource();
/// <summary>
/// Registers that a call to SubscribeCurrentThread has occured for this core, making this core immovable.
/// </summary>
void IncrementFixedCoreCount(unsigned int nodeId, unsigned int coreIndex, bool isExternalThread);
/// <summary>
/// Registers that a call to IExecutionResource::Release has occured, potentially freeing this core.
/// </summary>
void DecrementFixedCoreCount(unsigned int nodeId, unsigned int coreIndex, bool isExternalThread);
/// <summary>
/// Returns the number of external threads on this scheduler proxy.
/// </summary>
unsigned int GetNumExternalThreads()
{
return m_numExternalThreads;
}
/// <summary>
/// Decides whether this scheduler proxy should receive notifications when other
/// schedulers borrow its cores or return them back.
/// </summary>
bool ShouldReceiveNotifications()
{
return (m_minimumHardwareThreads == m_desiredHardwareThreads);
}
/// <summary>
/// A function that passes statistical information to the hill climbing instance. Based on these
/// statistics, hill climbing will make a recommendation on the number of resources the scheduler
/// should be allocated.
/// </summary>
/// <param name="currentCoreCount">
/// The number of resources used in this period of time.
/// </param>
/// <param name="completionRate">
/// The number of completed units or work in that period of time.
/// </param>
/// <param name="arrivalRate">
/// The number of incoming units or work in that period of time.
/// </param>
/// <param name="queueLength">
/// The total length of the work queue.
/// </param>
/// <returns>
/// The recommended allocation for the scheduler.
/// </returns>
unsigned int DoHillClimbing(unsigned int currentCoreCount, unsigned int completionRate, unsigned int arrivalRate, unsigned int queueLength)
{
return m_pHillClimbing->Update(currentCoreCount, completionRate, arrivalRate, queueLength);
}
/// <summary>
/// This function returns whether the scheduler has opted in to statistical rebalancing.
/// </summary>
/// <returns>
/// Whether hill climbing is enabled.
/// </returns>
bool IsHillClimbingEnabled()
{
return m_fDoHillClimbing;
}
/// <summary>
/// Gets the current length of the scheduler queue.
/// </summary>
/// <returns>
/// The queue length.
/// </returns>
unsigned int GetQueueLength()
{
return m_queueLength;
}
/// <summary>
/// Sets the current length of the scheduler queue.
/// </summary>
/// <param name="queueLength">
/// The length to be set.
/// </param>
void SetQueueLength(unsigned int queueLength)
{
m_queueLength = queueLength;
}
/// <summary>
/// Gets a new thread proxy from the factory.
/// </summary>
virtual IThreadProxy * GetNewThreadProxy(IExecutionContext * pContext);
/// <summary>
/// Called to shutdown a scheduler proxy. Derived classes can override shutdown behavior based on this.
/// </summary>
virtual void FinalShutdown();
/// <summary>
/// Called to assist dynamic resourcemanagement in determining whether cores assigned to schedulers
/// are idle. An idle core is one whose subscription level is 0.
/// </summary>
void IncrementCoreSubscription(ExecutionResource * pExecutionResource);
/// <summary>
/// Called to assist dynamic resourcemanagement in determining whether cores assigned to schedulers
/// are idle. An idle core is one whose subscription level is 0.
/// </summary>
void DecrementCoreSubscription(ExecutionResource * pExecutionResource);
#if defined(CONCRT_TRACING)
/// <summary>
/// Captures the initial state of the scheduler map at the beginning of core migration, each cycle.
/// </summary>
void TraceInitialDRMState();
/// <summary>
/// Dumps the allocation, for this scheduler proxy.
/// </summary>
void DumpAllocations();
#endif
protected:
/// <summary>
/// Deletes the scheduler proxy.
/// </summary>
virtual void DeleteThis()
{
delete this;
}
/// <summary>
/// Cleans up resources associated with the scheduler.
/// </summary>
void Cleanup();
/// <summary>
/// Destructor.
/// </summary>
~SchedulerProxy();
// A cached pointer to a thread proxy factory of the appropriate type for this scheduler proxy.
IThreadProxyFactory * m_pThreadProxyFactory;
private:
template <class T, class Counter> friend class List;
#if defined(CONCRT_TRACING)
struct SchedulerCoreData
{
unsigned char m_nodeIndex;
unsigned char m_coreIndex;
bool m_fAllocated : 1;
bool m_fFixed : 1;
bool m_fBorrowed : 1;
bool m_fIdle : 1;
};
// Captures the initial global allocation during the DRM phase.
SchedulerCoreData * m_drmInitialState;
unsigned int m_numTotalCores;
#endif
IScheduler * m_pScheduler;
// Pointer to the resource manager instance.
ResourceManager * m_pResourceManager;
// Local copy of allocation map for this scheduler proxy.
SchedulerNode * m_pAllocatedNodes;
// Helper array used to sort nodes, used by the RM during core migration.
unsigned int * m_pSortedNodeOrder;
// Links for a list.
SchedulerProxy * m_pNext, * m_pPrev;
// A lock that protects resource allocation and deallocation of roots within this proxy.
_ReentrantBlockingLock m_lock;
// Hill climbing instance.
HillClimbing * m_pHillClimbing;
// Static and dynamic allocation data is populated and manipulated by the RM, but
// stored in the scheduler proxy for convenience.
union
{
// Data used during static allocation.
StaticAllocationData m_staticData;
// Data used during dynamic allocation.
DynamicAllocationData m_dynamicData;
};
// Scheduler queue length.
unsigned int m_queueLength;
// Unique identifier.
unsigned int m_id;
// Variables that store policy elements.
unsigned int m_desiredHardwareThreads;
unsigned int m_minimumHardwareThreads;
unsigned int m_minConcurrency;
unsigned int m_maxConcurrency;
unsigned int m_targetOversubscriptionFactor;
int m_contextStackSize;
int m_contextPriority;
// Current concurrency level (number of vproc roots). This includes vproc roots
// that are marked for removal but has not yet been destroyed by the scheduler.
// Protected by the scheduler proxy lock
unsigned int m_currentConcurrency;
// The number of cores allocated to this scheduler proxy.
unsigned int m_numAllocatedCores;
// At any time this has the number of additional cores that can be allocated with m_tof threads.
// When this falls to 0, all remaining allocated cores will get m_tof - 1 threads, to ensure that
// we don't go over max concurrency threads.
unsigned int m_numFullySubscribedCores;
// 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 that have a subscribed thread on them. These cores are 'fixed' in that they cannot
// be removed by static/dynamic allocations, as long as the subscribed thread is present on them.
unsigned int m_numFixedCores;
// The number of virtual processors (threads) that were added to the related scheduler via initial
// allocation or core migration. Does not include oversubscribed virtual processors.
unsigned int m_numAssignedThreads;
// The number of external threads that were added to the related scheduler via external subscription calls.
unsigned int m_numExternalThreads;
// The number of cores that external threads occupy exclusively.
unsigned int m_numExternalThreadCores;
// The number of physical resources (hardware threads) available on this machine.
unsigned int m_physicalResourceCount;
// Number of nodes in the allocated nodes array.
unsigned int m_nodeCount;
// List of execution resources representing subscribed threads
List<ExecutionResource, CollectionTypes::Count> m_threadSubscriptions;
// Used during allocation to tell if cores were stolen from this proxy to satisfy a new allocation
// request.
bool m_fCoresStolen;
// Used to determine whether statistical rebalancing is used for this scheduler proxy.
bool m_fDoHillClimbing;
// Used to determine whether this SchedulerProxy needs an external thread allocation.
bool m_fNeedsExternalThreadAllocation;
};
} // namespace details
} // namespace Concurrency
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -