/*** Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: SMTYield.cpp Date: 2023-3-12 Author: Reece ***/ #include #include "SMTYield.hpp" namespace Aurora::Threading { AUKN_SYM void SetSpinCountTimeout(AuUInt8 uTimeout) { gRuntimeConfig.threadingConfig.uSpinLoopPowerA = uTimeout; } AUKN_SYM AuUInt8 GetSpinCountTimeout() { return gRuntimeConfig.threadingConfig.uSpinLoopPowerA; } AUKN_SYM void SetThreadLocalAdditionalSpinCountTimeout(AuUInt8 uTimeout) { gHasThreadLocalTimeout = 1; tlsSpinCountLocal = uTimeout; } AUKN_SYM AuUInt32 GetTotalSpinCountTimeout() { AuUInt32 uCount {}; if (!gRuntimeConfig.threadingConfig.bPlatformIsSMPProcessorOptimized) { return 16; } uCount = AuUInt32(gRuntimeConfig.threadingConfig.uSpinLoopPowerA); if (gHasThreadLocalTimeout) { uCount += 1u << AuUInt32(tlsSpinCountLocal); } 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(); } }