1 ///////////////////////////////////////////////////////////////////////////////
4 /// \brief Get the amount of physical memory
6 // Author: Lasse Collin
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
11 ///////////////////////////////////////////////////////////////////////////////
16 #if defined(HAVE_PHYSMEM_SYSCONF)
19 #elif defined(HAVE_PHYSMEM_SYSCTL)
20 # ifdef HAVE_SYS_PARAM_H
21 # include <sys/param.h>
23 # ifdef HAVE_SYS_SYSCTL_H
24 # include <sys/sysctl.h>
27 #elif defined(HAVE_PHYSMEM_SYSINFO)
28 # include <sys/sysinfo.h>
32 # define _WIN32_WINNT 0x0500
36 #elif defined(__DJGPP__)
41 /// \brief Get the amount of physical memory in bytes
43 /// \return Amount of physical memory in bytes. On error, zero is
45 static inline uint64_t
50 #if defined(HAVE_PHYSMEM_SYSCONF)
51 const long pagesize = sysconf(_SC_PAGESIZE);
52 const long pages = sysconf(_SC_PHYS_PAGES);
53 if (pagesize != -1 || pages != -1)
54 // According to docs, pagesize * pages can overflow.
55 // Simple case is 32-bit box with 4 GiB or more RAM,
56 // which may report exactly 4 GiB of RAM, and "long"
57 // being 32-bit will overflow. Casting to uint64_t
58 // hopefully avoids overflows in the near future.
59 ret = (uint64_t)(pagesize) * (uint64_t)(pages);
61 #elif defined(HAVE_PHYSMEM_SYSCTL)
62 int name[2] = { CTL_HW, HW_PHYSMEM };
67 size_t mem_ptr_size = sizeof(mem.ul);
68 if (!sysctl(name, 2, &mem.ul, &mem_ptr_size, NULL, NULL)) {
69 // Some systems use unsigned int as the "return value".
70 // This makes a difference on 64-bit boxes.
71 if (mem_ptr_size == sizeof(mem.ul))
73 else if (mem_ptr_size == sizeof(mem.ui))
77 #elif defined(HAVE_PHYSMEM_SYSINFO)
79 if (sysinfo(&si) == 0)
80 ret = (uint64_t)(si.totalram) * si.mem_unit;
83 if ((GetVersion() & 0xFF) >= 5) {
84 // Windows 2000 and later have GlobalMemoryStatusEx() which
85 // supports reporting values greater than 4 GiB. To keep the
86 // code working also on older Windows versions, use
87 // GlobalMemoryStatusEx() conditionally.
88 HMODULE kernel32 = GetModuleHandle("kernel32.dll");
89 if (kernel32 != NULL) {
90 BOOL (WINAPI *gmse)(LPMEMORYSTATUSEX) = GetProcAddress(
91 kernel32, "GlobalMemoryStatusEx");
93 MEMORYSTATUSEX meminfo;
94 meminfo.dwLength = sizeof(meminfo);
96 ret = meminfo.ullTotalPhys;
102 // GlobalMemoryStatus() is supported by Windows 95 and later,
103 // so it is fine to link against it unconditionally. Note that
104 // GlobalMemoryStatus() has no return value.
105 MEMORYSTATUS meminfo;
106 meminfo.dwLength = sizeof(meminfo);
107 GlobalMemoryStatus(&meminfo);
108 ret = meminfo.dwTotalPhys;
111 #elif defined(__DJGPP__)
112 __dpmi_free_mem_info meminfo;
113 if (__dpmi_get_free_memory_information(&meminfo) == 0
114 && meminfo.total_number_of_physical_pages
115 != (unsigned long)(-1))
116 ret = (uint64_t)(meminfo.total_number_of_physical_pages)