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