summaryrefslogtreecommitdiffstats
path: root/src/detection/memory
diff options
context:
space:
mode:
authorsumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
committersumuel <samuel@yakubos.org>2026-08-17 20:44:55 +0000
commit76424950e373d3b04ac3dd13019151bfba3e8423 (patch)
tree4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/memory
Add the files
Diffstat (limited to 'src/detection/memory')
-rw-r--r--src/detection/memory/memory.h11
-rw-r--r--src/detection/memory/memory_apple.c35
-rw-r--r--src/detection/memory/memory_bsd.c16
-rw-r--r--src/detection/memory/memory_haiku.c16
-rw-r--r--src/detection/memory/memory_linux.c62
-rw-r--r--src/detection/memory/memory_nbsd.c18
-rw-r--r--src/detection/memory/memory_nosupport.c5
-rw-r--r--src/detection/memory/memory_obsd.c18
-rw-r--r--src/detection/memory/memory_sunos.c9
-rw-r--r--src/detection/memory/memory_windows.c19
10 files changed, 209 insertions, 0 deletions
diff --git a/src/detection/memory/memory.h b/src/detection/memory/memory.h
new file mode 100644
index 0000000..1c23828
--- /dev/null
+++ b/src/detection/memory/memory.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "fastfetch.h"
+#include "modules/memory/option.h"
+
+typedef struct FFMemoryResult {
+ uint64_t bytesUsed;
+ uint64_t bytesTotal;
+} FFMemoryResult;
+
+const char* ffDetectMemory(FFMemoryResult* ram);
diff --git a/src/detection/memory/memory_apple.c b/src/detection/memory/memory_apple.c
new file mode 100644
index 0000000..6203949
--- /dev/null
+++ b/src/detection/memory/memory_apple.c
@@ -0,0 +1,35 @@
+#include "memory.h"
+#include "common/debug.h"
+
+#include <string.h>
+#include <mach/mach.h>
+#include <sys/sysctl.h>
+#include <unistd.h>
+
+const char* ffDetectMemory(FFMemoryResult* ram) {
+ size_t length = sizeof(ram->bytesTotal);
+
+#if FF_APPLE_MEMSIZE_USABLE
+ if (sysctlbyname("hw.memsize_usable", &ram->bytesTotal, &length, NULL, 0) != 0) {
+ return "Failed to read hw.memsize_usable";
+ }
+#else
+ if (sysctl((int[]) { CTL_HW, HW_MEMSIZE }, 2, &ram->bytesTotal, &length, NULL, 0) != 0) {
+ return "Failed to read hw.memsize";
+ }
+#endif
+
+ mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
+ vm_statistics64_data_t vmstat;
+ if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS) {
+ return "Failed to read host_statistics64";
+ }
+
+ // https://github.com/st3fan/osx-10.9/blob/34e34a6a539b5a822cda4074e56a7ced9b57da71/system_cmds-597.1.1/vm_stat.tproj/vm_stat.c#L139
+
+ uint64_t pagesFree = vmstat.free_count - vmstat.speculative_count;
+ uint64_t pagesFileBacked = vmstat.external_page_count; // Cached files
+ ram->bytesUsed = ram->bytesTotal - (pagesFree + pagesFileBacked) * instance.state.platform.sysinfo.pageSize;
+
+ return NULL;
+}
diff --git a/src/detection/memory/memory_bsd.c b/src/detection/memory/memory_bsd.c
new file mode 100644
index 0000000..f76f6b8
--- /dev/null
+++ b/src/detection/memory/memory_bsd.c
@@ -0,0 +1,16 @@
+#include "memory.h"
+#include "common/sysctl.h"
+
+const char* ffDetectMemory(FFMemoryResult* ram) {
+ size_t length = sizeof(ram->bytesTotal);
+ if (sysctl((int[]) { CTL_HW, HW_PHYSMEM }, 2, &ram->bytesTotal, &length, NULL, 0)) {
+ return "Failed to read hw.physmem";
+ }
+
+ // vm.stats.vm.* are int values
+ int32_t pagesFree = ffSysctlGetInt("vm.stats.vm.v_free_count", 0) + ffSysctlGetInt("vm.stats.vm.v_inactive_count", 0) + ffSysctlGetInt("vm.stats.vm.v_cache_count", 0);
+
+ ram->bytesUsed = ram->bytesTotal - (uint64_t) pagesFree * instance.state.platform.sysinfo.pageSize;
+
+ return NULL;
+}
diff --git a/src/detection/memory/memory_haiku.c b/src/detection/memory/memory_haiku.c
new file mode 100644
index 0000000..7888801
--- /dev/null
+++ b/src/detection/memory/memory_haiku.c
@@ -0,0 +1,16 @@
+#include "memory.h"
+
+#include <OS.h>
+
+const char* ffDetectMemory(FFMemoryResult* ram) {
+ system_info info;
+ if (get_system_info(&info) != B_OK) {
+ return "Error getting system info";
+ }
+
+ uint32_t pageSize = instance.state.platform.sysinfo.pageSize;
+ ram->bytesTotal = pageSize * info.max_pages;
+ ram->bytesUsed = pageSize * info.used_pages;
+
+ return NULL;
+}
diff --git a/src/detection/memory/memory_linux.c b/src/detection/memory/memory_linux.c
new file mode 100644
index 0000000..74d20a0
--- /dev/null
+++ b/src/detection/memory/memory_linux.c
@@ -0,0 +1,62 @@
+#include "memory.h"
+#include "common/io.h"
+#include "common/mallocHelper.h"
+
+#include <inttypes.h>
+
+const char* ffDetectMemory(FFMemoryResult* ram) {
+ char buf[PROC_FILE_BUFFSIZ];
+ ssize_t nRead = ffReadFileData("/proc/meminfo", ARRAY_SIZE(buf) - 1, buf);
+ if (nRead < 0) {
+ return "ffReadFileData(\"/proc/meminfo\", ARRAY_SIZE(buf)-1, buf)";
+ }
+ buf[nRead] = '\0';
+
+ uint64_t memTotal = 0,
+ memAvailable = 0,
+ shmem = 0,
+ memFree = 0,
+ buffers = 0,
+ cached = 0,
+ sReclaimable = 0;
+
+ char* token = NULL;
+ if ((token = strstr(buf, "MemTotal:")) != NULL) {
+ memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10);
+ } else {
+ return "MemTotal not found in /proc/meminfo";
+ }
+
+ if ((token = strstr(buf, "MemAvailable:")) != NULL) {
+ memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10);
+ }
+ if (memAvailable == 0 || memAvailable >= memTotal) // MemAvailable can be unreasonable. #1988
+ {
+ if ((token = strstr(buf, "MemFree:")) != NULL) {
+ memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
+ }
+
+ if ((token = strstr(buf, "Buffers:")) != NULL) {
+ buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
+ }
+
+ if ((token = strstr(buf, "Cached:")) != NULL) {
+ cached = strtoul(token + strlen("Cached:"), NULL, 10);
+ }
+
+ if ((token = strstr(buf, "Shmem:")) != NULL) {
+ shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
+ }
+
+ if ((token = strstr(buf, "SReclaimable:")) != NULL) {
+ sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
+ }
+
+ memAvailable = memFree + buffers + cached + sReclaimable - shmem;
+ }
+
+ ram->bytesTotal = memTotal * 1024lu;
+ ram->bytesUsed = (memTotal - memAvailable) * 1024lu;
+
+ return NULL;
+}
diff --git a/src/detection/memory/memory_nbsd.c b/src/detection/memory/memory_nbsd.c
new file mode 100644
index 0000000..ca09475
--- /dev/null
+++ b/src/detection/memory/memory_nbsd.c
@@ -0,0 +1,18 @@
+#include "memory.h"
+#include "common/sysctl.h"
+
+#include <sys/param.h>
+#include <uvm/uvm_extern.h>
+
+const char* ffDetectMemory(FFMemoryResult* ram) {
+ struct uvmexp_sysctl buf;
+ size_t length = sizeof(buf);
+ if (sysctl((int[]) { CTL_VM, VM_UVMEXP2 }, 2, &buf, &length, NULL, 0) < 0) {
+ return "sysctl(CTL_VM, VM_UVMEXP2) failed";
+ }
+
+ ram->bytesTotal = (uint64_t) buf.npages * instance.state.platform.sysinfo.pageSize;
+ ram->bytesUsed = ((uint64_t) buf.active + (uint64_t) buf.inactive + (uint64_t) buf.wired) * instance.state.platform.sysinfo.pageSize;
+
+ return NULL;
+}
diff --git a/src/detection/memory/memory_nosupport.c b/src/detection/memory/memory_nosupport.c
new file mode 100644
index 0000000..b44aaad
--- /dev/null
+++ b/src/detection/memory/memory_nosupport.c
@@ -0,0 +1,5 @@
+#include "memory.h"
+
+const char* ffDetectMemory(FF_A_UNUSED FFMemoryResult* ram) {
+ return "Not supported on this platform";
+}
diff --git a/src/detection/memory/memory_obsd.c b/src/detection/memory/memory_obsd.c
new file mode 100644
index 0000000..c6da087
--- /dev/null
+++ b/src/detection/memory/memory_obsd.c
@@ -0,0 +1,18 @@
+#include "memory.h"
+#include "common/sysctl.h"
+
+#include <sys/param.h>
+#include <uvm/uvm_extern.h>
+
+const char* ffDetectMemory(FFMemoryResult* ram) {
+ struct uvmexp buf;
+ size_t length = sizeof(buf);
+ if (sysctl((int[]) { CTL_VM, VM_UVMEXP }, 2, &buf, &length, NULL, 0) < 0) {
+ return "sysctl(CTL_VM, VM_UVMEXP) failed";
+ }
+
+ ram->bytesTotal = (uint64_t) buf.npages * instance.state.platform.sysinfo.pageSize;
+ ram->bytesUsed = ((uint64_t) buf.active + (uint64_t) buf.inactive + (uint64_t) buf.wired) * instance.state.platform.sysinfo.pageSize;
+
+ return NULL;
+}
diff --git a/src/detection/memory/memory_sunos.c b/src/detection/memory/memory_sunos.c
new file mode 100644
index 0000000..7dfdeab
--- /dev/null
+++ b/src/detection/memory/memory_sunos.c
@@ -0,0 +1,9 @@
+#include "memory.h"
+#include <unistd.h>
+
+const char* ffDetectMemory(FFMemoryResult* ram) {
+ ram->bytesTotal = (uint64_t) sysconf(_SC_PHYS_PAGES) * instance.state.platform.sysinfo.pageSize;
+ ram->bytesUsed = ram->bytesTotal - (uint64_t) sysconf(_SC_AVPHYS_PAGES) * instance.state.platform.sysinfo.pageSize;
+
+ return NULL;
+}
diff --git a/src/detection/memory/memory_windows.c b/src/detection/memory/memory_windows.c
new file mode 100644
index 0000000..779425d
--- /dev/null
+++ b/src/detection/memory/memory_windows.c
@@ -0,0 +1,19 @@
+#include "memory.h"
+
+#include <windows.h>
+
+const char* ffDetectMemory(FFMemoryResult* ram) {
+ MEMORYSTATUSEX statex = {
+ .dwLength = sizeof(statex),
+ };
+ // GlobalMemoryStatusEx() internally uses
+ // NtQuerySystemInformation(SystemBasicPerformanceInformation) in Win 7, and
+ // NtQuerySystemInformation(SystemMemoryUsageInformation) in Win 10
+ if (!GlobalMemoryStatusEx(&statex)) {
+ return "GlobalMemoryStatusEx() failed";
+ }
+
+ ram->bytesTotal = statex.ullTotalPhys;
+ ram->bytesUsed = statex.ullTotalPhys - statex.ullAvailPhys;
+ return NULL;
+}