📄 umsthreadproxy.h
字号:
/// Returns true if the thread is terminated
/// </returns>
bool IsTerminated();
/// <summary>
/// Returns the next context which was pulled off the UMS completion list. This call can only be made until one of these objects is
/// rescheduled. After that, the results of the call become undefined.
/// </summary>
/// <returns>
/// Pointer to the unblock notification (context).
/// </returns>
IUMSUnblockNotification *GetNextUnblockNotification()
{
PSLIST_ENTRY psle = m_listEntry.Next;
UMSThreadProxy *pProxy = psle == NULL ? NULL : CONTAINING_RECORD(psle, UMSThreadProxy, m_listEntry);
return pProxy;
}
/// <summary>
/// Indicates whether this is a primary or not.
/// </summary>
/// <returns>
/// True if this is the primary thread, false otherwise
/// </returns>
virtual bool IsPrimary()
{
return false;
}
#if defined(_DEBUG)
/// <summary>
/// Tells the proxy it's no longer shutting down a virtual processor root and normal lock validations apply.
/// </summary>
void ClearShutdownValidations()
{
m_fShutdownValidations = false;
}
/// <summary>
/// Tells the proxy it's shutting down a virtual processor root and normal lock validations don't apply.
/// </summary>
void SetShutdownValidations()
{
m_fShutdownValidations = true;
}
/// <summary>
/// Returns whether or not the proxy is in a "shutting down a virtual processor root" mode where normal lock validations don't apply.
/// </summary>
bool IsShutdownValidations() const
{
return m_fShutdownValidations;
}
#endif // _DEBUG
#if _UMSTRACE
void Trace(int traceEvt, void *pCtx, void *pVproc, ULONG_PTR data)
{
m_traceBuffer.Trace(traceEvt, pCtx, pVproc, data);
}
#endif // _UMSTRACE
/// <summary>
/// Returns whether this proxy is transmogrified (e.g.: running on its own dedicated primary to simulate being an NT thread).
/// This call is only valid on the *CURRENT PROXY* otherwise the answer may be stale at the moment of return.
/// </summary>
/// <returns>
/// Ture if this proxy is transmogrified.
/// </returns>
bool IsTransmogrified() const
{
return m_pTransmogrification != NULL;
}
protected:
// The thread proxy factory that created this thread proxy, and maintains the idle pool of thread proxies.
IThreadProxyFactory * m_pFactory;
// The UMS context for the underlying UT.
PUMS_CONTEXT m_pUMSContext;
// The OS handle for the underlying UT.
HANDLE m_hPhysicalContext;
// The blocking handle.
HANDLE m_hBlock;
enum BlockingType
{
// No blocking registered.
BlockingNone,
// Normal blocking
BlockingNormal,
// Critical blocking (e.g.: masking a page fault)
BlockingCritical
};
// How we last blocked.
volatile BlockingType m_blockingType;
// The virtual processor root on which this thread proxy is executing.
UMSFreeVirtualProcessorRoot * volatile m_pRoot;
// The last virtual processor root on which this thread proxy was executing.
UMSFreeVirtualProcessorRoot *m_pLastRoot;
// Stores the stack size of the thread proxy. Multiply by 1 KB to get actual stack size in bytes.
unsigned int m_stackSize;
// Stores the last priority value that was set on the thread. Initial value is normal priority.
int m_threadPriority;
// An indication as to whether this thread proxy was idle pooled.
bool m_fIdlePooled;
// **************************************************
// Messaging Block:
//
// Everything between these markers is a messaging block between the UT and the primary. These fields may *ONLY* be touched under
// guardianship of a hyper-critical region.
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// *************************
// Input to the primary:
// The action that the primary is to take.
enum YieldAction
{
// No message
ActionNone = 0,
// Switch to a new context. The old one is still in use.
ActionSwitchTo,
// Switch to a new context and retire the old one to a free pool.
ActionSwitchToAndRetire,
// Perform a transmogrification of the context (start it on the transmogrified primary)
ActionTransmogrify,
// Deactivate the primary
ActionDeactivate,
// Get rid of the thread
ActionFree,
// Reset the primary on a SwitchOut
ActionResetForSwitchOut,
// UT Startup
ActionStartup,
// Yield to the operating system (SwitchToThread)
ActionYieldToSystem
} m_yieldAction;
// The next thread proxy that should be executed.
UMSThreadProxy *m_pNextProxy;
// The primary which will transmogrify this UMS thread into a "virtual"-thread.
TransmogrifiedPrimary * volatile m_pTransmogrification;
// *************************
// Output from the primary:
// Why Deactivate returned.
enum ActivationCause
{
ActivationCauseNone = 0,
ActivationCauseActivate,
ActivationCauseCompletionNotification
};
// Results of messaged calls to the primary are marshaled back to the UT here.
union
{
// Indicates why Deactivate returned.
ActivationCause m_activationCause;
};
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// End Messaging Block:
// **************************************************
bool m_fSuspended;
volatile LONG m_fCanceled;
/// <summary>
/// Called in order to prepare this thread proxy to run atop a given virtual processor root.
/// </summary>
void PrepareToRun(UMSFreeVirtualProcessorRoot *pRoot);
/// <summary>
/// Spins until we've registered blocking.
/// </summary>
void SpinUntilBlocked();
/// <summary>
/// Spins until we've registered what blocking type the last block operation was and returns the type.
/// </summary>
BlockingType SpinOnAndReturnBlockingType();
/// <summary>
/// Switch from the current thread proxy to pProxy.
/// </summary>
/// <param name="pProxy">
/// The thread proxy to switch to.
/// </param>
/// <param name="switchState">
/// The reason for the switch.
/// </param>
void InternalSwitchTo(UMSThreadProxy *pProxy, SwitchingProxyState switchState);
/// <summary>
/// Switch out the current thread proxy.
/// </summary>
void InternalSwitchOut();
/// <summary>
/// Yield to the underlying Operating system
/// </summary>
void InternalYieldToSystem();
/// <summary>
/// Deactivate the current thread proxy. As this requires a message block set, it lives here
/// rather than in the VPROOT.
/// </summary>
/// <returns>
/// An indication of whether the awakening was due to an Activate call on the virtual processor root
/// (true) or an RM cause (e.g.: completion notification -- false).
/// </returns>
bool Deactivate();
/// <summary>
/// The caller has exited the dispatch loop. Free the thread and deactivate.
/// <summary>
void FreeViaExit();
private:
friend class UMSFreeVirtualProcessorRoot;
friend class UMSSchedulerProxy;
friend class UMSBackgroundPoller;
friend class Transmogrificator;
friend class TransmogrifiedPrimary;
friend class UMSFreeThreadProxyFactory;
template<class T> friend class SQueue;
#if _UMSTRACE
_TraceBuffer m_traceBuffer;
#endif // _UMSTRACE
// Intrusive Link Field
UMSThreadProxy *m_pNext;
// Process wide unique identifier.
unsigned int m_id;
// Tracks the depth of critical region entry within the RM.
DWORD m_criticalRegionCount;
// Tracks the depth of hyper-critical region entry within the RM.
DWORD m_hyperCriticalRegionCount;
// Thread id.
DWORD m_threadId;
// Link chain for the transfer list.
SLIST_ENTRY m_listEntry;
// The background poller list chain.
UMSBackgroundPollerEntry m_backgroundPollerEntry;
// The chain entries for transmogrification.
ListEntry m_transmogrificatorPendingQueue;
// The background poller notification proxy.
UMSSchedulerProxy *m_pPollInsertionProxy;
// BEGIN - USED IN DEBUG ONLY
__int64 m_lastRunPrepareTimeStamp;
DWORD m_UMSDebugBits;
DWORD m_UMSLastExecuteError;
bool m_fShutdownValidations;
// END - USED IN DEBUG ONLY
/// <summary>
/// Indicate that the thread proxy is ready for dispatch.
/// </summary>
void ReadyForDispatch();
/// <summary>
/// Dispatch routine for thread proxies.
/// </summary>
virtual void Dispatch() = 0;
/// <summary>
/// Thread start routine for proxies.
/// </summary>
static DWORD CALLBACK UMSThreadProxyMain(LPVOID lpParameter);
};
} // namespace details
} // namespace Concurrency
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -