// ==++== // // 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)