/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuRamInfo.cpp Date: 2021-6-12 Author: Reece ***/ #include #include "AuHWInfo.hpp" #include "AuRamInfo.hpp" #if defined(AURORA_IS_BSD_DERIVED) #include #include #include #include #endif #if defined(AURORA_IS_LINUX_DERIVED) #include #include #endif #if defined(AURORA_IS_MODERNNT_DERIVED) #include #include #endif namespace Aurora::HWInfo { static AuOptional gMemStartup; AUKN_SYM AuOptional GetMemStatProcess() { auto max = GetMemStatSystem().value_or(RamStat {}).qwAvailable; #if defined(AURORA_IS_MODERNNT_DERIVED) PROCESS_MEMORY_COUNTERS pm; if (GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast(&pm), sizeof(PROCESS_MEMORY_COUNTERS))) { 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 GetMemStatProcessBlamed() { #if defined(AURORA_IS_MODERNNT_DERIVED) auto max = GetMemStatSystem().value_or(RamStat {}).qwAvailable; #if defined(AURORA_PLATFORM_WIN32) if (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(3); if (NtQueryInformationProcess(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_EX pmc; PROCESS_MEMORY_COUNTERS pm; if (GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast(&pmc), sizeof(PROCESS_MEMORY_COUNTERS_EX))) { return RamStat {pmc.PrivateUsage, max}; } if (GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast(&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 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(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 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(cmd); auto vmInfo = GetVMInfo(); auto freeMem = AuUInt64(vmInfo.t_free) * AuUInt64(QueryBsdHwStat(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 GetMemStatStartup() { return gMemStartup; } AUKN_SYM AuUInt32 GetPageSize() { return gPageSize; } 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(); } }