From 1d21d0287858d328b2ba7cceb0bed457ce3ade1b Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 7 Feb 2025 10:02:26 +0800 Subject: [PATCH] CPU (Linux): support physical core count and package count detection on loongarch --- src/detection/cpu/cpu_linux.c | 38 +++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 4ff2524d6..cca85815d 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -10,6 +10,8 @@ #include #include +#define FF_CPUINFO_PATH "/proc/cpuinfo" + static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer) { //https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface @@ -437,8 +439,8 @@ FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo) FF_MAYBE_UNUSED static const char* detectCPUX86(const FFCPUOptions* options, FFCPUResult* cpu) { FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ); - if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0) - return "ffReadFileBuffer(\"/proc/cpuinfo\") failed"; + if (!ffReadFileBuffer(FF_CPUINFO_PATH, &cpuinfo) || cpuinfo.length == 0) + return "ffReadFileBuffer(\"" FF_CPUINFO_PATH "\") failed"; FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate(); FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); @@ -567,6 +569,30 @@ FF_MAYBE_UNUSED static void detectSocName(FFCPUResult* cpu) } } +#ifdef __loongarch__ +FF_MAYBE_UNUSED static uint16_t getLoongarchPropCount(FFstrbuf* cpuinfo, const char* key) +{ + const char* p = cpuinfo->chars; + uint64_t low = 0, high = 0; + uint32_t keylen = (uint32_t) strlen(key); + + while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), key, keylen))) + { + if (!p) break; + p += keylen; + char* pend; + unsigned long id = strtoul(p, &pend, 10); + if (__builtin_expect(id > 64, false)) + high |= 1 << (id - 64); + else + low |= 1 << id; + p = pend; + } + + return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high)); +} +#endif + FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, FFCPUResult* cpu) { cpu->coresPhysical = cpu->coresLogical = (uint16_t) get_nprocs_conf(); @@ -583,8 +609,8 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, if (cpu->name.length == 0) { FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ); - if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0) - return "ffReadFileBuffer(\"/proc/cpuinfo\") failed"; + if (!ffReadFileBuffer(FF_CPUINFO_PATH, &cpuinfo) || cpuinfo.length == 0) + return "ffReadFileBuffer(\"" FF_CPUINFO_PATH "\") failed"; FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate(); @@ -621,6 +647,10 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, ffStrbufAppend(&cpu->name, &cpuIsa); } } + #elif __loongarch__ + cpu->packages = getLoongarchPropCount(&cpuinfo, "\npackage\t\t\t:"); + cpu->coresPhysical = getLoongarchPropCount(&cpuinfo, "\ncore\t\t\t:"); + if (cpu->packages > 1) cpu->coresPhysical *= cpu->packages; #endif }