diff options
| author | Stefan Boberg <[email protected]> | 2025-11-24 09:56:20 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-11-24 09:56:20 +0100 |
| commit | 3bce1022e04e20fadaecdcf21bba582ec738600d (patch) | |
| tree | a9d6ecfeafeb7e3da866b42dc805cc3408457882 /src/zencore/system.cpp | |
| parent | increase timeout and add retry when testing host connectivity (#659) (diff) | |
| download | zen-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.cpp | 150 |
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" |