mempressure.cpp raw

   1  // Copyright (c) 2023-present The Limenka Knots developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #include <limenka-build-config.h> // IWYU pragma: keep
   6  
   7  #include <util/mempressure.h>
   8  
   9  #include <logging.h>
  10  #include <util/byte_units.h>
  11  
  12  #ifdef HAVE_LINUX_SYSINFO
  13  #include <sys/sysinfo.h>
  14  #endif
  15  #ifdef WIN32
  16  #include <windows.h>
  17  #endif
  18  
  19  #include <cstddef>
  20  #include <cstdint>
  21  
  22  size_t g_low_memory_threshold{0};
  23  
  24  bool SystemNeedsMemoryReleased()
  25  {
  26      if (g_low_memory_threshold <= 0) {
  27          // Intentionally bypass other metrics when disabled entirely
  28          return false;
  29      }
  30  #ifdef WIN32
  31      MEMORYSTATUSEX mem_status;
  32      mem_status.dwLength = sizeof(mem_status);
  33      if (GlobalMemoryStatusEx(&mem_status)) {
  34          if (mem_status.dwMemoryLoad >= 99 ||
  35              mem_status.ullAvailPhys < g_low_memory_threshold ||
  36              mem_status.ullAvailVirtual < g_low_memory_threshold) {
  37              LogPrintf("%s: YES: %s%% memory load; %s available physical memory; %s available virtual memory\n", __func__, int(mem_status.dwMemoryLoad), size_t(mem_status.ullAvailPhys), size_t(mem_status.ullAvailVirtual));
  38              return true;
  39          }
  40      }
  41  #endif
  42  #ifdef HAVE_LINUX_SYSINFO
  43      struct sysinfo sys_info;
  44      if (!sysinfo(&sys_info)) {
  45          // Explicitly 64-bit in case of 32-bit userspace on 64-bit kernel
  46          const uint64_t free_ram = uint64_t(sys_info.freeram) * sys_info.mem_unit;
  47          const uint64_t buffer_ram = uint64_t(sys_info.bufferram) * sys_info.mem_unit;
  48          if (free_ram + buffer_ram < g_low_memory_threshold) {
  49              LogPrintf("%s: YES: %s free RAM + %s buffer RAM\n", __func__, free_ram, buffer_ram);
  50              return true;
  51          }
  52      }
  53  #endif
  54      // NOTE: sysconf(_SC_AVPHYS_PAGES) doesn't account for caches on at least Linux, so not safe to use here
  55      return false;
  56  }
  57