{"thread":{"id":"63126","subject":"[PATCH 09/12] builtin/gc.c: correct RAM calculation when using sysinfo","startedAt":"2025-03-15T02:48:42Z","lastAt":"2025-03-15T02:48:42Z","messageCount":1,"participants":["Ramsay Jones"],"isPatch":true,"patchVersion":1,"patchTotal":12},"messages":[{"id":"514339","messageId":"84b41b4b-00fb-4bc9-83ab-df1911c81a8d@ramsayjones.plus.com","threadId":"63126","inReplyTo":null,"subject":"[PATCH 09/12] builtin/gc.c: correct RAM calculation when using sysinfo","fromName":"Ramsay Jones","fromEmail":"ramsay@ramsayjones.plus.com","sentAt":"2025-03-15T02:48:40Z","receivedAt":"2025-03-15T02:48:42Z","isPatch":true,"sender":{"key":"ramsay@ramsayjones.plus.com","avatar":"https://avatars.githubusercontent.com/u/33702710?v=4"},"body":"\nThe man page for sysinfo(2) on Linux states that (from v2.3.48) the\nsizes of the memory and swap fields, of the returned structure, are\ngiven as multiples of 'mem_unit' bytes. In earlier versions (prior to\nv2.3.23 on i386 in particular), the 'mem_unit' field was not part of\nthe structure, and all sizes were measured in bytes. The man page does\nnot discuss the motivation for this change, but it is possible that the\nchange was intended for the, relatively rare, 32-bit platform with more\nthan 4GB of memory.\n\nThe total_ram() function makes the assumption that the 'totalram' field\nof the 'struct sysinfo' is measured in bytes, or alternatively that the\n'mem_unit' field is always equal to one. Having writen a program to call\nthe sysinfo() function and print the structure fields, it seems that, on\nLinux x84_64 and i686 anyway, the 'mem_unit' field is indeed set to one\n(note that the 32-bit system had only 2GB ram). However, cygwin also has\nan sysinfo() implementation, which gives the following values:\n\n  $ ./sysinfo\n  uptime:      21381\n  loads:       0, 0, 0\n  total ram:   2074637\n  free ram:    843237\n  shared ram:  0\n  buffer ram:  0\n  total swap:  327680\n  free swap:   306932\n  procs:       15\n  total high:  0\n  free high:   0\n  mem_unit:    4096\n\n  total ram: 8497713152\n  $\n\n[This laptop has 8GB ram, so a little bit seems to be missing. ;) ]\n\nModify the total_ram() function to allow for the possibility that the\nmemory size is not specified in bytes (ie 'mem_unit' is greater than\none).\n\nSigned-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>\n---\n builtin/gc.c | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/gc.c b/builtin/gc.c\nindex 99431fd467..cdcf1dc6e7 100644\n--- a/builtin/gc.c\n+++ b/builtin/gc.c\n@@ -373,8 +373,13 @@ static uint64_t total_ram(void)\n #if defined(HAVE_SYSINFO)\n \tstruct sysinfo si;\n \n-\tif (!sysinfo(&si))\n-\t\treturn si.totalram;\n+\tif (!sysinfo(&si)) {\n+\t\tuint64_t total = si.totalram;\n+\n+\t\tif (si.mem_unit > 1)\n+\t\t\ttotal *= (uint64_t)si.mem_unit;\n+\t\treturn total;\n+\t}\n #elif defined(HAVE_BSD_SYSCTL) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM))\n \tint64_t physical_memory;\n \tint mib[2];\n-- \n2.49.0\n"}]}