aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/system.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zencore/system.cpp')
-rw-r--r--src/zencore/system.cpp97
1 files changed, 95 insertions, 2 deletions
diff --git a/src/zencore/system.cpp b/src/zencore/system.cpp
index 6909e1a9b..486050d83 100644
--- a/src/zencore/system.cpp
+++ b/src/zencore/system.cpp
@@ -148,6 +148,18 @@ GetSystemMetrics()
return Metrics;
}
+void
+RefreshDynamicSystemMetrics(SystemMetrics& Metrics)
+{
+ MEMORYSTATUSEX MemStatus{.dwLength = sizeof(MEMORYSTATUSEX)};
+ GlobalMemoryStatusEx(&MemStatus);
+
+ Metrics.AvailSystemMemoryMiB = MemStatus.ullAvailPhys / 1024 / 1024;
+ Metrics.AvailVirtualMemoryMiB = MemStatus.ullAvailVirtual / 1024 / 1024;
+ Metrics.AvailPageFileMiB = MemStatus.ullAvailPageFile / 1024 / 1024;
+ Metrics.UptimeSeconds = GetTickCount64() / 1000;
+}
+
std::vector<std::string>
GetLocalIpAddresses()
{
@@ -324,6 +336,51 @@ GetSystemMetrics()
return Metrics;
}
+
+void
+RefreshDynamicSystemMetrics(SystemMetrics& Metrics)
+{
+ long PageSize = sysconf(_SC_PAGE_SIZE);
+ long AvailPages = sysconf(_SC_AVPHYS_PAGES);
+
+ if (AvailPages > 0 && PageSize > 0)
+ {
+ Metrics.AvailSystemMemoryMiB = (AvailPages * PageSize) / 1024 / 1024;
+ Metrics.AvailVirtualMemoryMiB = Metrics.AvailSystemMemoryMiB;
+ }
+
+ if (FILE* UptimeFile = fopen("/proc/uptime", "r"))
+ {
+ double UptimeSec = 0;
+ if (fscanf(UptimeFile, "%lf", &UptimeSec) == 1)
+ {
+ Metrics.UptimeSeconds = static_cast<uint64_t>(UptimeSec);
+ }
+ fclose(UptimeFile);
+ }
+
+ if (FILE* MemInfo = fopen("/proc/meminfo", "r"))
+ {
+ char Line[256];
+ long SwapFree = 0;
+
+ while (fgets(Line, sizeof(Line), MemInfo))
+ {
+ if (strncmp(Line, "SwapFree:", 9) == 0)
+ {
+ sscanf(Line, "SwapFree: %ld kB", &SwapFree);
+ break;
+ }
+ }
+ fclose(MemInfo);
+
+ if (SwapFree > 0)
+ {
+ Metrics.AvailPageFileMiB = SwapFree / 1024;
+ }
+ }
+}
+
#elif ZEN_PLATFORM_MAC
std::string
GetMachineName()
@@ -398,6 +455,36 @@ GetSystemMetrics()
return Metrics;
}
+
+void
+RefreshDynamicSystemMetrics(SystemMetrics& Metrics)
+{
+ vm_size_t PageSize = 0;
+ host_page_size(mach_host_self(), &PageSize);
+
+ vm_statistics64_data_t VmStats;
+ mach_msg_type_number_t InfoCount = sizeof(VmStats) / sizeof(natural_t);
+ host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&VmStats, &InfoCount);
+
+ uint64_t FreeMemory = (uint64_t)(VmStats.free_count + VmStats.inactive_count) * PageSize;
+ Metrics.AvailSystemMemoryMiB = FreeMemory / 1024 / 1024;
+ Metrics.AvailVirtualMemoryMiB = Metrics.VirtualMemoryMiB;
+
+ xsw_usage SwapUsage;
+ size_t Size = sizeof(SwapUsage);
+ sysctlbyname("vm.swapusage", &SwapUsage, &Size, nullptr, 0);
+ Metrics.AvailPageFileMiB = (SwapUsage.xsu_total - SwapUsage.xsu_used) / 1024 / 1024;
+
+ struct timeval BootTime
+ {
+ };
+ Size = sizeof(BootTime);
+ if (sysctlbyname("kern.boottime", &BootTime, &Size, nullptr, 0) == 0)
+ {
+ Metrics.UptimeSeconds = static_cast<uint64_t>(time(nullptr) - BootTime.tv_sec);
+ }
+}
+
#else
# error "Unknown platform"
#endif
@@ -655,11 +742,16 @@ struct SystemMetricsTracker::Impl
std::mutex Mutex;
CpuSampler Sampler;
+ SystemMetrics CachedMetrics;
float CachedCpuPercent = 0.0f;
Clock::time_point NextSampleTime = Clock::now();
std::chrono::milliseconds MinInterval;
- explicit Impl(std::chrono::milliseconds InMinInterval) : MinInterval(InMinInterval) {}
+ explicit Impl(std::chrono::milliseconds InMinInterval) : MinInterval(InMinInterval)
+ {
+ // Capture topology and total memory once; these don't change at runtime
+ CachedMetrics = GetSystemMetrics();
+ }
float SampleCpu()
{
@@ -683,7 +775,8 @@ ExtendedSystemMetrics
SystemMetricsTracker::Query()
{
ExtendedSystemMetrics Metrics;
- static_cast<SystemMetrics&>(Metrics) = GetSystemMetrics();
+ static_cast<SystemMetrics&>(Metrics) = m_Impl->CachedMetrics;
+ RefreshDynamicSystemMetrics(Metrics);
std::lock_guard Lock(m_Impl->Mutex);
Metrics.CpuUsagePercent = m_Impl->SampleCpu();