📄 virtualprocessor.h
字号:
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// VirtualProcessor.h
//
// Source file containing the VirtualProcessor declaration.
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#pragma once
namespace Concurrency
{
namespace details
{
//
// virtualized hardware thread
//
/// <summary>
/// A virtual processor is an abstraction of a hardware thread. However, there may very well be more than one
/// virtual processor per hardware thread. The <c>SchedulerPolicy</c> key <c>TargetOversubscriptionFactor</c> determines
/// the number of virtual processor per hardware thread, scheduler wide.
/// </summary>
/// <remarks>
/// Virtual processors may be created and destroyed at any time, since resource management (RM) may give or take
/// away hardware threads. But as such batches of <c>TargetOversubscriptionFactor</c> virtual processors are created or
/// destroyed simultaneously.
/// </remarks>
class VirtualProcessor
{
public:
/// <summary>
/// Constructs a virtual processor.
/// </summary>
VirtualProcessor();
/// <summary>
/// Destroys a virtual processor
/// </summary>
virtual ~VirtualProcessor();
/// <summary>
/// Returns a scheduler unique identifier for the virtual processor.
/// </summary>
unsigned int GetId() const { return m_id; }
/// <summary>
/// Rambling -- searching foreign nodes for work. When work is found, update state accordingly.
/// </summary>
void UpdateRamblingState(bool rambling, SchedulingRing *pCurrentRing);
/// <summary>
/// Attempts to claim exclusive ownership of the virtual processor by resetting the the available flag.
/// </summary>
/// <returns>
/// True if it was able to claim the virtual processor, false otherwise.
/// </returns>
bool ClaimExclusiveOwnership();
/// <summary>
/// Makes a virtual processor available for scheduling work.
/// </summary>
void MakeAvailable();
/// <summary>
/// Returns a pointer to the internal context that is executing on this virtual processor.
/// </summary>
IExecutionContext * GetExecutingContext() { return m_pExecutingContext; }
/// <summary>
/// Returns a pointer to the owning node for the virtual processor.
/// </summary>
SchedulingNode * GetOwningNode() { return m_pOwningNode; }
/// <summary>
/// Returns a pointer to the owning ring for the virtual processor.
/// </summary>
SchedulingRing * GetOwningRing() { return m_pOwningRing; }
/// <summary>
/// Returns a pointer to the owning root for the virtual processor.
/// </summary>
IVirtualProcessorRoot * GetOwningRoot() { return m_pOwningRoot; }
/// <summary>
/// Returns a pointer to the suballocator for the virtual processor.
/// </summary>
SubAllocator * GetCurrentSubAllocator();
/// <summary>
/// Returns true if the virtual processor is marked as available, false otherwise.
/// </summary>
bool IsAvailable() { return (m_fAvailable == TRUE); }
/// <summary>
/// Returns true if the virtual processor is marked for retirement, false otherwise.
/// </summary>
bool IsMarkedForRetirement() { return m_fMarkedForRetirement; }
/// <summary>
/// Activates a virtual processor with the context provided.
/// </summary>
void Activate(IExecutionContext *pContext);
/// <summary>
/// Temporarily deactivates a virtual processor.
/// <summary>
/// <returns>
/// An indication of which side the awakening occured from (true -- we activated it, false -- the RM awoke it).
/// </returns>
bool Deactivate(IExecutionContext *pContext);
/// <summary>
/// Invokes the underlying virtual processor root to ensure all tasks are visible.
/// </summary>
void EnsureAllTasksVisible(IExecutionContext * pContext);
#if _UMSTRACE
void Trace(int traceEvt, void *pCtx, void *pVproc, ULONG_PTR data)
{
m_traceBuffer.Trace(traceEvt, pCtx, pVproc, data);
}
#endif // _UMSTRACE
/// <summary>
/// Returns the default destination of a SwitchTo(NULL). There is none on a default virtual processor.
/// </summary>
virtual IExecutionContext *GetDefaultDestination()
{
return NULL;
}
/// <summary>
/// Performs a search for work for the given virtual processor.
/// </summary>
bool SearchForWork(WorkItem *pWorkItem, ScheduleGroupBase *pOriginGroup)
{
return m_searchCtx.Search(pWorkItem, pOriginGroup);
}
/// <summary>
/// Performs a search for work for the given virtual processor only allowing certain types of work to be found.
/// </summary>
bool SearchForWork(WorkItem *pWorkItem, ScheduleGroupBase *pOriginGroup, WorkItem::WorkItemType allowableTypes)
{
return m_searchCtx.Search(pWorkItem, pOriginGroup, allowableTypes);
}
/// <summary>
/// Performs a yielding search for work for the given virtual processor.
/// </summary>
bool SearchForWorkInYield(WorkItem *pWork, ScheduleGroupBase *pOriginGroup)
{
return m_searchCtx.YieldingSearch(pWork, pOriginGroup);
}
/// <summary>
/// Performs a yielding search for work for the given virtual processor only allowing certain types of work to be found.
/// </summary>
bool SearchForWorkInYield(WorkItem *pWorkItem, ScheduleGroupBase *pOriginGroup, WorkItem::WorkItemType allowableTypes)
{
return m_searchCtx.YieldingSearch(pWorkItem, pOriginGroup, allowableTypes);
}
/// <summary>
/// Stub called in SFW before we search for runnable contexts.
/// </summary>
/// <returns>
/// A context which should be run.
/// </returns>
virtual InternalContextBase *PreRunnableSearch()
{
return NULL;
}
/// <summary>
/// Called when the context running atop this virtual processor has reached a safe point.
/// </summary>
/// <returns>
/// An indication of whether the caller should perform a commit.
/// </returns>
bool SafePoint();
/// <summary>
/// Hides or unhides a virtual processor. This may only be called for oversubscribed virtual processors in certain places!
/// </summary>
void Hide(bool fHidden)
{
m_fHidden = fHidden;
}
/// <summary>
/// Returns whether an oversubscribed virtual processor is "hidden" currently.
/// </summary>
bool IsHidden() const
{
return m_fHidden;
}
/// <summary>
/// Notifies the virtual processor that its activation is being throttled or unthrottled.
/// </summary>
void ThrottleActivation(bool fThrottled)
{
m_fThrottled = fThrottled;
}
/// <summary>
/// Answers the instantaneous query as to whether the virtual processor is throttled. This information is stale the moment it is returned.
/// </summary>
bool IsThrottled() const
{
return (m_fThrottled);
}
protected:
//
// protected data
//
// Indicates whether vproc is available to perform work.
volatile LONG m_fAvailable;
// Local caching of realized chores/contexts
StructuredWorkStealingQueue<InternalContextBase, _HyperNonReentrantLock> m_localRunnableContexts;
// The search context which keeps track of where this virtual processor is in a search-for-work regardless of algorithm.
WorkSearchContext m_searchCtx;
// Owning scheduling node -- immutable
SchedulingNode *m_pOwningNode;
// Current scheduling node
SchedulingRing *m_pCurrentRing;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -