1 #if !defined(spp_memory_h_guard) 2 #define spp_memory_h_guard 3 4 #include <cstdint> 5 #include <cstring> 6 #include <cstdlib> 7 8 #if defined(_WIN32) || defined( __CYGWIN__) 9 #define SPP_WIN 10 #endif 11 12 #ifdef SPP_WIN 13 #include <windows.h> 14 #include <Psapi.h> 15 #undef min 16 #undef max 17 #elif defined(__linux__) 18 #include <sys/types.h> 19 #include <sys/sysinfo.h> 20 #elif defined(__FreeBSD__) 21 #include <paths.h> 22 #include <fcntl.h> 23 #include <kvm.h> 24 #include <unistd.h> 25 #include <sys/sysctl.h> 26 #include <sys/user.h> 27 #endif 28 29 namespace spp 30 { GetSystemMemory()31 uint64_t GetSystemMemory() 32 { 33 #ifdef SPP_WIN 34 MEMORYSTATUSEX memInfo; 35 memInfo.dwLength = sizeof(MEMORYSTATUSEX); 36 GlobalMemoryStatusEx(&memInfo); 37 return static_cast<uint64_t>(memInfo.ullTotalPageFile); 38 #elif defined(__linux__) 39 struct sysinfo memInfo; 40 sysinfo (&memInfo); 41 auto totalVirtualMem = memInfo.totalram; 42 43 totalVirtualMem += memInfo.totalswap; 44 totalVirtualMem *= memInfo.mem_unit; 45 return static_cast<uint64_t>(totalVirtualMem); 46 #elif defined(__FreeBSD__) 47 kvm_t *kd; 48 u_int pageCnt; 49 size_t pageCntLen = sizeof(pageCnt); 50 u_int pageSize; 51 struct kvm_swap kswap; 52 uint64_t totalVirtualMem; 53 54 pageSize = static_cast<u_int>(getpagesize()); 55 56 sysctlbyname("vm.stats.vm.v_page_count", &pageCnt, &pageCntLen, NULL, 0); 57 totalVirtualMem = pageCnt * pageSize; 58 59 kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); 60 kvm_getswapinfo(kd, &kswap, 1, 0); 61 kvm_close(kd); 62 totalVirtualMem += kswap.ksw_total * pageSize; 63 64 return totalVirtualMem; 65 #else 66 return 0; 67 #endif 68 } 69 GetTotalMemoryUsed()70 uint64_t GetTotalMemoryUsed() 71 { 72 #ifdef SPP_WIN 73 MEMORYSTATUSEX memInfo; 74 memInfo.dwLength = sizeof(MEMORYSTATUSEX); 75 GlobalMemoryStatusEx(&memInfo); 76 return static_cast<uint64_t>(memInfo.ullTotalPageFile - memInfo.ullAvailPageFile); 77 #elif defined(__linux__) 78 struct sysinfo memInfo; 79 sysinfo(&memInfo); 80 auto virtualMemUsed = memInfo.totalram - memInfo.freeram; 81 82 virtualMemUsed += memInfo.totalswap - memInfo.freeswap; 83 virtualMemUsed *= memInfo.mem_unit; 84 85 return static_cast<uint64_t>(virtualMemUsed); 86 #elif defined(__FreeBSD__) 87 kvm_t *kd; 88 u_int pageSize; 89 u_int pageCnt, freeCnt; 90 size_t pageCntLen = sizeof(pageCnt); 91 size_t freeCntLen = sizeof(freeCnt); 92 struct kvm_swap kswap; 93 uint64_t virtualMemUsed; 94 95 pageSize = static_cast<u_int>(getpagesize()); 96 97 sysctlbyname("vm.stats.vm.v_page_count", &pageCnt, &pageCntLen, NULL, 0); 98 sysctlbyname("vm.stats.vm.v_free_count", &freeCnt, &freeCntLen, NULL, 0); 99 virtualMemUsed = (pageCnt - freeCnt) * pageSize; 100 101 kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); 102 kvm_getswapinfo(kd, &kswap, 1, 0); 103 kvm_close(kd); 104 virtualMemUsed += kswap.ksw_used * pageSize; 105 106 return virtualMemUsed; 107 #else 108 return 0; 109 #endif 110 } 111 GetProcessMemoryUsed()112 uint64_t GetProcessMemoryUsed() 113 { 114 #ifdef SPP_WIN 115 PROCESS_MEMORY_COUNTERS_EX pmc; 116 GetProcessMemoryInfo(GetCurrentProcess(), reinterpret_cast<PPROCESS_MEMORY_COUNTERS>(&pmc), sizeof(pmc)); 117 return static_cast<uint64_t>(pmc.PrivateUsage); 118 #elif defined(__linux__) 119 auto parseLine = 120 [](char* line)->int 121 { 122 auto i = strlen(line); 123 124 while(*line < '0' || *line > '9') 125 { 126 line++; 127 } 128 129 line[i-3] = '\0'; 130 i = atoi(line); 131 return i; 132 }; 133 134 auto file = fopen("/proc/self/status", "r"); 135 auto result = -1; 136 char line[128]; 137 138 while(fgets(line, 128, file) != nullptr) 139 { 140 if(strncmp(line, "VmSize:", 7) == 0) 141 { 142 result = parseLine(line); 143 break; 144 } 145 } 146 147 fclose(file); 148 return static_cast<uint64_t>(result) * 1024; 149 #elif defined(__FreeBSD__) 150 struct kinfo_proc info; 151 size_t infoLen = sizeof(info); 152 int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; 153 154 sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &infoLen, NULL, 0); 155 #ifdef __DragonFly__ 156 return static_cast<uint64_t>(info.kp_vm_rssize * getpagesize()); 157 #else 158 return static_cast<uint64_t>(info.ki_rssize * getpagesize()); 159 #endif 160 #else 161 return 0; 162 #endif 163 } 164 GetPhysicalMemory()165 uint64_t GetPhysicalMemory() 166 { 167 #ifdef SPP_WIN 168 MEMORYSTATUSEX memInfo; 169 memInfo.dwLength = sizeof(MEMORYSTATUSEX); 170 GlobalMemoryStatusEx(&memInfo); 171 return static_cast<uint64_t>(memInfo.ullTotalPhys); 172 #elif defined(__linux__) 173 struct sysinfo memInfo; 174 sysinfo(&memInfo); 175 176 auto totalPhysMem = memInfo.totalram; 177 178 totalPhysMem *= memInfo.mem_unit; 179 return static_cast<uint64_t>(totalPhysMem); 180 #elif defined(__FreeBSD__) 181 u_long physMem; 182 size_t physMemLen = sizeof(physMem); 183 int mib[] = { CTL_HW, HW_PHYSMEM }; 184 185 sysctl(mib, sizeof(mib) / sizeof(*mib), &physMem, &physMemLen, NULL, 0); 186 return physMem; 187 #else 188 return 0; 189 #endif 190 } 191 192 } 193 194 #endif // spp_memory_h_guard 195