Skip to content

Commit 1279bbc

Browse files
committed
CPU (Linux): rework cpuinfo parsing
1 parent 4e9fecc commit 1279bbc

File tree

1 file changed

+123
-80
lines changed

1 file changed

+123
-80
lines changed

src/detection/cpu/cpu_linux.c

+123-80
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,7 @@ static const char* parseCpuInfo(
283283
while(ffStrbufGetline(&line, &len, cpuinfo))
284284
{
285285
//Stop after reasonable information is acquired
286-
if((*line == '\0' || *line == '\n')
287-
#if __arm__ || __aarch64__ || __loongarch__
288-
&& cpu->name.length > 0 // #1202 #1204
289-
#endif
290-
)
286+
if((*line == '\0' || *line == '\n') && cpu->name.length > 0)
291287
{
292288
ffStrbufGetlineRestore(&line, &len, cpuinfo);
293289
break;
@@ -296,28 +292,37 @@ static const char* parseCpuInfo(
296292
(void)(
297293
// arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful.
298294
// "Hardware" should always be used in this case
299-
#if !(__arm__ || __aarch64__)
295+
#if __x86_64__ || __i386__
300296
(cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) ||
301297
(cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) ||
302298
(physicalCoresBuffer->length == 0 && ffParsePropLine(line, "cpu cores :", physicalCoresBuffer)) ||
303299
(cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) ||
304300
#endif
305301

306-
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
307-
(cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) ||
308-
(cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) ||
309-
#endif
310-
311302
#if __arm__ || __aarch64__
312303
(cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) ||
313304
(cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices
314305
#endif
306+
315307
#if __powerpc__ || __powerpc
308+
(cpuMHz->length == 0 && ffParsePropLine(line, "clock :", &cpuMHz)) || //For POWER
316309
(cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER
317310
#endif
318-
#if __mips__
311+
312+
#if __mips__ || __mips
319313
(cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS
320314
#endif
315+
316+
#if __loongarch__
317+
(cpu->name.length == 0 && ffParsePropLine(line, "Model Name :", &cpu->name)) ||
318+
(cpuMHz->length == 0 && ffParsePropLine(line, "CPU MHz :", cpuMHz)) ||
319+
#endif
320+
321+
#if __riscv__ || __loongarch__
322+
(cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) ||
323+
(cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) ||
324+
#endif
325+
321326
false
322327
);
323328
}
@@ -414,6 +419,59 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options)
414419
return true;
415420
}
416421

422+
#if __i386__ || __x86_64__
423+
424+
FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
425+
{
426+
const char* p = cpuinfo->chars;
427+
uint64_t low = 0, high = 0;
428+
429+
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:"))))
430+
{
431+
if (!p) break;
432+
p += strlen("\nphysical id\t:");
433+
char* pend;
434+
unsigned long id = strtoul(p, &pend, 10);
435+
if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist?
436+
high |= 1 << (id - 64);
437+
else
438+
low |= 1 << id;
439+
p = pend;
440+
}
441+
442+
return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high));
443+
}
444+
445+
FF_MAYBE_UNUSED static const char* detectCPUX86(const FFCPUOptions* options, FFCPUResult* cpu)
446+
{
447+
FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ);
448+
if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0)
449+
return "ffReadFileBuffer(\"/proc/cpuinfo\") failed";
450+
451+
FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate();
452+
FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate();
453+
const char* error = parseCpuInfo(&cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, NULL,NULL, NULL);
454+
if (error) return error;
455+
456+
cpu->coresLogical = (uint16_t) get_nprocs_conf();
457+
cpu->coresOnline = (uint16_t) get_nprocs();
458+
cpu->packages = getPackageCount(&cpuinfo);
459+
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, 0); // physical cores in single package
460+
if (cpu->coresPhysical == 0)
461+
cpu->coresPhysical = cpu->coresLogical;
462+
else if (cpu->packages > 1)
463+
cpu->coresPhysical *= cpu->packages;
464+
465+
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
466+
ffCPUDetectSpeedByCpuid(cpu);
467+
if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0)
468+
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
469+
470+
return NULL;
471+
}
472+
473+
#else
474+
417475
FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
418476
{
419477
// Always use the last part of the ISA string. Ref: #590 #1204
@@ -517,89 +575,74 @@ FF_MAYBE_UNUSED static void detectSocName(FFCPUResult* cpu)
517575
}
518576
}
519577

520-
FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
521-
{
522-
const char* p = cpuinfo->chars;
523-
uint64_t low = 0, high = 0;
524-
525-
while ((p = memmem(p, cpuinfo->length - (uint32_t) (p - cpuinfo->chars), "\nphysical id\t:", strlen("\nphysical id\t:"))))
526-
{
527-
if (!p) break;
528-
p += strlen("\nphysical id\t:");
529-
char* pend;
530-
unsigned long id = strtoul(p, &pend, 10);
531-
if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist?
532-
high |= 1 << (id - 64);
533-
else
534-
low |= 1 << id;
535-
p = pend;
536-
}
537-
538-
return (uint16_t) (__builtin_popcountll(low) + __builtin_popcountll(high));
539-
}
540-
541-
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
578+
FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, FFCPUResult* cpu)
542579
{
543-
FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ);
544-
if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0)
545-
return "ffReadFileBuffer(\"/proc/cpuinfo\") failed";
546-
547-
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
548-
549-
FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate();
550-
FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate();
551-
FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate();
552-
FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate();
553-
FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate();
554-
555-
const char* error = parseCpuInfo(&cpuinfo, cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
556-
if (error) return error;
557-
558-
cpu->coresLogical = (uint16_t) get_nprocs_conf();
580+
cpu->coresPhysical = cpu->coresLogical = (uint16_t) get_nprocs_conf();
559581
cpu->coresOnline = (uint16_t) get_nprocs();
560-
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
561-
#if __x86_64__ || __i386__
562-
cpu->packages = getPackageCount(&cpuinfo);
563-
if (cpu->packages > 1)
564-
cpu->coresPhysical *= cpu->packages; // https://github.com/hykilpikonna/hyfetch/issues/374#issuecomment-2571578914
565-
#endif
566-
567-
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
568-
ffCPUDetectSpeedByCpuid(cpu);
569-
if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0)
570-
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
571582

572583
#if __ANDROID__
573584
detectAndroid(cpu);
574-
#elif !(__x86_64__ || __i386__)
585+
#else
575586
detectSocName(cpu);
576587
#endif
577588

578-
#if __arm__ || __aarch64__
579-
uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16);
580-
ffStrbufSetStatic(&cpu->vendor, hwImplId2Vendor(cpuImplementer));
589+
detectFrequency(cpu, options);
581590

582-
if (cpu->name.length == 0)
583-
detectArmName(&cpuinfo, cpu, cpuImplementer);
584-
#elif !(__x86_64__ || __i386__)
585591
if (cpu->name.length == 0)
586592
{
587-
if(cpuUarch.length > 0)
588-
{
589-
if(cpu->name.length > 0)
590-
ffStrbufAppendC(&cpu->name, ' ');
591-
ffStrbufAppend(&cpu->name, &cpuUarch);
592-
}
593+
FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA(PROC_FILE_BUFFSIZ);
594+
if (!ffReadFileBuffer("/proc/cpuinfo", &cpuinfo) || cpuinfo.length == 0)
595+
return "ffReadFileBuffer(\"/proc/cpuinfo\") failed";
596+
597+
FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate();
598+
FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate();
599+
FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate();
600+
FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate();
601+
602+
const char* error = parseCpuInfo(&cpuinfo, cpu, NULL, &cpuMHz, &cpuIsa, &cpuUarch, &cpuImplementerStr);
603+
if (error) return error;
604+
605+
if (cpu->frequencyBase == 0)
606+
cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0);
607+
608+
#if __arm__ || __aarch64__
609+
uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16);
610+
ffStrbufSetStatic(&cpu->vendor, hwImplId2Vendor(cpuImplementer));
593611

594-
if(cpuIsa.length > 0)
612+
if (cpu->name.length == 0)
613+
detectArmName(&cpuinfo, cpu, cpuImplementer);
614+
#elif __riscv__ || __riscv
615+
if (cpu->name.length == 0)
595616
{
596-
parseIsa(&cpuIsa);
597-
if(cpu->name.length > 0)
598-
ffStrbufAppendC(&cpu->name, ' ');
599-
ffStrbufAppend(&cpu->name, &cpuIsa);
617+
if(cpuUarch.length > 0)
618+
{
619+
if(cpu->name.length > 0)
620+
ffStrbufAppendC(&cpu->name, ' ');
621+
ffStrbufAppend(&cpu->name, &cpuUarch);
622+
}
623+
624+
if(cpuIsa.length > 0)
625+
{
626+
parseIsa(&cpuIsa);
627+
if(cpu->name.length > 0)
628+
ffStrbufAppendC(&cpu->name, ' ');
629+
ffStrbufAppend(&cpu->name, &cpuIsa);
630+
}
600631
}
632+
#endif
601633
}
602-
#endif
603634

604635
return NULL;
605636
}
637+
#endif
638+
639+
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
640+
{
641+
cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET;
642+
643+
#if __x86_64__ || __i386__
644+
return detectCPUX86(options, cpu);
645+
#else
646+
return detectCPUOthers(options, cpu);
647+
#endif
648+
}

0 commit comments

Comments
 (0)