#if !defined(spp_memory_h_guard) #define spp_memory_h_guard #include #include #include #if defined(_WIN32) || defined( __CYGWIN__) #define SPP_WIN #endif #ifdef SPP_WIN #include #include #undef min #undef max #elif defined(__linux__) #include #include #elif defined(__FreeBSD__) #include #include #include #include #include #include #endif namespace spp { uint64_t GetSystemMemory(); uint64_t GetTotalMemoryUsed(); uint64_t GetProcessMemoryUsed(); uint64_t GetPhysicalMemory(); uint64_t GetSystemMemory() { #ifdef SPP_WIN MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&memInfo); return static_cast(memInfo.ullTotalPageFile); #elif defined(__linux__) struct sysinfo memInfo; sysinfo (&memInfo); auto totalVirtualMem = memInfo.totalram; totalVirtualMem += memInfo.totalswap; totalVirtualMem *= memInfo.mem_unit; return static_cast(totalVirtualMem); #elif defined(__FreeBSD__) kvm_t *kd; u_int pageCnt; size_t pageCntLen = sizeof(pageCnt); u_int pageSize; struct kvm_swap kswap; uint64_t totalVirtualMem; pageSize = static_cast(getpagesize()); sysctlbyname("vm.stats.vm.v_page_count", &pageCnt, &pageCntLen, NULL, 0); totalVirtualMem = pageCnt * pageSize; kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); kvm_getswapinfo(kd, &kswap, 1, 0); kvm_close(kd); totalVirtualMem += kswap.ksw_total * pageSize; return totalVirtualMem; #else return 0; #endif } uint64_t GetTotalMemoryUsed() { #ifdef SPP_WIN MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&memInfo); return static_cast(memInfo.ullTotalPageFile - memInfo.ullAvailPageFile); #elif defined(__linux__) struct sysinfo memInfo; sysinfo(&memInfo); auto virtualMemUsed = memInfo.totalram - memInfo.freeram; virtualMemUsed += memInfo.totalswap - memInfo.freeswap; virtualMemUsed *= memInfo.mem_unit; return static_cast(virtualMemUsed); #elif defined(__FreeBSD__) kvm_t *kd; u_int pageSize; u_int pageCnt, freeCnt; size_t pageCntLen = sizeof(pageCnt); size_t freeCntLen = sizeof(freeCnt); struct kvm_swap kswap; uint64_t virtualMemUsed; pageSize = static_cast(getpagesize()); sysctlbyname("vm.stats.vm.v_page_count", &pageCnt, &pageCntLen, NULL, 0); sysctlbyname("vm.stats.vm.v_free_count", &freeCnt, &freeCntLen, NULL, 0); virtualMemUsed = (pageCnt - freeCnt) * pageSize; kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); kvm_getswapinfo(kd, &kswap, 1, 0); kvm_close(kd); virtualMemUsed += kswap.ksw_used * pageSize; return virtualMemUsed; #else return 0; #endif } uint64_t GetProcessMemoryUsed() { #ifdef SPP_WIN PROCESS_MEMORY_COUNTERS_EX pmc; GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast(&pmc), sizeof(pmc)); return static_cast(pmc.PrivateUsage); #elif defined(__linux__) auto parseLine = [](char* line)->int { auto i = strlen(line); while(*line < '0' || *line > '9') { line++; } line[i-3] = '\0'; i = atoi(line); return i; }; auto file = fopen("/proc/self/status", "r"); auto result = -1; char line[128]; while(fgets(line, 128, file) != nullptr) { if(strncmp(line, "VmSize:", 7) == 0) { result = parseLine(line); break; } } fclose(file); return static_cast(result) * 1024; #elif defined(__FreeBSD__) struct kinfo_proc info; size_t infoLen = sizeof(info); int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &infoLen, NULL, 0); return static_cast(info.ki_rssize * getpagesize()); #else return 0; #endif } uint64_t GetPhysicalMemory() { #ifdef SPP_WIN MEMORYSTATUSEX memInfo; memInfo.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&memInfo); return static_cast(memInfo.ullTotalPhys); #elif defined(__linux__) struct sysinfo memInfo; sysinfo(&memInfo); auto totalPhysMem = memInfo.totalram; totalPhysMem *= memInfo.mem_unit; return static_cast(totalPhysMem); #elif defined(__FreeBSD__) u_long physMem; size_t physMemLen = sizeof(physMem); int mib[] = { CTL_HW, HW_PHYSMEM }; sysctl(mib, sizeof(mib) / sizeof(*mib), &physMem, &physMemLen, NULL, 0); return physMem; #else return 0; #endif } } #endif // spp_memory_h_guard