You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
578 lines
21 KiB
C++
578 lines
21 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright and license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
// Original file Copyright Crytek GMBH or its affiliates, used under license.
|
|
|
|
#include "CrySystem_precompiled.h"
|
|
#include "ThreadConfigManager.h"
|
|
#include "IConsole.h"
|
|
#include "System.h"
|
|
#include <StringUtils.h>
|
|
#include <CryCustomTypes.h>
|
|
#include "CryUtils.h"
|
|
namespace
|
|
{
|
|
const char* sCurThreadConfigFilename = "";
|
|
const uint32 sPlausibleStackSizeLimitKB = (1024 * 100); // 100mb
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CThreadConfigManager::CThreadConfigManager()
|
|
{
|
|
m_defaultConfig.szThreadName = "CryThread_Unnamed";
|
|
m_defaultConfig.stackSizeBytes = 0;
|
|
m_defaultConfig.affinityFlag = -1;
|
|
m_defaultConfig.priority = THREAD_PRIORITY_NORMAL;
|
|
m_defaultConfig.bDisablePriorityBoost = false;
|
|
m_defaultConfig.paramActivityFlag = (SThreadConfig::TThreadParamFlag)~0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
const SThreadConfig* CThreadConfigManager::GetThreadConfig(const char* szThreadName, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, szThreadName);
|
|
|
|
// Format thread name
|
|
char strThreadName[THREAD_NAME_LENGTH_MAX];
|
|
const int cNumCharsNeeded = azvsnprintf(strThreadName, CRY_ARRAY_COUNT(strThreadName), szThreadName, args);
|
|
if (cNumCharsNeeded > THREAD_NAME_LENGTH_MAX - 1)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: ThreadName \"%s\" has been truncated. Max characters allowed: %i. ", strThreadName, THREAD_NAME_LENGTH_MAX - 1);
|
|
}
|
|
|
|
// Get Thread Config
|
|
const SThreadConfig* retThreasdConfig = GetThreadConfigImpl(strThreadName);
|
|
|
|
va_end(args);
|
|
return retThreasdConfig;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
const SThreadConfig* CThreadConfigManager::GetThreadConfigImpl(const char* szThreadName)
|
|
{
|
|
// Get thread config for platform
|
|
ThreadConfigMapConstIter threatRet = m_threadConfig.find(CryFixedStringT<THREAD_NAME_LENGTH_MAX>(szThreadName));
|
|
if (threatRet == m_threadConfig.end())
|
|
{
|
|
// Search in wildcard setups
|
|
ThreadConfigMapConstIter wildCardIter = m_wildcardThreadConfig.begin();
|
|
ThreadConfigMapConstIter wildCardIterEnd = m_wildcardThreadConfig.end();
|
|
for (; wildCardIter != wildCardIterEnd; ++wildCardIter)
|
|
{
|
|
if (CryStringUtils::MatchWildcard(szThreadName, wildCardIter->second.szThreadName))
|
|
{
|
|
// Store new thread config
|
|
SThreadConfig threadConfig = wildCardIter->second;
|
|
std::pair<ThreadConfigMapIter, bool> res;
|
|
res = m_threadConfig.insert(ThreadConfigMapPair(CryFixedStringT<THREAD_NAME_LENGTH_MAX>(szThreadName), threadConfig));
|
|
|
|
// Store name (ref to key)
|
|
SThreadConfig& rMapThreadConfig = res.first->second;
|
|
rMapThreadConfig.szThreadName = res.first->first.c_str();
|
|
|
|
// Return new thread config
|
|
return &res.first->second;
|
|
}
|
|
}
|
|
|
|
// Failure case, no match found
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadInfo>: Unable to find config for thread:%s", szThreadName);
|
|
return &m_defaultConfig;
|
|
}
|
|
|
|
// Return thread config
|
|
return &threatRet->second;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
const SThreadConfig* CThreadConfigManager::GetDefaultThreadConfig() const
|
|
{
|
|
return &m_defaultConfig;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CThreadConfigManager::LoadConfig(const char* pcPath)
|
|
{
|
|
// Adjust filename for OnDisk or in .pak file loading
|
|
char szFullPathBuf[AZ::IO::IArchive::MaxPath];
|
|
gEnv->pCryPak->AdjustFileName(pcPath, szFullPathBuf, AZ_ARRAY_SIZE(szFullPathBuf), 0);
|
|
|
|
// Open file
|
|
XmlNodeRef xmlRoot = GetISystem()->LoadXmlFromFile(szFullPathBuf);
|
|
if (!xmlRoot)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: File \"%s\" not found!", pcPath);
|
|
return false;
|
|
}
|
|
|
|
// Load config for active platform
|
|
sCurThreadConfigFilename = pcPath;
|
|
const char* strPlatformId = IdentifyPlatform();
|
|
CryFixedStringT<32> tmpPlatformStr;
|
|
bool retValue = false;
|
|
|
|
// Try load common platform settings
|
|
tmpPlatformStr.Format("%s_Common", strPlatformId);
|
|
LoadPlatformConfig(xmlRoot, tmpPlatformStr.c_str());
|
|
|
|
#if defined(CRY_PLATFORM_DESKTOP)
|
|
// Handle PC specifically as we do not know the core setup of the executing machine.
|
|
// Try and find the next power of 2 core setup. Otherwise fallback to a lower power of 2 core setup spec
|
|
|
|
// Try and load next pow of 2 setup for active pc core configuration
|
|
const unsigned int numCPUs = ((CSystem*)GetISystem())->GetCPUFeatures()->GetLogicalCPUCount();
|
|
uint32 i = numCPUs;
|
|
for (; i > 0; --i)
|
|
{
|
|
tmpPlatformStr.Format("%s_%i", strPlatformId, i);
|
|
retValue = LoadPlatformConfig(xmlRoot, tmpPlatformStr.c_str());
|
|
if (retValue)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (retValue && i != numCPUs)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: (%s: %u core) Unable to find platform config \"%s\". Next valid config found was %s_%u.",
|
|
strPlatformId, numCPUs, tmpPlatformStr.c_str(), strPlatformId, i);
|
|
}
|
|
|
|
#else
|
|
tmpPlatformStr.Format("%s", strPlatformId);
|
|
retValue = LoadPlatformConfig(xmlRoot, strPlatformId);
|
|
#endif
|
|
|
|
// Print out info
|
|
if (retValue)
|
|
{
|
|
CryLogAlways("<ThreadConfigInfo>: Thread profile loaded: \"%s\" (%s) ", tmpPlatformStr.c_str(), pcPath);
|
|
}
|
|
else
|
|
{
|
|
// Could not find any matching platform
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: Active platform identifier string \"%s\" not found in config \"%s\".", strPlatformId, sCurThreadConfigFilename);
|
|
}
|
|
|
|
sCurThreadConfigFilename = "";
|
|
return retValue;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CThreadConfigManager::ConfigLoaded() const
|
|
{
|
|
return !m_threadConfig.empty();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CThreadConfigManager::LoadPlatformConfig(const XmlNodeRef& rXmlRoot, const char* sPlatformId)
|
|
{
|
|
// Validate node
|
|
if (!rXmlRoot->isTag("ThreadConfig"))
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: Unable to find root xml node \"ThreadConfig\"");
|
|
return false;
|
|
}
|
|
|
|
// Find active platform
|
|
const uint32 numPlatforms = rXmlRoot->getChildCount();
|
|
for (uint32 i = 0; i < numPlatforms; ++i)
|
|
{
|
|
const XmlNodeRef xmlPlatformNode = rXmlRoot->getChild(i);
|
|
|
|
// Is platform node
|
|
if (!xmlPlatformNode->isTag("Platform"))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Is has Name attribute
|
|
if (!xmlPlatformNode->haveAttr("Name"))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Is platform of interest
|
|
const char* platformName = xmlPlatformNode->getAttr("Name");
|
|
if (_stricmp(sPlatformId, platformName) == 0)
|
|
{
|
|
// Load platform
|
|
LoadThreadDefaultConfig(xmlPlatformNode);
|
|
LoadPlatformThreadConfigs(xmlPlatformNode);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CThreadConfigManager::LoadPlatformThreadConfigs(const XmlNodeRef& rXmlPlatformRef)
|
|
{
|
|
// Get thread configurations for active platform
|
|
const uint32 numThreads = rXmlPlatformRef->getChildCount();
|
|
for (uint32 j = 0; j < numThreads; ++j)
|
|
{
|
|
const XmlNodeRef xmlThreadNode = rXmlPlatformRef->getChild(j);
|
|
|
|
if (!xmlThreadNode->isTag("Thread"))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Ensure thread config has name
|
|
if (!xmlThreadNode->haveAttr("Name"))
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Thread node without \"name\" attribute encountered.");
|
|
continue;
|
|
}
|
|
|
|
// Load thread config
|
|
SThreadConfig loadedThreadConfig = SThreadConfig(m_defaultConfig);
|
|
LoadThreadConfig(xmlThreadNode, loadedThreadConfig);
|
|
|
|
// Get thread name and check if it contains wildcard characters
|
|
const char* szThreadName = xmlThreadNode->getAttr("Name");
|
|
bool bWildCard = strchr(szThreadName, '*') ? true : false;
|
|
ThreadConfigMap& threadConfig = bWildCard ? m_wildcardThreadConfig : m_threadConfig;
|
|
|
|
// Check for duplicate and override it with new config if found
|
|
if (threadConfig.find(szThreadName) != threadConfig.end())
|
|
{
|
|
CryLogAlways("<ThreadConfigInfo>: [XML Parsing] Thread with name \"%s\" already loaded. Overriding with new configuration", szThreadName);
|
|
threadConfig[szThreadName] = loadedThreadConfig;
|
|
continue;
|
|
}
|
|
|
|
// Store new thread config
|
|
std::pair<ThreadConfigMapIter, bool> res;
|
|
res = threadConfig.insert(ThreadConfigMapPair(CryFixedStringT<THREAD_NAME_LENGTH_MAX>(szThreadName), loadedThreadConfig));
|
|
|
|
// Store name (ref to key)
|
|
SThreadConfig& rMapThreadConfig = res.first->second;
|
|
rMapThreadConfig.szThreadName = res.first->first.c_str();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CThreadConfigManager::LoadThreadDefaultConfig(const XmlNodeRef& rXmlPlatformRef)
|
|
{
|
|
// Find default thread config node
|
|
const uint32 numNodes = rXmlPlatformRef->getChildCount();
|
|
for (uint32 j = 0; j < numNodes; ++j)
|
|
{
|
|
const XmlNodeRef xmlNode = rXmlPlatformRef->getChild(j);
|
|
|
|
// Load default config
|
|
if (xmlNode->isTag("ThreadDefault"))
|
|
{
|
|
LoadThreadConfig(xmlNode, m_defaultConfig);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CThreadConfigManager::LoadAffinity(const XmlNodeRef& rXmlThreadRef, uint32& rAffinity, SThreadConfig::TThreadParamFlag& rParamActivityFlag)
|
|
{
|
|
const char* szValidCharacters = "-,0123456789";
|
|
uint32 affinity = 0;
|
|
|
|
// Validate node
|
|
if (!rXmlThreadRef->haveAttr("Affinity"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Validate token
|
|
CryFixedStringT<32> affinityRawStr(rXmlThreadRef->getAttr("Affinity"));
|
|
if (affinityRawStr.empty())
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Empty attribute \"Affinity\" encountered");
|
|
return;
|
|
}
|
|
|
|
if (affinityRawStr.compareNoCase("ignore") == 0)
|
|
{
|
|
// Param is inactive, clear bit
|
|
rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_Affinity;
|
|
return;
|
|
}
|
|
|
|
CryFixedStringT<32>::size_type nPos = affinityRawStr.find_first_not_of(" -,0123456789");
|
|
if (nPos != CryFixedStringT<32>::npos)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING,
|
|
"<ThreadConfigInfo>: [XML Parsing] Invalid character \"%c\" encountered in \"Affinity\" attribute. Valid characters:\"%s\" Offending token:\"%s\"", affinityRawStr.at(nPos),
|
|
szValidCharacters, affinityRawStr.c_str());
|
|
return;
|
|
}
|
|
|
|
// Tokenize comma separated string
|
|
int pos = 0;
|
|
CryFixedStringT<32> affnityTokStr = affinityRawStr.Tokenize(",", pos);
|
|
while (!affnityTokStr.empty())
|
|
{
|
|
affnityTokStr.Trim();
|
|
|
|
long affinityId = strtol(affnityTokStr.c_str(), NULL, 10);
|
|
if (affinityId == LONG_MAX || affinityId == LONG_MIN)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Unknown value \"%s\" encountered for attribute \"Affinity\"", affnityTokStr.c_str());
|
|
return;
|
|
}
|
|
|
|
// Allow scheduler to pick thread
|
|
if (affinityId == -1)
|
|
{
|
|
affinity = ~0;
|
|
break;
|
|
}
|
|
|
|
// Set affinity bit
|
|
affinity |= BIT(affinityId);
|
|
|
|
// Move to next token
|
|
affnityTokStr = affinityRawStr.Tokenize(",", pos);
|
|
}
|
|
|
|
// Set affinity reference
|
|
rAffinity = affinity;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CThreadConfigManager::LoadPriority(const XmlNodeRef& rXmlThreadRef, int32& rPriority, SThreadConfig::TThreadParamFlag& rParamActivityFlag)
|
|
{
|
|
const char* szValidCharacters = "-,0123456789";
|
|
|
|
// Validate node
|
|
if (!rXmlThreadRef->haveAttr("Priority"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Validate token
|
|
CryFixedStringT<32> threadPrioStr(rXmlThreadRef->getAttr("Priority"));
|
|
threadPrioStr.Trim();
|
|
if (threadPrioStr.empty())
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Empty attribute \"Priority\" encountered");
|
|
return;
|
|
}
|
|
|
|
if (threadPrioStr.compareNoCase("ignore") == 0)
|
|
{
|
|
// Param is inactive, clear bit
|
|
rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_Priority;
|
|
return;
|
|
}
|
|
|
|
// Test for character string (no numbers allowed)
|
|
if (threadPrioStr.find_first_of(szValidCharacters) == CryFixedStringT<32>::npos)
|
|
{
|
|
threadPrioStr.MakeLower();
|
|
|
|
// Set priority
|
|
if (threadPrioStr.compare("below_normal") == 0)
|
|
{
|
|
rPriority = THREAD_PRIORITY_BELOW_NORMAL;
|
|
}
|
|
else if (threadPrioStr.compare("normal") == 0)
|
|
{
|
|
rPriority = THREAD_PRIORITY_NORMAL;
|
|
}
|
|
else if (threadPrioStr.compare("above_normal") == 0)
|
|
{
|
|
rPriority = THREAD_PRIORITY_ABOVE_NORMAL;
|
|
}
|
|
else if (threadPrioStr.compare("idle") == 0)
|
|
{
|
|
rPriority = THREAD_PRIORITY_IDLE;
|
|
}
|
|
else if (threadPrioStr.compare("lowest") == 0)
|
|
{
|
|
rPriority = THREAD_PRIORITY_LOWEST;
|
|
}
|
|
else if (threadPrioStr.compare("highest") == 0)
|
|
{
|
|
rPriority = THREAD_PRIORITY_HIGHEST;
|
|
}
|
|
else if (threadPrioStr.compare("time_critical") == 0)
|
|
{
|
|
rPriority = THREAD_PRIORITY_TIME_CRITICAL;
|
|
}
|
|
else
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Platform unsupported value \"%s\" encountered for attribute \"Priority\"", threadPrioStr.c_str());
|
|
return;
|
|
}
|
|
}
|
|
// Test for number string (no alphabetical characters allowed)
|
|
else if (threadPrioStr.find_first_not_of(szValidCharacters) == CryFixedStringT<32>::npos)
|
|
{
|
|
long numValue = strtol(threadPrioStr.c_str(), NULL, 10);
|
|
if (numValue == LONG_MAX || numValue == LONG_MIN)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Unsupported number type \"%s\" for for attribute \"Priority\"", threadPrioStr.c_str());
|
|
return;
|
|
}
|
|
|
|
// Set priority
|
|
rPriority = numValue;
|
|
}
|
|
else
|
|
{
|
|
// String contains characters and numbers
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Unsupported type \"%s\" encountered for attribute \"Priority\". Token containers numbers and characters", threadPrioStr.c_str());
|
|
return;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CThreadConfigManager::LoadDisablePriorityBoost(const XmlNodeRef& rXmlThreadRef, bool& rPriorityBoost, SThreadConfig::TThreadParamFlag& rParamActivityFlag)
|
|
{
|
|
// Validate node
|
|
if (!rXmlThreadRef->haveAttr("DisablePriorityBoost"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Extract bool info
|
|
CryFixedStringT<16> sAttribToken(rXmlThreadRef->getAttr("DisablePriorityBoost"));
|
|
sAttribToken.Trim();
|
|
sAttribToken.MakeLower();
|
|
|
|
if (sAttribToken.compare("ignore") == 0)
|
|
{
|
|
// Param is inactive, clear bit
|
|
rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_PriorityBoost;
|
|
return;
|
|
}
|
|
else if (sAttribToken.compare("true") == 0 || sAttribToken.compare("1") == 0)
|
|
{
|
|
rPriorityBoost = true;
|
|
}
|
|
else if (sAttribToken.compare("false") == 0 || sAttribToken.compare("0") == 0)
|
|
{
|
|
rPriorityBoost = false;
|
|
}
|
|
else
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Unsupported bool type \"%s\" encountered for attribute \"DisablePriorityBoost\"",
|
|
rXmlThreadRef->getAttr("DisablePriorityBoost"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CThreadConfigManager::LoadStackSize(const XmlNodeRef& rXmlThreadRef, uint32& rStackSize, SThreadConfig::TThreadParamFlag& rParamActivityFlag)
|
|
{
|
|
const char* sValidCharacters = "0123456789";
|
|
|
|
if (rXmlThreadRef->haveAttr("StackSizeKB"))
|
|
{
|
|
// Read stack size
|
|
CryFixedStringT<32> stackSize(rXmlThreadRef->getAttr("StackSizeKB"));
|
|
|
|
// Validate stack size
|
|
if (stackSize.empty())
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Empty attribute \"StackSize\" encountered");
|
|
return;
|
|
}
|
|
else if (stackSize.compareNoCase("ignore") == 0)
|
|
{
|
|
// Param is inactive, clear bit
|
|
rParamActivityFlag &= ~SThreadConfig::eThreadParamFlag_StackSize;
|
|
return;
|
|
}
|
|
else if (stackSize.find_first_not_of(sValidCharacters) == CryFixedStringT<32>::npos)
|
|
{
|
|
// Convert string to long
|
|
long stackSizeVal = strtol(stackSize.c_str(), NULL, 10);
|
|
if (stackSizeVal == LONG_MAX || stackSizeVal == LONG_MIN)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] Invalid number for \"StackSize\" encountered. \"%s\"", stackSize.c_str());
|
|
return;
|
|
}
|
|
else if (stackSizeVal <= 0 || stackSizeVal > sPlausibleStackSizeLimitKB)
|
|
{
|
|
CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "<ThreadConfigInfo>: [XML Parsing] \"StackSize\" value not plausible \"%" PRId64 "KB\"", (int64)stackSizeVal);
|
|
return;
|
|
}
|
|
|
|
// Set stack size
|
|
rStackSize = stackSizeVal * 1024; // Convert to bytes
|
|
}
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CThreadConfigManager::LoadThreadConfig(const XmlNodeRef& rXmlThreadRef, SThreadConfig& rThreadConfig)
|
|
{
|
|
LoadAffinity(rXmlThreadRef, rThreadConfig.affinityFlag, rThreadConfig.paramActivityFlag);
|
|
LoadPriority(rXmlThreadRef, rThreadConfig.priority, rThreadConfig.paramActivityFlag);
|
|
LoadDisablePriorityBoost(rXmlThreadRef, rThreadConfig.bDisablePriorityBoost, rThreadConfig.paramActivityFlag);
|
|
LoadStackSize(rXmlThreadRef, rThreadConfig.stackSizeBytes, rThreadConfig.paramActivityFlag);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
const char* CThreadConfigManager::IdentifyPlatform()
|
|
{
|
|
#if defined(AZ_RESTRICTED_PLATFORM)
|
|
#include AZ_RESTRICTED_FILE(ThreadConfigManager_cpp)
|
|
#endif
|
|
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
|
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
|
#elif defined(ANDROID)
|
|
return "android";
|
|
#elif defined(LINUX)
|
|
return "linux";
|
|
#elif defined(APPLE)
|
|
return "mac";
|
|
#elif defined(WIN32) || defined(WIN64)
|
|
return "pc";
|
|
#else
|
|
#error "Undefined platform"
|
|
#endif
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CThreadConfigManager::DumpThreadConfigurationsToLog()
|
|
{
|
|
#if !defined(RELEASE)
|
|
|
|
// Print header
|
|
CryLogAlways("== Thread Startup Config List (\"%s\") ==", IdentifyPlatform());
|
|
|
|
// Print loaded default config
|
|
CryLogAlways(" (Default) 1. \"%s\" (StackSize:%uKB | Affinity:%u | Priority:%i | PriorityBoost:\"%s\")", m_defaultConfig.szThreadName, m_defaultConfig.stackSizeBytes / 1024,
|
|
m_defaultConfig.affinityFlag, m_defaultConfig.priority, m_defaultConfig.bDisablePriorityBoost ? "disabled" : "enabled");
|
|
|
|
// Print loaded thread configs
|
|
int listItemCounter = 1;
|
|
ThreadConfigMapConstIter iter = m_threadConfig.begin();
|
|
ThreadConfigMapConstIter iterEnd = m_threadConfig.end();
|
|
for (; iter != iterEnd; ++iter)
|
|
{
|
|
const SThreadConfig& threadConfig = iter->second;
|
|
CryLogAlways("%3d.\"%s\" %s (StackSize:%uKB %s | Affinity:%u %s | Priority:%i %s | PriorityBoost:\"%s\" %s)", ++listItemCounter,
|
|
threadConfig.szThreadName, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_ThreadName) ? "" : "(ignored)",
|
|
threadConfig.stackSizeBytes / 1024u, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_StackSize) ? "" : "(ignored)",
|
|
threadConfig.affinityFlag, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_Affinity) ? "" : "(ignored)",
|
|
threadConfig.priority, (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_Priority) ? "" : "(ignored)",
|
|
!threadConfig.bDisablePriorityBoost ? "enabled" : "disabled", (threadConfig.paramActivityFlag & SThreadConfig::eThreadParamFlag_PriorityBoost) ? "" : "(ignored)");
|
|
}
|
|
#endif
|
|
}
|