/ src / common / memory_detect.cpp
memory_detect.cpp
 1  // Copyright 2020 yuzu Emulator Project
 2  // Licensed under GPLv2 or any later version
 3  // Refer to the license.txt file included.
 4  
 5  #ifdef _WIN32
 6  #include <windows.h>
 7  // Depends on <windows.h> coming first
 8  #include <sysinfoapi.h>
 9  #else
10  #include <sys/types.h>
11  #include <unistd.h>
12  #if defined(__APPLE__) || defined(__FreeBSD__)
13  #include <sys/sysctl.h>
14  #elif defined(__linux__)
15  #include <sys/sysinfo.h>
16  #endif
17  #endif
18  
19  #include "common/memory_detect.h"
20  
21  namespace Common {
22  
23  // Detects the RAM and Swapfile sizes
24  const MemoryInfo GetMemInfo() {
25      MemoryInfo mem_info{};
26  
27  #ifdef _WIN32
28      MEMORYSTATUSEX memorystatus;
29      memorystatus.dwLength = sizeof(memorystatus);
30      GlobalMemoryStatusEx(&memorystatus);
31      mem_info.total_physical_memory = memorystatus.ullTotalPhys;
32      mem_info.total_swap_memory = memorystatus.ullTotalPageFile - mem_info.total_physical_memory;
33  #elif defined(__APPLE__)
34      u64 ramsize;
35      struct xsw_usage vmusage;
36      std::size_t sizeof_ramsize = sizeof(ramsize);
37      std::size_t sizeof_vmusage = sizeof(vmusage);
38      // hw and vm are defined in sysctl.h
39      // https://github.com/apple/darwin-xnu/blob/master/bsd/sys/sysctl.h#L471
40      // sysctlbyname(const char *, void *, size_t *, void *, size_t);
41      sysctlbyname("hw.memsize", &ramsize, &sizeof_ramsize, nullptr, 0);
42      sysctlbyname("vm.swapusage", &vmusage, &sizeof_vmusage, nullptr, 0);
43      mem_info.total_physical_memory = ramsize;
44      mem_info.total_swap_memory = vmusage.xsu_total;
45  #elif defined(__FreeBSD__)
46      u_long physmem, swap_total;
47      std::size_t sizeof_u_long = sizeof(u_long);
48      // sysctlbyname(const char *, void *, size_t *, const void *, size_t);
49      sysctlbyname("hw.physmem", &physmem, &sizeof_u_long, nullptr, 0);
50      sysctlbyname("vm.swap_total", &swap_total, &sizeof_u_long, nullptr, 0);
51      mem_info.total_physical_memory = physmem;
52      mem_info.total_swap_memory = swap_total;
53  #elif defined(__linux__)
54      struct sysinfo meminfo;
55      sysinfo(&meminfo);
56      mem_info.total_physical_memory = meminfo.totalram;
57      mem_info.total_swap_memory = meminfo.totalswap;
58  #else
59      mem_info.total_physical_memory = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGE_SIZE);
60      mem_info.total_swap_memory = 0;
61  #endif
62  
63      return mem_info;
64  }
65  
66  u64 GetPageSize() {
67  #ifdef _WIN32
68      SYSTEM_INFO info;
69      ::GetSystemInfo(&info);
70      return static_cast<u64>(info.dwPageSize);
71  #else
72      return static_cast<u64>(sysconf(_SC_PAGESIZE));
73  #endif
74  }
75  
76  } // namespace Common