📄 schedulerpolicybase.cpp
字号:
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
//
// SchedulerPolicyBase.cpp
//
// Scheduler policy implementation
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
#include "concrtinternal.h"
namespace Concurrency
{
namespace details
{
/// <summary>
/// Internal list of scheduler policy defaults.
/// </summary>
unsigned int PolicyDefaults[] =
{
::Concurrency::ThreadScheduler, // SchedulerKind
MaxExecutionResources, // MaxConcurrency
1, // MinConcurrency
1, // TargetOversubscriptionFactor
8, // LocalContextCacheSize
0, // ContextStackSize
THREAD_PRIORITY_NORMAL, // ContextPriority
EnhanceScheduleGroupLocality, // SchedulingProtocol
ProgressFeedbackEnabled, // DynamicProgressFeedback
};
/// <summary>
/// Internal map from policy keys to descriptive strings.
/// </summary>
char* PolicyElementKeyStrings[] =
{
"SchedulerKind",
"MaxConcurrency",
"MinConcurrency",
"TargetOversubscriptionFactor",
"LocalContextCacheSize",
"ContextStackSize",
"ContextPriority",
"SchedulingProtocol",
"DynamicProgressFeedback",
"MaxPolicyElementKey"
};
}
/// <summary>
/// Creates a new default scheduler policy.
/// </summary>
SchedulerPolicy::SchedulerPolicy()
{
_Initialize(0, NULL);
}
/// <summary>
/// Creates a new scheduler policy that uses a named-parameter style of initialization. Unnamed parameters take defaults described above.
/// </summary>
SchedulerPolicy::SchedulerPolicy(__in size_t _PolicyKeyCount, ...)
{
va_list args;
va_start(args, _PolicyKeyCount);
_Initialize(_PolicyKeyCount, &args);
}
/// <summary>
/// Initializes the scheduler policy.
/// </summary>
void SchedulerPolicy::_Initialize(__in size_t _PolicyKeyCount, va_list *_PArgs)
{
size_t bagSize = sizeof(unsigned int) * Concurrency::MaxPolicyElementKey;
_PolicyBag *pPolicyBag = new _PolicyBag;
_M_pPolicyBag = pPolicyBag;
try
{
memcpy(pPolicyBag->_M_values._M_pPolicyBag, PolicyDefaults, bagSize);
for (size_t i = 0; i < _PolicyKeyCount; i++)
{
PolicyElementKey key = va_arg(*_PArgs, PolicyElementKey);
unsigned int value = va_arg(*_PArgs, unsigned int);
if ( !_ValidPolicyKey(key))
throw invalid_scheduler_policy_key(_StringFromPolicyKey(key));
if ( !_ValidPolicyValue(key, value))
throw invalid_scheduler_policy_value(_StringFromPolicyKey(key));
pPolicyBag->_M_values._M_pPolicyBag[key] = value;
}
if (!_AreConcurrencyLimitsValid())
{
throw invalid_scheduler_policy_thread_specification();
}
if (!_ArePolicyCombinationsValid())
{
throw invalid_scheduler_policy_value();
}
_ResolvePolicyValues();
}
catch (...)
{
delete pPolicyBag;
throw;
}
}
/// <summary>
/// The most convenient way to define a new scheduler policy is to copy
/// an existing policy and modify it. The copy constructor is also needed
/// for all the usual reasons.
/// </summary>
SchedulerPolicy::SchedulerPolicy(__in const SchedulerPolicy &srcPolicy)
{
_M_pPolicyBag = new _PolicyBag;
_Assign(srcPolicy);
}
/// <summary>
/// The most convenient way to define a new scheduler policy is to copy
/// an existing policy and modify it. The copy constructor is also needed
/// for all the usual reasons.
/// </summary>
SchedulerPolicy& SchedulerPolicy::operator=(__in const SchedulerPolicy &rhsPolicy)
{
_Assign(rhsPolicy);
return *this;
}
/// <summary>
/// Make this policy a copy of the source policy.
/// </summary>
void SchedulerPolicy::_Assign(__in const SchedulerPolicy &rhsPolicy)
{
size_t bagSize = sizeof(unsigned int) * Concurrency::MaxPolicyElementKey;
memcpy(_M_pPolicyBag->_M_values._M_pPolicyBag, rhsPolicy._M_pPolicyBag->_M_values._M_pPolicyBag, bagSize);
}
/// <summary>
/// Destroys a scheduler policy.
/// </summary>
SchedulerPolicy::~SchedulerPolicy()
{
delete _M_pPolicyBag;
}
/// <summary>
/// Retrieve the value of the supplied policy key.
/// </summary>
/// <param name="key">
/// [in] The policy key.
/// </param>
/// <returns>
/// The policy key value for the key, if is a supported key.
/// </returns>
/// <remarks>
/// The function will throw "invalid_scheduler_policy_key" for any key that is not supported.
/// </remarks>
unsigned int SchedulerPolicy::GetPolicyValue(PolicyElementKey key) const
{
if (!_ValidPolicyKey(key))
{
throw invalid_scheduler_policy_key(_StringFromPolicyKey(key));
}
return _M_pPolicyBag->_M_values._M_pPolicyBag[key];
}
/// <summary>
/// Set the value of the supplied policy key and return the old value.
/// </summary>
/// <param name="key">
/// [in] The policy key.
/// </param>
/// <param name="value">
/// [in] The value for the policy key.
/// </param>
/// <returns>
/// The old policy key value for the key, if is a supported key.
/// </returns>
/// <remarks>
/// The function will throw "invalid_scheduler_policy_key" for any key that is not supported,
/// and "invalid_scheduler_policy_value" for a value that is not supported for a valid key.
/// </remarks>
unsigned int SchedulerPolicy::SetPolicyValue(PolicyElementKey key, unsigned int value)
{
if (!_ValidPolicyKey(key)
|| key == ::Concurrency::MinConcurrency
|| key == ::Concurrency::MaxConcurrency)
{
throw invalid_scheduler_policy_key(_StringFromPolicyKey(key));
}
if (!_ValidPolicyValue(key, value))
{
throw invalid_scheduler_policy_value(_StringFromPolicyKey(key));
}
unsigned int oldValue = GetPolicyValue(key);
_M_pPolicyBag->_M_values._M_pPolicyBag[key] = value;
_ResolvePolicyValues();
return oldValue;
}
/// <summary>
/// Set the value of the supplied policy key and return the old value.
/// </summary>
/// <param name="_MinConcurrency">
/// [in] The value for MinConcurrency.
/// </param>
/// <param name="_MaxConcurrency">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -