📄 schedulerpolicybase.cpp
字号:
/// [in] The value for MaxConcurrency.
/// </param>
/// <remarks>
/// The function will throw "invalid_scheduler_policy_value" if:
/// _MaxConcurrency != MaxExecutionResources && _MinConcurrency > _MaxConcurrency
///</remarks>
void SchedulerPolicy::SetConcurrencyLimits(__in unsigned int _MinConcurrency, __in unsigned int _MaxConcurrency)
{
if (!_ValidPolicyValue(::Concurrency::MaxConcurrency, _MaxConcurrency))
throw invalid_scheduler_policy_value(_StringFromPolicyKey(::Concurrency::MaxConcurrency));
if (!_ValidPolicyValue(::Concurrency::MinConcurrency, _MinConcurrency))
throw invalid_scheduler_policy_value(_StringFromPolicyKey(::Concurrency::MinConcurrency));
if (!_AreConcurrencyLimitsValid(_MinConcurrency, _MaxConcurrency))
throw invalid_scheduler_policy_thread_specification();
if (!_ArePolicyCombinationsValid())
throw invalid_scheduler_policy_value();
_M_pPolicyBag->_M_values._M_pPolicyBag[::Concurrency::MaxConcurrency] = _MaxConcurrency;
_M_pPolicyBag->_M_values._M_pPolicyBag[::Concurrency::MinConcurrency] = _MinConcurrency;
_ResolvePolicyValues();
}
/// <summary>
/// Resolves some of the policy keys that are set to defaults, based on the characteristics of the underlying system.
/// </summary>
void SchedulerPolicy::_ResolvePolicyValues()
{
// Resolve the SchedulerKind policy key value.
if (_M_pPolicyBag->_M_values._M_pPolicyBag[::Concurrency::SchedulerKind] == ::Concurrency::UmsThreadDefault)
{
if (::Concurrency::GetOSVersion() == ::Concurrency::IResourceManager::UmsThreadAwareOS)
{
_M_pPolicyBag->_M_values._M_pPolicyBag[::Concurrency::SchedulerKind] = ::Concurrency::UmsThreadDefault;
}
else
{
_M_pPolicyBag->_M_values._M_pPolicyBag[::Concurrency::SchedulerKind] = ::Concurrency::ThreadScheduler;
}
}
// Resolve MinConcurrency and MaxConcurrency, if either of them are set to the special value MaxExecutionResources.
unsigned int coreCount = ::Concurrency::GetProcessorCount();
ASSERT((coreCount > 0) && (coreCount <= INT_MAX));
if (_M_pPolicyBag->_M_values._M_pPolicyBag[MinConcurrency] == MaxExecutionResources)
{
if (_M_pPolicyBag->_M_values._M_pPolicyBag[MaxConcurrency] == MaxExecutionResources)
{
// [1] Both the keys are set to MaxExecutionResources.
_M_pPolicyBag->_M_values._M_pPolicyBag[MinConcurrency] = _M_pPolicyBag->_M_values._M_pPolicyBag[MaxConcurrency] = coreCount;
}
else
{
// [2] MinConcurrency is set to MaxExecutionResources.
_M_pPolicyBag->_M_values._M_pPolicyBag[MinConcurrency] = (_M_pPolicyBag->_M_values._M_pPolicyBag[MaxConcurrency] < coreCount) ?
_M_pPolicyBag->_M_values._M_pPolicyBag[MaxConcurrency] : coreCount;
}
}
else if (_M_pPolicyBag->_M_values._M_pPolicyBag[MaxConcurrency] == MaxExecutionResources)
{
// [3] MaxConcurrency is set to MaxExecutionResources.
_M_pPolicyBag->_M_values._M_pPolicyBag[MaxConcurrency] = (_M_pPolicyBag->_M_values._M_pPolicyBag[MinConcurrency] > coreCount) ?
_M_pPolicyBag->_M_values._M_pPolicyBag[MinConcurrency] : coreCount;
}
ASSERT(_M_pPolicyBag->_M_values._M_pPolicyBag[MinConcurrency] >= 0 && _M_pPolicyBag->_M_values._M_pPolicyBag[MaxConcurrency] >= _M_pPolicyBag->_M_values._M_pPolicyBag[MinConcurrency]);
}
char* SchedulerPolicy::_StringFromPolicyKey(unsigned int index)
{
if (index > ::Concurrency::MaxPolicyElementKey)
index = ::Concurrency::MaxPolicyElementKey;
return PolicyElementKeyStrings[index];
}
bool SchedulerPolicy::_ValidPolicyKey(PolicyElementKey key)
{
return (key >= SchedulerKind && key < MaxPolicyElementKey);
}
bool SchedulerPolicy::_ValidPolicyValue(PolicyElementKey key, unsigned int value)
{
bool valid = true;
switch (key)
{
case ::Concurrency::SchedulerKind:
if ( !(value == ::Concurrency::ThreadScheduler
|| value == ::Concurrency::UmsThreadDefault))
{
valid = false;
}
break;
case ::Concurrency::ContextPriority:
{
int priority = (int)value;
//
// The win32 api accepts values [-7, 7), 15 and -15 for threads other than the current thread.
// In addition, we define a special value INHERIT_THREAD_PRIORITY, whereby the internal contexts
// inherit the priority of the thread creating the scheduler
//
if ( !(priority >= -7 && priority < 7
|| priority == 15
|| priority == -15
|| priority == INHERIT_THREAD_PRIORITY))
{
valid = false;
}
}
break;
case ::Concurrency::SchedulingProtocol:
if ( !(value == ::Concurrency::EnhanceScheduleGroupLocality
|| value == ::Concurrency::EnhanceForwardProgress))
{
valid = false;
}
break;
case ::Concurrency::MaxConcurrency:
if ( !((value > 0 && value <= INT_MAX) || value == MaxExecutionResources))
{
valid = false;
}
break;
case ::Concurrency::MinConcurrency:
if ( !((value >= 0 && value <= INT_MAX) || value == MaxExecutionResources))
{
valid = false;
}
break;
case ::Concurrency::LocalContextCacheSize:
case ::Concurrency::ContextStackSize:
if ( !(value <= INT_MAX))
{
valid = false;
}
break;
case ::Concurrency::TargetOversubscriptionFactor:
if ( !(value > 0 && value <= INT_MAX))
{
valid = false;
}
break;
case ::Concurrency::DynamicProgressFeedback:
if ( !(value == ::Concurrency::ProgressFeedbackEnabled || value == ::Concurrency::ProgressFeedbackDisabled))
{
valid = false;
}
break;
case ::Concurrency::MaxPolicyElementKey:
default:
ASSERT(false);
valid = false;
break;
}
return valid;
}
void SchedulerPolicy::_ValidateConcRTPolicy() const
{
unsigned int minConcurrency = GetPolicyValue(::Concurrency::MinConcurrency);
if (minConcurrency == 0)
{
throw invalid_scheduler_policy_value(_StringFromPolicyKey(::Concurrency::MinConcurrency));
}
::Concurrency::DynamicProgressFeedbackType dynamicProgress =
(::Concurrency::DynamicProgressFeedbackType) GetPolicyValue(::Concurrency::DynamicProgressFeedback);
if (dynamicProgress == ProgressFeedbackDisabled)
{
throw invalid_scheduler_policy_value(_StringFromPolicyKey(::Concurrency::DynamicProgressFeedback));
}
}
/// <summary>
/// Test a policy's concurrency limits.
/// </summary>
bool SchedulerPolicy::_AreConcurrencyLimitsValid(unsigned int _MinConcurrency, unsigned int _MaxConcurrency)
{
// For concurrency limits that are != MaxExecutionResource, plug into the equation: _MinConcurrency <= _MaxConcurrency,
// and return false, if it does not hold.
// Validate Max
if ((_MaxConcurrency != MaxExecutionResources)
&& (_MinConcurrency != MaxExecutionResources) && (_MaxConcurrency < _MinConcurrency))
{
return false;
}
return true;
}
/// <summary>
/// Test a policy's concurrency limits.
/// </summary>
bool SchedulerPolicy::_AreConcurrencyLimitsValid() const
{
return _AreConcurrencyLimitsValid(GetPolicyValue(::Concurrency::MinConcurrency),
GetPolicyValue(::Concurrency::MaxConcurrency));
}
/// <summary>
/// Test a policy's concurrency limits.
/// </summary>
bool SchedulerPolicy::_ArePolicyCombinationsValid() const
{
unsigned int minConcurrency = GetPolicyValue(::Concurrency::MinConcurrency);
::Concurrency::SchedulerType schedulerKind = (::Concurrency::SchedulerType) GetPolicyValue(::Concurrency::SchedulerKind);
return (schedulerKind != ::Concurrency::UmsThreadDefault || minConcurrency != 0);
}
} // namespace Concurrency
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -