139 lines
4.0 KiB
C++
139 lines
4.0 KiB
C++
/***
|
|
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: SMTYield.cpp
|
|
Date: 2023-3-12
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "SMTYield.hpp"
|
|
|
|
namespace Aurora::Threading
|
|
{
|
|
AUKN_SYM void SetSpinCountTimeout(AuUInt32 uTimeout)
|
|
{
|
|
gRuntimeConfig.threadingConfig.uSpinLoopPowerA = uTimeout;
|
|
}
|
|
|
|
AUKN_SYM AuUInt32 GetSpinCountTimeout()
|
|
{
|
|
return gRuntimeConfig.threadingConfig.uSpinLoopPowerA;
|
|
}
|
|
|
|
AUKN_SYM void SetThreadLocalAdditionalSpinCountTimeout(AuUInt32 uTimeout)
|
|
{
|
|
gHasThreadLocalTimeout = 1;
|
|
tlsSpinCountLocal = uTimeout;
|
|
}
|
|
|
|
AUKN_SYM AuUInt32 GetTotalSpinCountTime()
|
|
{
|
|
AuUInt32 uCount {};
|
|
|
|
if (!gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
uCount = AuUInt32(gRuntimeConfig.threadingConfig.uSpinLoopPowerA);
|
|
if (gHasThreadLocalTimeout)
|
|
{
|
|
uCount += tlsSpinCountLocal;
|
|
}
|
|
|
|
//#if defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86)
|
|
// uCount *= 4;
|
|
//#endif
|
|
// well, i guess not because intel recommends going by rdtsc ticks, and not to assume eventual uop sleep of an unspecified period
|
|
return uCount;
|
|
}
|
|
|
|
AUKN_SYM const ThreadingConfig *GetThreadingConfig()
|
|
{
|
|
return &gRuntimeConfig.threadingConfig;
|
|
}
|
|
|
|
AUKN_SYM void SetThreadingConfig(const ThreadingConfig *pUpdateConfig)
|
|
{
|
|
if (!pUpdateConfig)
|
|
{
|
|
return;
|
|
}
|
|
|
|
gRuntimeConfig.threadingConfig = decltype(gRuntimeConfig.threadingConfig)(ThreadingConfig(*pUpdateConfig));
|
|
|
|
Primitives::InitAdaptiveThreshold();
|
|
}
|
|
|
|
AUKN_SYM bool IsWaitOnRecommended();
|
|
}
|
|
|
|
namespace Aurora::Threading::Primitives
|
|
{
|
|
void InitAdaptiveThreshold()
|
|
{
|
|
auto uCores = AuHwInfo::GetCPUInfo().uThreads;
|
|
|
|
gUseFutexRWLock = gRuntimeConfig.threadingConfig.bPreferFutexRWLock &&
|
|
IsWaitOnRecommended();
|
|
|
|
if (uCores == 1)
|
|
{
|
|
gSpinAdaptiveThreshold = 0;
|
|
gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized = false;
|
|
return;
|
|
}
|
|
|
|
if (!gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin)
|
|
{
|
|
gSpinAdaptiveThreshold = 0;
|
|
return;
|
|
}
|
|
|
|
if (uCores >= 16)
|
|
{
|
|
gSpinAdaptiveThreshold = uCores / gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt16;
|
|
}
|
|
else if (uCores >= 8 && gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt8)
|
|
{
|
|
gSpinAdaptiveThreshold = uCores / gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt8;
|
|
}
|
|
else if (uCores >= 4 && gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt4)
|
|
{
|
|
gSpinAdaptiveThreshold = uCores / gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt4;
|
|
}
|
|
else if (uCores >= 0 && gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt0)
|
|
{
|
|
gSpinAdaptiveThreshold = uCores / gRuntimeConfig.threadingConfig.uAdaptiveSpinCUCnt0;
|
|
}
|
|
else
|
|
{
|
|
gSpinAdaptiveThreshold = 0;
|
|
}
|
|
}
|
|
|
|
void InitAdaptiveThresholdFirstTime()
|
|
{
|
|
if (!gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin &&
|
|
gRuntimeConfig.threadingConfig.bPreferEnableAdaptiveSpin)
|
|
{
|
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
|
if (gRuntimeConfig.threadingConfig.bPreferLinuxAdaptiveSpin)
|
|
{
|
|
gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin = true;
|
|
}
|
|
#else
|
|
if (AuSwInfo::IsWindows10OrGreater())
|
|
{
|
|
gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin = gRuntimeConfig.threadingConfig.bPreferNewWin32AdaptiveSpin;
|
|
}
|
|
else
|
|
{
|
|
gRuntimeConfig.threadingConfig.bForceEnableAdaptiveSpin = gRuntimeConfig.threadingConfig.bPreferOldWin32AdaptiveSpin;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
InitAdaptiveThreshold();
|
|
}
|
|
} |