#include #include "common/getMemoryAmount.h" // http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system /* * Author: David Robert Nadeau * Site: http://NadeauSoftware.com/ * License: Creative Commons Attribution 3.0 Unported License * http://creativecommons.org/licenses/by/3.0/deed.en_US */ #if defined(WIN32) || defined(_WIN32) #include #else #include #include #include #if defined(BSD) #include #endif #endif /** * Returns the size of physical memory (RAM) in bytes. * Returns 0 on unsupported platform */ uint64_t getMemoryAmountOrZero() { #if defined(_WIN32) && (defined(__CYGWIN__) || defined(__CYGWIN32__)) /* Cygwin under Windows. ------------------------------------ */ /* New 64-bit MEMORYSTATUSEX isn't available. Use old 32.bit */ MEMORYSTATUS status; status.dwLength = sizeof(status); GlobalMemoryStatus(&status); return status.dwTotalPhys; #elif defined(WIN32) || defined(_WIN32) /* Windows. ------------------------------------------------- */ /* Use new 64-bit MEMORYSTATUSEX, not old 32-bit MEMORYSTATUS */ MEMORYSTATUSEX status; status.dwLength = sizeof(status); GlobalMemoryStatusEx(&status); return status.ullTotalPhys; #else /* UNIX variants. ------------------------------------------- */ /* Prefer sysctl() over sysconf() except sysctl() HW_REALMEM and HW_PHYSMEM */ #if defined(CTL_HW) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM64)) int mib[2]; mib[0] = CTL_HW; #if defined(HW_MEMSIZE) mib[1] = HW_MEMSIZE; /* OSX. --------------------- */ #elif defined(HW_PHYSMEM64) mib[1] = HW_PHYSMEM64; /* NetBSD, OpenBSD. --------- */ #endif uint64_t size = 0; /* 64-bit */ size_t len = sizeof(size); if (sysctl(mib, 2, &size, &len, nullptr, 0) == 0) return size; return 0; /* Failed? */ #elif defined(_SC_AIX_REALMEM) /* AIX. ----------------------------------------------------- */ return sysconf(_SC_AIX_REALMEM) * 1024; #elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) /* FreeBSD, Linux, OpenBSD, and Solaris. -------------------- */ return uint64_t(sysconf(_SC_PHYS_PAGES)) *uint64_t(sysconf(_SC_PAGESIZE)); #elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGE_SIZE) /* Legacy. -------------------------------------------------- */ return uint64_t(sysconf(_SC_PHYS_PAGES)) * uint64_t(sysconf(_SC_PAGE_SIZE)); #elif defined(CTL_HW) && (defined(HW_PHYSMEM) || defined(HW_REALMEM)) /* DragonFly BSD, FreeBSD, NetBSD, OpenBSD, and OSX. -------- */ int mib[2]; mib[0] = CTL_HW; #if defined(HW_REALMEM) mib[1] = HW_REALMEM; /* FreeBSD. ----------------- */ #elif defined(HW_PYSMEM) mib[1] = HW_PHYSMEM; /* Others. ------------------ */ #endif unsigned int size = 0; /* 32-bit */ size_t len = sizeof(size); if (sysctl(mib, 2, &size, &len, nullptr, 0) == 0) return size; return 0; /* Failed? */ #endif /* sysctl and sysconf variants */ #endif } uint64_t getMemoryAmount() { auto res = getMemoryAmountOrZero(); if (!res) throw std::runtime_error("Cannot determine memory amount"); return res; }