📄 schedulerresourcemanagement.cpp
字号:
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// SchedulerResourceManagement.cpp
//
// Implementation of IScheduler.
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#include "concrtinternal.h"
namespace Concurrency
{
namespace details
{
/// <summary>
/// Constructs an instance of the class that handles communication with the resource manager on behalf of a scheduler.
/// </summary>
SchedulerResourceManagement::SchedulerResourceManagement(SchedulerBase *pScheduler)
: m_pScheduler(pScheduler)
{
}
/// <summary>
/// Returns a scheduler unique identifier for the context.
/// </summary>
/// <returns>
/// The Id for the IScheduler.
/// </returns>
unsigned int SchedulerResourceManagement::GetId() const
{
return m_pScheduler->m_id;
}
/// <summary>
/// Called by the resource manager in order to gather statistics for a given scheduler. The statistics gathered here
/// will be used to drive dynamic feedback with the scheduler to determine when it is appropriate to assign more resources
/// or take resources away. Note that these counts can be optimistic and do not necessarily have to reflect the current
/// count with 100% synchronized accuracy.
/// </summary>
/// <param name="pTaskCompletionRate">
/// The number of tasks which have been completed by the scheduler since the last call to the Statistics method.
/// </param>
/// <param name="pTaskArrivalRate">
/// The number of tasks that have arrived in the scheduler since the last call to the Statistics method.
/// </param>
/// <param name="pNumberOfTasksEnqueued">
/// The total number of tasks in all scheduler queues.
/// </param>
void SchedulerResourceManagement::Statistics(unsigned int *pTaskCompletionRate, unsigned int *pTaskArrivalRate, unsigned int *pNumberOfTasksEnqueued)
{
m_pScheduler->Statistics(pTaskCompletionRate, pTaskArrivalRate, pNumberOfTasksEnqueued);
}
/// <summary>
/// Get the scheduler policy.
/// </summary>
/// <returns>
/// The policy of the scheduler.
/// </returns>
SchedulerPolicy SchedulerResourceManagement::GetPolicy() const
{
return m_pScheduler->GetPolicy();
}
/// <summary>
/// Called when the resource manager is giving virtual processors to a particular scheduler. The virtual processors are
/// identified by an array of IVirtualProcessorRoot interfaces. This call is made to grant virtual processor roots
/// at initial allocation during the course of ISchedulerProxy::RequestInitialVirtualProcessors, and during dynamic
/// core migration.
/// </summary>
/// <param name="pVirtualProcessorRoots">
/// An array of IVirtualProcessorRoot interfaces representing the virtual processors being added to the scheduler.
/// </param>
/// <param name="count">
/// Number of IVirtualProcessorRoot interfaces in the array.
/// </param>
void SchedulerResourceManagement::AddVirtualProcessors(IVirtualProcessorRoot **ppVirtualProcessorRoots, unsigned int count)
{
if (ppVirtualProcessorRoots == NULL)
throw std::invalid_argument("ppVirtualProcessorRoots");
if (count < 1)
throw std::invalid_argument("count");
for (unsigned int idx = 0; idx < count; ++idx)
m_pScheduler->AddVirtualProcessor(ppVirtualProcessorRoots[idx]);
}
/// <summary>
/// Called when the resource manager is taking away virtual processors from a particular scheduler. The scheduler should
/// mark the supplied virtual processors such that they are removed asynchronously and return immediately. Note that
/// the scheduler should make every attempt to remove the virtual processors as quickly as possible as the resource manager
/// will reaffinitize threads executing upon them to other resources. Delaying stopping the virtual processors may result
/// in unintentional oversubscription within the scheduler.
/// </summary>
/// <param name="pVirtualProcessorRoots">
/// An array of IVirtualProcessorRoot interfaces representing the virtual processors which are to be removed.
/// </param>
/// <param name="count">
/// Number of IVirtualProcessorRoot interfaces in the array.
/// </param>
void SchedulerResourceManagement::RemoveVirtualProcessors(IVirtualProcessorRoot **ppVirtualProcessorRoots, unsigned int count)
{
if (ppVirtualProcessorRoots == NULL)
throw std::invalid_argument("ppVirtualProcessorRoots");
if (count < 1)
throw std::invalid_argument("count");
for (unsigned int idx = 0; idx < count; ++idx)
m_pScheduler->RemoveVirtualProcessor(ppVirtualProcessorRoots[idx]);
}
/// <summary>
/// Called when the resource manager is made aware that the hardware threads underneath the virtual processors assigned to
/// this particular scheduler are 'externally idle' once again i.e. any other schedulers that may have been using them have
/// stopped using them. This API is called only when a scheduler proxy was created with MinConcurrency = MaxConcurrency.
/// </summary>
/// <param name="pVirtualProcessorRoots">
/// An array of IVirtualProcessorRoot interfaces representing the virtual processors on which other schedulers have become idle.
/// </param>
/// <param name="count">
/// Number of IVirtualProcessorRoot interfaces in the array.
/// </param>
void SchedulerResourceManagement::NotifyResourcesExternallyIdle(IVirtualProcessorRoot **ppVirtualProcessorRoots, unsigned int count)
{
}
/// <summary>
/// Called when the resource manager is made aware that the execution resources underneath the virtual processors assigned to
/// this particular scheduler are busy (active) on other schedulers. The reason these execution resources were lent to
/// other schedulers is usually a lack of activation on the part of this scheduler, or a system-wide oversubscription.
/// This API is called only when a scheduler proxy was created with MinConcurrency = MaxConcurrency.
/// </summary>
/// <param name="pVirtualProcessorRoots">
/// An array of IVirtualProcessorRoot interfaces representing the virtual processors on which other schedulers have become busy.
/// </param>
/// <param name="count">
/// Number of IVirtualProcessorRoot interfaces in the array.
/// </param>
void SchedulerResourceManagement::NotifyResourcesExternallyBusy(IVirtualProcessorRoot **ppVirtualProcessorRoots, unsigned int count)
{
}
/// <summary>
/// After requesting initial threads from the resource manager, a scheduler which specifies it wishes UMS threads will be called from the
/// resource manager with a completion list interface which allows the scheduler to determine when UMS threads have unblocked. Note that
/// this interface is only allowed to be touched from a thread running on a virtual processor root.
/// </summary>
/// <param name="pCompletionList">
/// The completion list interface for the scheduler. There is a single list per scheduler.
/// </param>
void SchedulerResourceManagement::SetCompletionList(IUMSCompletionList *pCompletionList)
{
static_cast<UMSThreadScheduler *>(m_pScheduler)->SetCompletionList(pCompletionList);
}
} // namespace details
} // namespace Concurrency
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -