aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/system.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-11-24 09:56:20 +0100
committerGitHub Enterprise <[email protected]>2025-11-24 09:56:20 +0100
commit3bce1022e04e20fadaecdcf21bba582ec738600d (patch)
treea9d6ecfeafeb7e3da866b42dc805cc3408457882 /src/zencore/system.cpp
parentincrease timeout and add retry when testing host connectivity (#659) (diff)
downloadzen-3bce1022e04e20fadaecdcf21bba582ec738600d.tar.xz
zen-3bce1022e04e20fadaecdcf21bba582ec738600d.zip
GetSystemMetrics for Mac,Linux (#660)
Implemented GetSystemMetrics function for Mac and Linux
Diffstat (limited to 'src/zencore/system.cpp')
-rw-r--r--src/zencore/system.cpp150
1 files changed, 148 insertions, 2 deletions
diff --git a/src/zencore/system.cpp b/src/zencore/system.cpp
index f37bdf423..b9ac3bdee 100644
--- a/src/zencore/system.cpp
+++ b/src/zencore/system.cpp
@@ -16,8 +16,13 @@ ZEN_THIRD_PARTY_INCLUDES_START
ZEN_THIRD_PARTY_INCLUDES_END
#elif ZEN_PLATFORM_LINUX
# include <sys/utsname.h>
+# include <unistd.h>
#elif ZEN_PLATFORM_MAC
# include <unistd.h>
+# include <mach/mach.h>
+# include <mach/mach_host.h>
+# include <sys/types.h>
+# include <sys/sysctl.h>
#endif
namespace zen {
@@ -134,7 +139,104 @@ GetMachineName()
SystemMetrics
GetSystemMetrics()
{
- return {};
+ SystemMetrics Metrics;
+
+ // Get processor information
+ long NumProcessors = sysconf(_SC_NPROCESSORS_ONLN);
+ if (NumProcessors > 0)
+ {
+ Metrics.LogicalProcessorCount = static_cast<uint32_t>(NumProcessors);
+ }
+
+ // On Linux, we approximate core count from logical processor count
+ // A more accurate implementation would parse /proc/cpuinfo
+ Metrics.CoreCount = Metrics.LogicalProcessorCount;
+ Metrics.CpuCount = 1; // Default to 1 CPU package
+
+ // Parse /proc/cpuinfo for more accurate core/CPU info
+ if (FILE* CpuInfo = fopen("/proc/cpuinfo", "r"))
+ {
+ char Line[1024];
+ int PhysicalIds = 0;
+ int CoreIds = 0;
+
+ while (fgets(Line, sizeof(Line), CpuInfo))
+ {
+ if (strncmp(Line, "physical id", 11) == 0)
+ {
+ int Id;
+ if (sscanf(Line, "physical id\t: %d", &Id) == 1)
+ {
+ if (Id + 1 > PhysicalIds)
+ {
+ PhysicalIds = Id + 1;
+ }
+ }
+ }
+ else if (strncmp(Line, "cpu cores", 9) == 0)
+ {
+ sscanf(Line, "cpu cores\t: %d", &CoreIds);
+ }
+ }
+ fclose(CpuInfo);
+
+ if (PhysicalIds > 0)
+ {
+ Metrics.CpuCount = PhysicalIds;
+ }
+ if (CoreIds > 0)
+ {
+ Metrics.CoreCount = CoreIds * Metrics.CpuCount;
+ }
+ }
+
+ // Get memory information
+ long Pages = sysconf(_SC_PHYS_PAGES);
+ long PageSize = sysconf(_SC_PAGE_SIZE);
+ long AvailPages = sysconf(_SC_AVPHYS_PAGES);
+
+ if (Pages > 0 && PageSize > 0)
+ {
+ Metrics.SystemMemoryMiB = (Pages * PageSize) / 1024 / 1024;
+ Metrics.AvailSystemMemoryMiB = (AvailPages * PageSize) / 1024 / 1024;
+ }
+
+ // Virtual memory is not directly available via sysconf
+ // Set to system memory as a reasonable default
+ Metrics.VirtualMemoryMiB = Metrics.SystemMemoryMiB;
+ Metrics.AvailVirtualMemoryMiB = Metrics.AvailSystemMemoryMiB;
+
+ // Parse /proc/meminfo for swap/page file information
+ Metrics.PageFileMiB = 0;
+ Metrics.AvailPageFileMiB = 0;
+
+ if (FILE* MemInfo = fopen("/proc/meminfo", "r"))
+ {
+ char Line[256];
+ long SwapTotal = 0;
+ long SwapFree = 0;
+
+ while (fgets(Line, sizeof(Line), MemInfo))
+ {
+ if (strncmp(Line, "SwapTotal:", 10) == 0)
+ {
+ sscanf(Line, "SwapTotal: %ld kB", &SwapTotal);
+ }
+ else if (strncmp(Line, "SwapFree:", 9) == 0)
+ {
+ sscanf(Line, "SwapFree: %ld kB", &SwapFree);
+ }
+ }
+ fclose(MemInfo);
+
+ if (SwapTotal > 0)
+ {
+ Metrics.PageFileMiB = SwapTotal / 1024;
+ Metrics.AvailPageFileMiB = SwapFree / 1024;
+ }
+ }
+
+ return Metrics;
}
#elif ZEN_PLATFORM_MAC
std::string
@@ -152,7 +254,51 @@ GetMachineName()
SystemMetrics
GetSystemMetrics()
{
- return {};
+ SystemMetrics Metrics;
+
+ // Get processor information
+ size_t Size = sizeof(Metrics.LogicalProcessorCount);
+ sysctlbyname("hw.logicalcpu", &Metrics.LogicalProcessorCount, &Size, nullptr, 0);
+
+ uint32_t PhysicalCpu = 0;
+ Size = sizeof(PhysicalCpu);
+ sysctlbyname("hw.physicalcpu", &PhysicalCpu, &Size, nullptr, 0);
+ Metrics.CoreCount = PhysicalCpu;
+
+ uint32_t Packages = 0;
+ Size = sizeof(Packages);
+ sysctlbyname("hw.packages", &Packages, &Size, nullptr, 0);
+ Metrics.CpuCount = Packages > 0 ? Packages : 1;
+
+ // Get memory information
+ uint64_t MemSize = 0;
+ Size = sizeof(MemSize);
+ sysctlbyname("hw.memsize", &MemSize, &Size, nullptr, 0);
+ Metrics.SystemMemoryMiB = MemSize / 1024 / 1024;
+
+ // Get available memory using vm_stat
+ 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;
+
+ // Virtual memory on macOS is essentially unlimited, set to a large value
+ Metrics.VirtualMemoryMiB = Metrics.SystemMemoryMiB * 16;
+ Metrics.AvailVirtualMemoryMiB = Metrics.VirtualMemoryMiB;
+
+ // macOS doesn't use traditional page files, use swap space
+ xsw_usage SwapUsage;
+ Size = sizeof(SwapUsage);
+ sysctlbyname("vm.swapusage", &SwapUsage, &Size, nullptr, 0);
+ Metrics.PageFileMiB = SwapUsage.xsu_total / 1024 / 1024;
+ Metrics.AvailPageFileMiB = (SwapUsage.xsu_total - SwapUsage.xsu_used) / 1024 / 1024;
+
+ return Metrics;
}
#else
# error "Unknown platform"