[+] AuHWInfo::GetPerCoreCPUTimeEx(const AuMemoryViewWrite &arrayOfCpuCoreTimeTimes)
[*] Linux: dont use hard-coded macro for kernel frequency when evaluating uptime
This commit is contained in:
parent
6b0ca15cdb
commit
63e44ab462
@ -1,5 +1,5 @@
|
||||
/***
|
||||
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
Copyright (C) 2023 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||||
|
||||
File: CoreLoad.hpp
|
||||
Date: 2023-12-30
|
||||
@ -19,5 +19,18 @@ namespace Aurora::HWInfo
|
||||
AuUInt64 uUserTime {};
|
||||
};
|
||||
|
||||
AUKN_SYM bool GetPerCoreCPUTime(AuList<CpuCoreTime> ×);
|
||||
/**
|
||||
* Internally calls GetPerCoreCPUTimeEx with a reserved times array of the maximum bounds of CpuBitId.
|
||||
* Recompile the world, if your platform targets >= 128 threads.
|
||||
*/
|
||||
AUKN_SYM bool GetPerCoreCPUTime(AuList<CpuCoreTime> ×);
|
||||
|
||||
/**
|
||||
* Emplaces CpuCoreTime into a virtually contiguous array of CpuCoreTime elements for each core in
|
||||
* order of the platforms convention. See: const CpuInfo & AuHwInfo::GetCPUInfo().
|
||||
* May return less or greater than the reported cores by GetCPUInfo(), if the underlying platform
|
||||
* decides to return wonky values.
|
||||
* Returns an empty optional on failure.
|
||||
*/
|
||||
AUKN_SYM AuOptional<AuUInt32> GetPerCoreCPUTimeEx(const AuMemoryViewWrite &arrayOfCpuCoreTimeTimes);
|
||||
}
|
@ -20,9 +20,20 @@
|
||||
|
||||
#elif defined(AURORA_IS_LINUX_DERIVED)
|
||||
|
||||
#if !defined(USER_HZ)
|
||||
#define USER_HZ 100
|
||||
#endif
|
||||
namespace Aurora::HWInfo
|
||||
{
|
||||
static AuUInt64 GetKernelFrequency()
|
||||
{
|
||||
static AuUInt64 gRet = 0;
|
||||
|
||||
if (!gRet)
|
||||
{
|
||||
gRet = sysconf(_SC_CLK_TCK);
|
||||
}
|
||||
|
||||
return gRet;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -35,7 +46,7 @@ namespace Aurora::HWInfo
|
||||
#else
|
||||
static const auto kFreq =
|
||||
#if defined(AURORA_IS_LINUX_DERIVED)
|
||||
USER_HZ
|
||||
GetKernelFrequency()
|
||||
#else
|
||||
CLOCKS_PER_SEC
|
||||
#endif
|
||||
@ -89,31 +100,42 @@ namespace Aurora::HWInfo
|
||||
int error = sysctlbyname(pName, pBuffer, pLength, NULL, 0);
|
||||
if (error != 0 && errno != ENOMEM)
|
||||
{
|
||||
SysPushErrorGeneric(errno);
|
||||
SysPushErrorHAL("CpuTimes: {}", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void PlatformGetCoreTimes(AuList<CpuCoreTime> ×)
|
||||
static AuOptional<AuUInt32> PlatformGetCoreTimes(const AuMemoryViewWrite ×)
|
||||
{
|
||||
auto uThreads = AuHwInfo::GetCPUInfo().uThreads;
|
||||
|
||||
AuList<long> cpuStates;
|
||||
cpuStates.resize((uThreads + 1) * CPUSTATES);
|
||||
if (!AuTryResize(cpuStates, (uThreads + 1) * CPUSTATES))
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return {};
|
||||
}
|
||||
|
||||
auto uArraySize = times.Count<CpuCoreTime>();
|
||||
auto pArrayBase = times.Begin<CpuCoreTime>();
|
||||
|
||||
size_t len { cpuStates.size() * sizeof(long) };
|
||||
|
||||
if (CpuSysctl("kern.cp_times", cpuStates.data(), &len) < 0)
|
||||
{
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (uThreads > uArraySize)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
times.resize(uThreads);
|
||||
for (AU_ITERATE_N(uCore, uThreads))
|
||||
{
|
||||
auto &coreTimes = times[uCore];
|
||||
auto &coreTimes = pArrayBase[uCore];
|
||||
|
||||
coreTimes.uKernelTime = cpuStates[(CPUSTATES * uCore) + CP_SYS];
|
||||
#if defined(CP_INTR)
|
||||
@ -133,20 +155,25 @@ namespace Aurora::HWInfo
|
||||
coreTimes.uUptime;
|
||||
|
||||
}
|
||||
|
||||
return AuUInt32 { uThreads };
|
||||
}
|
||||
|
||||
#elif defined(AURORA_IS_LINUX_DERIVED)
|
||||
|
||||
static bool PlatformGetCoreTimes(AuList<CpuCoreTime> ×)
|
||||
static AuOptional<AuUInt32> PlatformGetCoreTimes(const AuMemoryViewWrite ×)
|
||||
{
|
||||
bool bStatus { true };
|
||||
AuUInt uIndex {};
|
||||
AuString statFile {};
|
||||
|
||||
if (!AuFS::ReadString("/proc/stat", statFile))
|
||||
{
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto uArraySize = times.Count<CpuCoreTime>();
|
||||
auto pArrayBase = times.Begin<CpuCoreTime>();
|
||||
|
||||
AuParse::SplitNewlines(statFile, [&](const AuROString &line)
|
||||
{
|
||||
CpuCoreTime coreTimes;
|
||||
@ -237,15 +264,15 @@ namespace Aurora::HWInfo
|
||||
coreTimes.uAllPowerUpTime = coreTimes.uIdleTime +
|
||||
coreTimes.uUptime;
|
||||
|
||||
times.push_back(coreTimes);
|
||||
pArrayBase[(uIndex++) % uArraySize] = coreTimes;
|
||||
});
|
||||
|
||||
return bStatus;
|
||||
return AuUInt32 { uIndex };
|
||||
}
|
||||
|
||||
#elif defined(AURORA_IS_MODERNNT_DERIVED)
|
||||
|
||||
static bool PlatformGetCoreTimes(AuList<CpuCoreTime> ×)
|
||||
static AuOptional<AuUInt32> PlatformGetCoreTimes(const AuMemoryViewWrite ×)
|
||||
{
|
||||
#if defined(_AU_MASSIVE_CPUID)
|
||||
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION processorInfo[256];
|
||||
@ -253,10 +280,13 @@ namespace Aurora::HWInfo
|
||||
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION processorInfo[128];
|
||||
#endif
|
||||
|
||||
auto uArraySize = times.Count<CpuCoreTime>();
|
||||
auto pArrayBase = times.Begin<CpuCoreTime>();
|
||||
|
||||
if (!pNtQuerySystemInformation)
|
||||
{
|
||||
SysPushErrorFeatureMissing();
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
ULONG uOutLen {};
|
||||
@ -265,19 +295,19 @@ namespace Aurora::HWInfo
|
||||
sizeof(processorInfo),
|
||||
&uOutLen)))
|
||||
{
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto uCount = uOutLen / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
|
||||
|
||||
if (!AuTryResize(times, uCount))
|
||||
if (uCount > uArraySize)
|
||||
{
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
for (AU_ITERATE_N(uCore, uCount))
|
||||
{
|
||||
auto &coreTimes = times[uCore];
|
||||
auto &coreTimes = pArrayBase[uCore];
|
||||
|
||||
coreTimes.uIdleTime = ConvertTicks(processorInfo[uCore].IdleTime.QuadPart);
|
||||
coreTimes.uInterruptTime = 0;
|
||||
@ -293,28 +323,47 @@ namespace Aurora::HWInfo
|
||||
coreTimes.uUptime;
|
||||
}
|
||||
|
||||
return true;
|
||||
return AuUInt32 { uCount };
|
||||
}
|
||||
|
||||
|
||||
#elif defined(AURORA_IS_POSIX_DERIVED)
|
||||
|
||||
static bool PlatformGetCoreTimes(AuList<CpuCoreTime> ×)
|
||||
static AuOptional<AuUInt32> PlatformGetCoreTimes(const AuMemoryViewWrite ×)
|
||||
{
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static bool PlatformGetCoreTimes(AuList<CpuCoreTime> ×)
|
||||
static AuOptional<AuUInt32> PlatformGetCoreTimes(const AuMemoryViewWrite ×)
|
||||
{
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
AUKN_SYM AuOptional<AuUInt32> GetPerCoreCPUTimeEx(const AuMemoryViewWrite &arrayOfCpuCoreTimeTimes)
|
||||
{
|
||||
return PlatformGetCoreTimes(arrayOfCpuCoreTimeTimes);
|
||||
}
|
||||
|
||||
AUKN_SYM bool GetPerCoreCPUTime(AuList<CpuCoreTime> ×)
|
||||
{
|
||||
return PlatformGetCoreTimes(times);
|
||||
if (!AuTryResize(times, 256))
|
||||
{
|
||||
SysPushErrorMemory();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto ret = GetPerCoreCPUTimeEx(times))
|
||||
{
|
||||
times.resize(ret.Value());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user