memory_detect.cpp 2.3 KB

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