summaryrefslogtreecommitdiffstats
path: root/src/detection/cpucache/cpucache_apple.c
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/cpucache/cpucache_apple.c
Add the files
Diffstat (limited to 'src/detection/cpucache/cpucache_apple.c')
-rw-r--r--src/detection/cpucache/cpucache_apple.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/detection/cpucache/cpucache_apple.c b/src/detection/cpucache/cpucache_apple.c
new file mode 100644
index 0000000..3d1562c
--- /dev/null
+++ b/src/detection/cpucache/cpucache_apple.c
@@ -0,0 +1,63 @@
+#include "cpucache.h"
+#include "common/sysctl.h"
+#include "common/strutil.h"
+
+const char* ffDetectCPUCache(FFCPUCacheResult* result) {
+ // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_system_capabilities#3901385
+ uint32_t nPerfLevels = (uint32_t) ffSysctlGetInt("hw.nperflevels", 0);
+ if (nPerfLevels <= 0) {
+ return "sysctl(hw.nperflevels) failed";
+ }
+
+ // macOS provides the global system cache line size
+ uint32_t lineSize = (uint32_t) ffSysctlGetInt64("hw.cachelinesize", 0);
+
+ char sysctlKey[128] = "hw.perflevelN.";
+ char* pNum = sysctlKey + strlen("hw.perflevel");
+ char* pSubkey = sysctlKey + strlen("hw.perflevelN.");
+ const size_t lenLeft = ARRAY_SIZE(sysctlKey) - strlen("hw.perflevelN.");
+
+ for (uint32_t i = 0; i < nPerfLevels; ++i) {
+ *pNum = (char) ('0' + i);
+
+ ffStrCopy(pSubkey, "physicalcpu", lenLeft);
+ uint32_t ncpu = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
+ if (ncpu <= 0) {
+ continue;
+ }
+
+ ffStrCopy(pSubkey, "l1icachesize", lenLeft);
+ uint32_t size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
+ if (size) {
+ ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_INSTRUCTION)->num = ncpu;
+ }
+
+ ffStrCopy(pSubkey, "l1dcachesize", lenLeft);
+ size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
+ if (size) {
+ ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_DATA)->num = ncpu;
+ }
+
+ ffStrCopy(pSubkey, "l2cachesize", lenLeft);
+ size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
+ if (size) {
+ ffStrCopy(pSubkey, "cpusperl2", lenLeft);
+ uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
+ if (cpuSper) {
+ ffCPUCacheAddItem(result, 2, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper;
+ }
+ }
+
+ ffStrCopy(pSubkey, "l3cachesize", lenLeft);
+ size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
+ if (size) {
+ ffStrCopy(pSubkey, "cpusperl3", lenLeft);
+ uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
+ if (cpuSper) {
+ ffCPUCacheAddItem(result, 3, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper;
+ }
+ }
+ }
+
+ return NULL;
+}