Skip to content

Commit c9a5177

Browse files
ramsay-jonesgitster
authored andcommitted
builtin/gc.c: correct RAM calculation when using sysinfo
The man page for sysinfo(2) on Linux states that (from v2.3.48) the sizes of the memory and swap fields, of the returned structure, are given as multiples of 'mem_unit' bytes. In earlier versions (prior to v2.3.23 on i386 in particular), the 'mem_unit' field was not part of the structure, and all sizes were measured in bytes. The man page does not discuss the motivation for this change, but it is possible that the change was intended for the, relatively rare, 32-bit platform with more than 4GB of memory. The total_ram() function makes the assumption that the 'totalram' field of the 'struct sysinfo' is measured in bytes, or alternatively that the 'mem_unit' field is always equal to one. Having writen a program to call the sysinfo() function and print the structure fields, it seems that, on Linux x84_64 and i686 anyway, the 'mem_unit' field is indeed set to one (note that the 32-bit system had only 2GB ram). However, cygwin also has an sysinfo() implementation, which gives the following values: $ ./sysinfo uptime: 21381 loads: 0, 0, 0 total ram: 2074637 free ram: 843237 shared ram: 0 buffer ram: 0 total swap: 327680 free swap: 306932 procs: 15 total high: 0 free high: 0 mem_unit: 4096 total ram: 8497713152 $ [This laptop has 8GB ram, so a little bit seems to be missing. ;) ] Modify the total_ram() function to allow for the possibility that the memory size is not specified in bytes (ie 'mem_unit' is greater than one). Signed-off-by: Ramsay Jones <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a45ca6f commit c9a5177

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

builtin/gc.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,13 @@ static uint64_t total_ram(void)
373373
#if defined(HAVE_SYSINFO)
374374
struct sysinfo si;
375375

376-
if (!sysinfo(&si))
377-
return si.totalram;
376+
if (!sysinfo(&si)) {
377+
uint64_t total = si.totalram;
378+
379+
if (si.mem_unit > 1)
380+
total *= (uint64_t)si.mem_unit;
381+
return total;
382+
}
378383
#elif defined(HAVE_BSD_SYSCTL) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM))
379384
int64_t physical_memory;
380385
int mib[2];

0 commit comments

Comments
 (0)