// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// threadscheduler.h
//
// Header file containing the metaphor for a thread based concrt scheduler
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#pragma once
#pragma warning (push)
#pragma warning (disable: 4100) // unreferenced formal parameter, for comments
namespace Concurrency
{
namespace details
{
class ThreadScheduler : public IScheduler, public SchedulerBase
{
public:
///
/// Creates a thread based scheduler
///
ThreadScheduler(_In_ const ::Concurrency::SchedulerPolicy& pPolicy);
///
/// Creates a thread based scheduler
///
static ThreadScheduler* Create(_In_ const ::Concurrency::SchedulerPolicy& pPolicy);
///
/// Create the correct flavor of virtual processor
///
virtual VirtualProcessor *CreateVirtualProcessor(SchedulingNode *pOwningNode, IVirtualProcessorRoot *pOwningRoot);
///
/// Destroys a thread based scheduler
///
virtual ~ThreadScheduler();
///
/// Returns a scheduler unique identifier for the context.
///
///
/// The Id for the IScheduler.
///
virtual unsigned int GetId() const { return Id(); }
///
/// Get the scheduler policy.
///
///
/// The policy of the scheduler.
///
virtual SchedulerPolicy GetPolicy() const
{
return SchedulerBase::GetPolicy();
}
///
/// 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.
///
///
/// The number of tasks which have been completed by the scheduler since the last call to the Statistics method.
///
///
/// The number of tasks that have arrived in the scheduler since the last call to the Statistics method.
///
///
/// The total number of tasks in all scheduler queues.
///
virtual void Statistics(unsigned int *pTaskCompletionRate, unsigned int *pTaskArrivalRate, unsigned int *pNumberOfTasksEnqueued)
{
SchedulerBase::Statistics(pTaskCompletionRate, pTaskArrivalRate, pNumberOfTasksEnqueued);
}
///
/// 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.
///
///
/// An array of IVirtualProcessorRoot interfaces representing the virtual processors being added to the scheduler.
///
///
/// Number of IVirtualProcessorRoot interfaces in the array.
///
virtual void AddVirtualProcessors(IVirtualProcessorRoot **ppVirtualProcessorRoots, unsigned int count)
{
SchedulerBase::AddVirtualProcessors(ppVirtualProcessorRoots, count);
}
///
/// 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.
///
///
/// An array of IVirtualProcessorRoot interfaces representing the virtual processors which are to be removed.
///
///
/// Number of IVirtualProcessorRoot interfaces in the array.
///
virtual void RemoveVirtualProcessors(IVirtualProcessorRoot **ppVirtualProcessorRoots, unsigned int count)
{
SchedulerBase::RemoveVirtualProcessors(ppVirtualProcessorRoots, count);
}
///
/// 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.
///
///
/// An array of IVirtualProcessorRoot interfaces representing the virtual processors on which other schedulers have become idle.
///
///
/// Number of IVirtualProcessorRoot interfaces in the array.
///
virtual void NotifyResourcesExternallyIdle(IVirtualProcessorRoot ** ppVirtualProcessorRoots, unsigned int count) {}
///
/// 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.
///
///
/// An array of IVirtualProcessorRoot interfaces representing the virtual processors on which other schedulers have become busy.
///
///
/// Number of IVirtualProcessorRoot interfaces in the array.
///
virtual void NotifyResourcesExternallyBusy(IVirtualProcessorRoot ** ppVirtualProcessorRoots, unsigned int count) {}
///
/// Returns an IScheduler interface.
///
///
/// An IScheduler interface.
///
virtual IScheduler * GetIScheduler() { return this; }
protected:
///
/// Creates a new thread internal context and returns it to the base scheduler.
///
virtual InternalContextBase *CreateInternalContext();
private:
// Hide the assignment operator and copy constructor.
ThreadScheduler const &operator =(ThreadScheduler const &); // no assign op
ThreadScheduler(ThreadScheduler const &); // no copy ctor
};
} // namespace details
} // namespace Concurrency
#pragma warning (pop)