// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // // UMSThreadVirtualProcessor.h // // Header file containing the metaphor for a UMS thread based virtual processor // // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- #pragma once namespace Concurrency { namespace details { class UMSThreadVirtualProcessor : public VirtualProcessor { public: /// /// Construct a UMS virtual processor /// UMSThreadVirtualProcessor(SchedulingNode *pOwningNode, IVirtualProcessorRoot *pOwningRoot); /// /// Destroy the UMS virtual processor /// virtual ~UMSThreadVirtualProcessor(); /// /// Start a worker context executing on this.virtual processor. /// virtual bool StartupWorkerContext(ScheduleGroupSegmentBase* pSegment, InternalContextBase *pContext); /// /// Makes a virtual processor available for scheduling work. This can only be called from the scheduling /// context. /// void MakeAvailableFromSchedulingContext(); /// /// Returns true if it is safe for a context to enter the critical region on this virtual processor. /// If there is already a context in the critical region on this vproc, the routine returns false. /// bool CanCriticalEnter() { return (m_pCriticalContext == NULL); } /// /// Notification that a critically blocked context has come off the completion list. /// void CriticalNotify(); /// /// Returns the default destination of a SwitchTo(NULL). UMS schedulers trigger a return to primary. /// virtual IExecutionContext *GetDefaultDestination() { return (IExecutionContext *)m_pSchedulingContext; } /// /// Attempts to wake the virtual processor due to a notification coming in that is critical to progress on /// the virtual processor (e.g.: a critically blocked context coming back on the completion list from /// another virtual processor). /// void AttemptWake(); /// /// Stub called in SFW before we search for runnable contexts. /// /// /// A context which should be run. /// virtual InternalContextBase *PreRunnableSearch(); protected: /// /// Affinitizes an internal context to the virtual processor. /// /// /// The internal context to affinitize. /// virtual void Affinitize(InternalContextBase *pContext); /// /// Returns a type-cast of pContext to an InternalContextBase or NULL if it is not. /// virtual InternalContextBase *ToInternalContext(IExecutionContext *pContext); /// /// Initializes the virtual processor. This API is called by the constructor, and when a virtual processor is to /// be re-initialized, when it is pulled of the free pool in the list array. /// /// /// The owning schedule node for this virtual processor /// /// /// The owning IVirtualProcessorRoot /// virtual void Initialize(SchedulingNode *pOwningNode, IVirtualProcessorRoot *pOwningRoot); private: friend class UMSSchedulingContext; // Indication that a critical context for this virtual processor is ready to run volatile LONG m_fCriticalIsReady; // The Scheduling context for this virtual processor. Note that we *NEVER* deactivate the scheduling context. UMSSchedulingContext *m_pSchedulingContext; // The critically blocked context. UMSThreadInternalContext *m_pCriticalContext; // The startup scheduling group segment. This may only be touched when m_pExecutingContext is NULL. ScheduleGroupSegmentBase *m_pStartingSegment; }; } // namespace details } // namespace Concurrency