Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:19
erlang
0966-memsup-Return-correct-amount-of-total-syst...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0966-memsup-Return-correct-amount-of-total-system-memory-.patch of Package erlang
From 8fa2387eefcc8a9b931c0ed560c6d0768294f88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org> Date: Wed, 26 Aug 2020 08:11:19 +0200 Subject: [PATCH] memsup: Return correct amount of total system memory on macOS On macOS, `memsup:get_system_memory_data/0` and `memsup:get_memory_data/0` returns a much too low number for the amount system memory. The bug is in a function that tried to determine the amount of memory by summing numbers from the output of the `vm_stat` command. Instead of trying to fix the summation, we will change approach and use the port program to retrieve the information. Using the Mach APIs the total amount of memory can be retrieved directly without any summing. https://bugs.erlang.org/browse/ERL-1327 --- lib/os_mon/c_src/memsup.c | 66 +++++++++++++++++++++++++++++++++++++++ lib/os_mon/src/memsup.erl | 31 +----------------- 2 files changed, 67 insertions(+), 30 deletions(-) diff --git a/lib/os_mon/c_src/memsup.c b/lib/os_mon/c_src/memsup.c index 322e474c3b..b1f45a590a 100644 --- a/lib/os_mon/c_src/memsup.c +++ b/lib/os_mon/c_src/memsup.c @@ -114,6 +114,13 @@ #include <sys/sysinfo.h> #endif +#if defined(__APPLE__) +#include <mach/mach.h> +static mach_port_t mach_host_port; +static vm_size_t mach_page_size; +static uint64_t total_memory_size; +#endif + /* commands */ #include "memsup.h" @@ -394,6 +401,48 @@ get_extended_mem_sgi(memory_ext *me) { } #endif +#if defined(__APPLE__) +static void +init_apple(void) { + kern_return_t kr; + mach_msg_type_number_t count; + host_basic_info_data_t hinfo; + + mach_host_port = mach_host_self(); + + count = HOST_BASIC_INFO_COUNT; + kr = host_info(mach_host_port, HOST_BASIC_INFO, (host_info_t) &hinfo, &count); + if (kr != KERN_SUCCESS) { + abort(); + } + total_memory_size = hinfo.max_mem; + + kr = host_page_size(mach_host_port, &mach_page_size); + if (kr != KERN_SUCCESS) { + abort(); + } +} + +static void +get_extended_mem_apple(memory_ext *me) { + kern_return_t kr; + host_basic_info_data_t hinfo; + mach_msg_type_number_t count; + vm_statistics_data_t vm_stat; + + count = HOST_VM_INFO_COUNT; + kr = host_statistics(mach_host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &count); + if (kr != KERN_SUCCESS) { + return; + } + + me->free = vm_stat.free_count * mach_page_size; + me->total = total_memory_size; + me->pagesize = 1; + me->flag = F_MEM_TOTAL | F_MEM_FREE; +} +#endif + static void get_extended_mem(memory_ext *me) { /* android */ @@ -418,6 +467,9 @@ get_extended_mem(memory_ext *me) { #if defined(_SC_AVPHYS_PAGES) if (get_extended_mem_sysconf(me)) return; +#elif defined(__APPLE__) + get_extended_mem_apple(me); + /* We fake the rest */ /* SunOS4 (for example) */ #else @@ -471,6 +523,15 @@ fail: print_error("%s", strerror(errno)); exit(1); } +#elif defined(__APPLE__) + { + memory_ext me; + me.free = 0; + get_extended_mem_apple(&me); + *used = me.total - me.free; + *tot = total_memory_size; + *pagesize = 1; + } #else /* SunOS4 */ *used = (1<<27); /* Fake! 128 MB used */ *tot = (1<<28); /* Fake! 256 MB total */ @@ -567,7 +628,12 @@ message_loop(int erlin_fd) int MAIN(int argc, char **argv) { +#ifdef __APPLE__ + init_apple(); +#endif + program_name = argv[0]; + message_loop(ERLIN_FD); return 0; } diff --git a/lib/os_mon/src/memsup.erl b/lib/os_mon/src/memsup.erl index bbf120e973..c55185c9d3 100644 --- a/lib/os_mon/src/memsup.erl +++ b/lib/os_mon/src/memsup.erl @@ -175,7 +175,7 @@ init([]) -> OS = os:type(), PortMode = case OS of - {unix, darwin} -> false; + {unix, darwin} -> true; {unix, freebsd} -> false; {unix, dragonfly} -> false; % Linux supports this. @@ -726,22 +726,6 @@ reply(Pending, MemUsage, SysMemUsage) -> %% get_memory_usage(OS) -> {Alloc, Total} -%% Darwin: -%% Uses vm_stat command. -get_memory_usage({unix,darwin}) -> - Str1 = os:cmd("/usr/bin/vm_stat"), - PageSize = 4096, - - {[Free], Str2} = fread_value("Pages free:~d.", Str1), - {[Active], Str3} = fread_value("Pages active:~d.", Str2), - {[Inactive], Str4} = fread_value("Pages inactive:~d.", Str3), - {[Speculative], Str5} = fread_value("Pages speculative:~d.", Str4), - {[Wired], _} = fread_value("Pages wired down:~d.", Str5), - - NMemUsed = (Wired + Active + Inactive) * PageSize, - NMemTotal = NMemUsed + (Free + Speculative) * PageSize, - {NMemUsed,NMemTotal}; - %% FreeBSD: Look in /usr/include/sys/vmmeter.h for the format of struct %% vmmeter get_memory_usage({unix,OSname}) when OSname == freebsd; OSname == dragonfly -> @@ -761,16 +745,6 @@ get_memory_usage({win32,_OSname}) -> io_lib:fread("~d~d~d~d~d~d~d", Result), {TotPhys-AvailPhys, TotPhys}. -fread_value(Format, Str0) -> - case io_lib:fread(Format, skip_to_eol(Str0)) of - {error, {fread, input}} -> {[0], Str0}; - {ok, Value, Str1} -> {Value, Str1} - end. - -skip_to_eol([]) -> []; -skip_to_eol([$\n | T]) -> T; -skip_to_eol([_ | T]) -> skip_to_eol(T). - freebsd_sysctl(Def) -> list_to_integer(os:cmd("/sbin/sysctl -n " ++ Def) -- "\n"). @@ -790,9 +764,6 @@ get_ext_memory_usage(OS, {Alloc, Total}) -> {unix, dragonfly} -> [{total_memory, Total}, {free_memory, Total-Alloc}, {system_total_memory, Total}]; - {unix, darwin} -> - [{total_memory, Total}, {free_memory, Total-Alloc}, - {system_total_memory, Total}]; _ -> % OSs using a port dummy % not sent anyway end. -- 2.26.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor