master ohmu/fastfetch-openbsd / src / detection / cpucache / cpucache_apple.c
ohmu  ·  2026-10-15
 1#include "cpucache.h"
 2#include "common/debug.h"
 3#include "common/sysctl.h"
 4#include "common/strutil.h"
 5
 6const char* ffDetectCPUCache(FFCPUCacheResult* result) {
 7    // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_system_capabilities#3901385
 8    uint32_t nPerfLevels = (uint32_t) ffSysctlGetInt("hw.nperflevels", 0);
 9    if (nPerfLevels <= 0) {
10        FF_DEBUG("sysctl(hw.nperflevels) failed");
11        return "sysctl(hw.nperflevels) failed";
12    }
13
14    // macOS provides the global system cache line size
15    uint32_t lineSize = (uint32_t) ffSysctlGetInt64("hw.cachelinesize", 0);
16
17    char sysctlKey[128] = "hw.perflevelN.";
18    char* pNum = sysctlKey + strlen("hw.perflevel");
19    char* pSubkey = sysctlKey + strlen("hw.perflevelN.");
20    const size_t lenLeft = ARRAY_SIZE(sysctlKey) - strlen("hw.perflevelN.");
21
22    for (uint32_t i = 0; i < nPerfLevels; ++i) {
23        *pNum = (char) ('0' + i);
24
25        ffStrCopy(pSubkey, "physicalcpu", lenLeft);
26        uint32_t ncpu = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
27        if (ncpu <= 0) {
28            continue;
29        }
30
31        ffStrCopy(pSubkey, "l1icachesize", lenLeft);
32        uint32_t size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
33        if (size) {
34            ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_INSTRUCTION)->num = ncpu;
35        }
36
37        ffStrCopy(pSubkey, "l1dcachesize", lenLeft);
38        size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
39        if (size) {
40            ffCPUCacheAddItem(result, 1, size, lineSize, FF_CPU_CACHE_TYPE_DATA)->num = ncpu;
41        }
42
43        ffStrCopy(pSubkey, "l2cachesize", lenLeft);
44        size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
45        if (size) {
46            ffStrCopy(pSubkey, "cpusperl2", lenLeft);
47            uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
48            if (cpuSper) {
49                ffCPUCacheAddItem(result, 2, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper;
50            }
51        }
52
53        ffStrCopy(pSubkey, "l3cachesize", lenLeft);
54        size = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
55        if (size) {
56            ffStrCopy(pSubkey, "cpusperl3", lenLeft);
57            uint32_t cpuSper = (uint32_t) ffSysctlGetInt(sysctlKey, 0);
58            if (cpuSper) {
59                ffCPUCacheAddItem(result, 3, size, lineSize, FF_CPU_CACHE_TYPE_UNIFIED)->num = ncpu / cpuSper;
60            }
61        }
62    }
63
64    return nullptr;
65}