📄 resourcemanager.h
字号:
{
Standby,
LoadBalance,
Exit
};
#if defined(CONCRT_TRACING)
struct GlobalCoreData
{
unsigned char m_nodeIndex;
unsigned char m_coreIndex;
unsigned char m_useCount;
unsigned char m_idleSchedulers;
};
// Maintains a trace for every core removed during preprocessing.
struct PreProcessingTraceData
{
SchedulerProxy * m_pProxy;
unsigned char m_nodeIndex;
unsigned char m_coreIndex;
bool m_fMarkedAsOwned : 1;
bool m_fBorrowedCoreRemoved : 1;
bool m_fSharedCoreRemoved : 1;
bool m_fIdleCore : 1;
};
// Maintains a trace for each core allocation
struct DynamicAllocationTraceData
{
SchedulerProxy * m_pGiver; // this is null if the core was unused or idle
SchedulerProxy * m_pReceiver;
unsigned char m_round;
unsigned char m_nodeIndex;
unsigned char m_coreIndex;
bool m_fUnusedCoreMigration : 1;
bool m_fIdleCoreSharing : 1;
bool m_fBorrowedByGiver : 1;
bool m_fIdleOnGiver : 1;
};
#endif
//
// Private data
//
// The singleton resource manager instance.
static ResourceManager *s_pResourceManager;
// A lock that protects setting of the singleton instance.
static _StaticLock s_lock;
// The total number of hardware threads on the system.
static unsigned int s_physicalProcessorCount;
// The number of processor packages on the system.
static unsigned int s_packageCount;
// The number of NUMA nodes on the system.
static unsigned int s_nodeCount;
// Operating system characteristics.
static bool s_fNativeX64;
static bool s_fRequireUMSWorkaround;
static IResourceManager::OSVersion s_version;
// Termination indicator
static volatile LONG s_terminating;
// Static counters to generate unique identifiers.
static volatile LONG s_schedulerIdCount;
static volatile LONG s_executionContextIdCount;
static volatile LONG s_threadProxyIdCount;
// Variables used to obtain information about the topology of the system.
static DWORD s_logicalProcessorInformationLength;
static PSYSTEM_LOGICAL_PROCESSOR_INFORMATION s_pSysInfo;
// Constants that are used as parameters to the ReleaseSchedulerResources API
static const unsigned int ReleaseCoresUptoMin = -1;
static const unsigned int ReleaseOnlyBorrowedCores = -2;
// RM instance reference count
volatile LONG m_referenceCount;
// Number of schedulers currently using resources granted by the RM.
unsigned int m_numSchedulers;
// The maximum number of schedulers the dynamic RM worker has resources to handle, at any time. This can
// change during the lifetime of the process.
unsigned int m_maxSchedulers;
// Number of schedulers in the RM that need resource notifications.
unsigned int m_numSchedulersNeedingNotifications;
// The number of processor packages on the system. This is a mirror of s_nodeCount above.
unsigned int m_nodeCount;
// A field used during core migration to keep track of the number of idle cores - cores such that
// all schedulers they are assigned to are not using them.
unsigned int m_dynamicIdleCoresAvailable;
// Keeps track of the allocation round during dynamic core migration. Used for tracing.
unsigned int m_allocationRound;
// A state variable that is used to control how the dynamic worker behaves.
volatile DynamicRMWorkerState m_dynamicRMWorkerState;
// A lock that protects resource allocation and deallocation.
_NonReentrantBlockingLock m_lock;
// The global allocation map for all schedulers - array of processor nodes.
GlobalNode * m_pGlobalNodes;
// An array that is used to represent sorted nodes during allocation.
unsigned int* m_pSortedNodeOrder;
// Handle to the dynamic RM worker thread.
HANDLE m_hDynamicRMThreadHandle;
// An event that is used to control the dynamic RM worker thread.
HANDLE m_hDynamicRMEvent;
// Data used for static and/or dynamic allocation.
AllocationData ** m_ppProxyData;
DynamicAllocationData ** m_ppGivingProxies;
DynamicAllocationData ** m_ppReceivingProxies;
// Lists to hold scheduler proxies.
List<SchedulerProxy, CollectionTypes::Count> m_schedulers;
// The UMS poller -- right now the thread which polls periodically for UMS completions of "odd threads" which don't show up on the completion
// list.
UMSBackgroundPoller *m_pUMSPoller;
// The transmogrificator. The object responsible for the transmogrification of UTs.
Transmogrificator *m_pTransmogrificator;
// A collection of thread proxy factories
ThreadProxyFactoryManager m_threadProxyFactoryManager;
// A pointer to a kernel32 function that exists only on versions of windows that are 6000 and higher.
typedef void (WINAPI *PFnFlushProcessWriteBuffers)(void);
PFnFlushProcessWriteBuffers m_pfnFlushProcessWriteBuffers;
// A pointer to a kernel32 function that exists only on versions of windows that are 6100 and higher.
typedef VOID (WINAPI *PFnGetCurrentProcessorNumberEx)(PPROCESSOR_NUMBER);
static PFnGetCurrentProcessorNumberEx s_pfnGetCurrentProcessorNumberEx;
// A pointer to a page that is used to flush write buffers on versions of Windows < 6000.
char* m_pPageVirtualProtect;
#if defined(CONCRT_TRACING)
// Captures the initial global state during the DRM phase.
GlobalCoreData * m_drmInitialState;
unsigned int m_numTotalCores;
// Maintains a trace for every core removed during preprocessing.
PreProcessingTraceData m_preProcessTraces[100];
unsigned int m_preProcessTraceIndex;
// Maintains a trace for each core allocation
DynamicAllocationTraceData m_dynAllocationTraces[100];
unsigned int m_dynAllocationTraceIndex;
#endif
//
// Private methods
//
// Private constructor.
ResourceManager();
// Private destructor.
~ResourceManager();
/// <summary>
/// Initializes static information such as os version, node and core counts.
/// </summary>
static void InitializeSystemInformation(bool fSaveTopologyInfo = false);
/// <summary>
/// Initialize function pointers that are only present on specific versions of the OS (Win7 or higher).
/// <summary>
static void InitializeSystemFunctionPointers();
/// <summary>
/// Creates a scheduler proxy for an IScheduler that registers with the RM.
/// </summary>
SchedulerProxy* CreateSchedulerProxy(IScheduler *pScheduler);
/// <summary>
/// Increments the reference count to RM but does not allow a 0 to 1 transition.
/// </summary>
/// <returns>
/// True if the RM was referenced; false, if the reference count was 0.
/// </returns>
bool SafeReference();
/// <summary>
/// Creates a structure of nodes and cores based on the machine topology.
/// </summary>
void DetermineTopology();
/// <summary>
/// Instructs schedulers to release borrowed cores. Then tries to allocate available cores for the new scheduler.
/// </summary>
unsigned int ReleaseBorrowedCores(SchedulerProxy * pNewProxy, unsigned int request);
/// <summary>
/// Tries to redistribute cores allocated to all schedulers, proportional to each schedulers value for 'DesiredHardwareThreads',
/// and allocates any freed cores to the new scheduler.
/// </summary>
unsigned int RedistributeCoresAmongAll(SchedulerProxy* pSchedulerProxy, unsigned int allocated, unsigned int minimum, unsigned int desired);
/// <summary>
/// Instructs all other schedulers to give up cores until they are at min. Then tries to allocate available cores
/// for the new scheduler.
/// </summary>
unsigned int ReduceOthersToMin(SchedulerProxy * pNewProxy, unsigned int request);
/// <summary>
/// Allocates cores to the new scheduler at higher use counts - this is use only to satisify MinHWThreads.
/// </summary>
unsigned int AllocateAtHigherUseCounts(SchedulerProxy * pSchedulerProxy, unsigned int request);
/// <summary>
/// Worker routine that does the actual core allocation, using the supplied use count. It tries to
/// pack allocated cores onto nodes by preferring nodes where more free cores are available.
/// </summary>
unsigned int AllocateCores(SchedulerProxy * pSchedulerProxy, unsigned int request, unsigned int useCount);
/// <summary>
/// Instructs a scheduler proxy to free up a fixed number of resources. This is only a temporary release of resources. The
/// use count on the global core is decremented and the scheduler proxy remembers the core as temporarily released. At a later
/// point, the release is either confirmed or rolled back, depending on whether the released core was used to satisfy a
/// different scheduler's allocation.
/// </summary>
/// <param name="pSchedulerProxy">
/// The scheduler proxy that needs to free up resources.
/// </param>
/// <param name="numberToFree">
/// The number of resources to free. This parameter can have a couple of special values:
/// ReleaseCoresUptoMin - scheduler should release all cores above it's minimum. Preference is giving to releasing borrowed cores.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -