334 lines
8.4 KiB
C++
334 lines
8.4 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: AuRamInfo.cpp
|
|
Date: 2021-6-12
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "AuHWInfo.hpp"
|
|
#include "AuRamInfo.hpp"
|
|
|
|
#if defined(AURORA_IS_BSD_DERIVED)
|
|
#include <sys/sysctl.h>
|
|
#include <sys/vmmeter.h>
|
|
#include <sys/limits.h>
|
|
#include <vm/vm_param.h>
|
|
#endif
|
|
|
|
#if defined(AURORA_IS_LINUX_DERIVED)
|
|
#include <sys/sysinfo.h>
|
|
#include <sys/resource.h>
|
|
#endif
|
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
#include <psapi.h>
|
|
#include <winternl.h>
|
|
#endif
|
|
|
|
namespace Aurora::HWInfo
|
|
{
|
|
static AuOptional<RamStat> gMemStartup;
|
|
|
|
AUKN_SYM AuOptional<RamStat> GetMemStatProcess()
|
|
{
|
|
auto max = GetMemStatSystem().value_or(RamStat {}).qwAvailable;
|
|
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
|
|
PROCESS_MEMORY_COUNTERS_EX pmc;
|
|
PROCESS_MEMORY_COUNTERS pm;
|
|
|
|
if (pGetProcessMemoryInfo)
|
|
{
|
|
if (pGetProcessMemoryInfo(GetCurrentProcess(),
|
|
reinterpret_cast<PPROCESS_MEMORY_COUNTERS>(&pmc),
|
|
sizeof(PROCESS_MEMORY_COUNTERS_EX)))
|
|
{
|
|
if (pmc.PagefileUsage)
|
|
{
|
|
return RamStat { pmc.PagefileUsage, max };
|
|
}
|
|
else
|
|
{
|
|
return RamStat { pmc.PrivateUsage, max };
|
|
}
|
|
}
|
|
|
|
if (pGetProcessMemoryInfo(GetCurrentProcess(),
|
|
reinterpret_cast<PPROCESS_MEMORY_COUNTERS>(&pm),
|
|
sizeof(PROCESS_MEMORY_COUNTERS)))
|
|
{
|
|
if (pm.PagefileUsage)
|
|
{
|
|
return RamStat { pm.PagefileUsage, max };
|
|
}
|
|
else
|
|
{
|
|
return RamStat { pm.WorkingSetSize, max };
|
|
}
|
|
}
|
|
}
|
|
|
|
return RamStat {0, max};
|
|
|
|
#elif defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
struct rusage usage;
|
|
|
|
getrusage(RUSAGE_SELF, &usage);
|
|
auto used = AuUInt64(usage.ru_maxrss)
|
|
#if !defined(AURORA_IS_XNU_DERIVED)
|
|
* 1024
|
|
#endif
|
|
;
|
|
return RamStat {used, max};
|
|
|
|
#else
|
|
|
|
return {};
|
|
|
|
#endif
|
|
}
|
|
|
|
AUKN_SYM AuOptional<RamStat> GetMemStatProcessBlamed()
|
|
{
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
auto max = GetMemStatSystem().value_or(RamStat {}).qwAvailable;
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
if (pNtQueryInformationProcess &&
|
|
AuSwInfo::IsWindows10OrGreater())
|
|
{
|
|
struct VM_COUNTERS_EX
|
|
{
|
|
SIZE_T PeakVirtualSize;
|
|
SIZE_T VirtualSize;
|
|
ULONG PageFaultCount;
|
|
SIZE_T PeakWorkingSetSize;
|
|
SIZE_T WorkingSetSize;
|
|
SIZE_T QuotaPeakPagedPoolUsage;
|
|
SIZE_T QuotaPagedPoolUsage;
|
|
SIZE_T QuotaPeakNonPagedPoolUsage;
|
|
SIZE_T QuotaNonPagedPoolUsage;
|
|
SIZE_T PagefileUsage;
|
|
SIZE_T PeakPagefileUsage;
|
|
SIZE_T PrivateUsage;
|
|
};
|
|
|
|
struct VM_COUNTERS_EX2
|
|
{
|
|
VM_COUNTERS_EX CountersEx;
|
|
SIZE_T PrivateWorkingSetSize;
|
|
ULONGLONG SharedCommitUsage;
|
|
} vm;
|
|
|
|
static const PROCESSINFOCLASS kProcessVmCounters = static_cast<PROCESSINFOCLASS>(3);
|
|
|
|
if (pNtQueryInformationProcess(GetCurrentProcess(),
|
|
kProcessVmCounters,
|
|
&vm,
|
|
sizeof(vm),
|
|
0))
|
|
{
|
|
// I WILL NOT USE A BLOATED OS THAT LIES TO US
|
|
// I WILL NOT USE A BLOATED OS THAT LIES TO US
|
|
// I WILL NOT USE A BLOATED OS THAT LIES TO US
|
|
// I WILL NOT USE A BLOATED OS THAT LIES TO US
|
|
// I WILL NOT USE A BLOATED OS THAT LIES TO US
|
|
// I WILL NOT USE A BLOATED OS THAT LIES TO US
|
|
return RamStat {vm.PrivateWorkingSetSize, max};
|
|
}
|
|
}
|
|
#endif
|
|
|
|
PROCESS_MEMORY_COUNTERS pm;
|
|
if (pGetProcessMemoryInfo(GetCurrentProcess(),
|
|
reinterpret_cast<PPROCESS_MEMORY_COUNTERS>(&pm),
|
|
sizeof(PROCESS_MEMORY_COUNTERS)))
|
|
{
|
|
return RamStat { pm.WorkingSetSize, max };
|
|
}
|
|
|
|
return RamStat {};
|
|
#else
|
|
return GetMemStatProcess();
|
|
#endif
|
|
}
|
|
|
|
#if defined(AURORA_IS_BSD_DERIVED)
|
|
struct vmtotal GetVMInfo()
|
|
{
|
|
struct vmtotal info;
|
|
int mib[2];
|
|
|
|
mib[0] = CTL_VM;
|
|
mib[1] = VM_TOTAL;
|
|
|
|
size_t len = sizeof(info);
|
|
sysctl(mib, 2, &info, &len, NULL, 0);
|
|
|
|
return info; // TODO: consider polling VM_UVMEXP
|
|
}
|
|
#endif
|
|
|
|
AUKN_SYM AuOptional<RamStat> GetMemStatSystem()
|
|
{
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
|
|
MEMORYSTATUSEX statex;
|
|
statex.dwLength = sizeof(statex);
|
|
|
|
if (!GlobalMemoryStatusEx(&statex))
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return RamStat {statex.ullTotalPageFile - statex.ullAvailPageFile, statex.ullTotalPageFile};
|
|
|
|
#elif defined(AURORA_IS_BSD_DERIVED)
|
|
|
|
auto vmInfo = GetVMInfo();
|
|
auto pageSize = AuUInt64(QueryBsdHwStat<unsigned int>(HW_PAGESIZE).value_or(4096));
|
|
auto totalMem = AuUInt64(vmInfo.t_vm) * pageSize;
|
|
auto freeMem = AuUInt64(vmInfo.t_free) * pageSize;
|
|
|
|
return RamStat {freeMem - totalMem, totalMem};
|
|
|
|
#elif defined(AURORA_IS_LINUX_DERIVED)
|
|
|
|
struct sysinfo info;
|
|
|
|
if (sysinfo(&info) != 0)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return RamStat {(info.totalram - info.freeram) + (info.totalswap - info.freeswap), info.totalram + info.totalswap};
|
|
|
|
#else
|
|
|
|
return GetMemStatPhysical();
|
|
|
|
#endif
|
|
}
|
|
|
|
AUKN_SYM AuOptional<RamStat> GetMemStatPhysical()
|
|
{
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
|
|
MEMORYSTATUSEX statex;
|
|
statex.dwLength = sizeof(statex);
|
|
|
|
if (!GlobalMemoryStatusEx(&statex))
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return RamStat {statex.ullTotalPhys - statex.ullAvailPhys, statex.ullTotalPhys};
|
|
|
|
#elif defined(AURORA_IS_BSD_DERIVED)
|
|
|
|
#if defined(HW_PHYSMEM64)
|
|
uint64_t stat;
|
|
auto cmd = HW_PHYSMEM64;
|
|
#else
|
|
unsigned int stat;
|
|
auto cmd = HW_PHYSMEM;
|
|
#endif
|
|
|
|
auto maxMem = QueryBsdHwStat<decltype(stat)>(cmd);
|
|
auto vmInfo = GetVMInfo();
|
|
auto freeMem = AuUInt64(vmInfo.t_free) * AuUInt64(QueryBsdHwStat<unsigned int>(HW_PAGESIZE).value_or(4096));
|
|
|
|
return RamStat {vmInfo.t_rm, maxMem.value_or(freeMem)};
|
|
|
|
#elif defined(AURORA_IS_LINUX_DERIVED)
|
|
|
|
struct sysinfo info;
|
|
|
|
if (sysinfo(&info) != 0)
|
|
{
|
|
return {};
|
|
}
|
|
|
|
return RamStat {info.totalram - info.freeram, info.totalram};
|
|
|
|
#else
|
|
|
|
return {};
|
|
|
|
#endif
|
|
}
|
|
|
|
AUKN_SYM AuOptional<RamStat> GetMemStatStartup()
|
|
{
|
|
return gMemStartup;
|
|
}
|
|
|
|
AUKN_SYM AuUInt32 GetPageSize()
|
|
{
|
|
return gPageSize;
|
|
}
|
|
|
|
AUKN_SYM AuOptional<AuUInt64> GetSwapSize()
|
|
{
|
|
static AuOptional<AuUInt64> gCached;
|
|
if (gCached)
|
|
{
|
|
return gCached;
|
|
}
|
|
|
|
if (auto opt = GetMemStatSystem())
|
|
{
|
|
if (auto optPhys = GetMemStatPhysical())
|
|
{
|
|
return gCached = AuUInt64(opt.value().qwAvailable - optPhys.value().qwAvailable);
|
|
}
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
AUKN_SYM AuOptional<AuUInt64> GetPhysicalSize()
|
|
{
|
|
static AuOptional<AuUInt64> gCached;
|
|
if (gCached)
|
|
{
|
|
return gCached;
|
|
}
|
|
|
|
if (auto optPhys = GetMemStatPhysical())
|
|
{
|
|
return gCached = optPhys.value().qwAvailable;
|
|
}
|
|
|
|
return {};
|
|
}
|
|
|
|
static void SetPageSize()
|
|
{
|
|
#if defined(AURORA_IS_MODERNNT_DERIVED)
|
|
|
|
SYSTEM_INFO info;
|
|
GetSystemInfo(&info);
|
|
gPageSize = info.dwPageSize;
|
|
|
|
#elif defined(AURORA_IS_POSIX_DERIVED)
|
|
|
|
gPageSize = getpagesize();
|
|
|
|
#else
|
|
|
|
gPageSize = 4096;
|
|
|
|
#endif
|
|
}
|
|
|
|
void InitRamInfo()
|
|
{
|
|
gMemStartup = GetMemStatSystem();
|
|
SetPageSize();
|
|
}
|
|
}
|