@@ -159,14 +159,13 @@ static void detectAndroid(FFCPUResult* cpu)
159159#if __arm__ || __aarch64__
160160#include "cpu_arm.h"
161161
162- static void detectArmName (FILE * cpuinfo , FFCPUResult * cpu , uint32_t implId )
162+ static void detectArmName (FFstrbuf * cpuinfo , FFCPUResult * cpu , uint32_t implId )
163163{
164- FF_AUTO_FREE char * line = NULL ;
165- rewind (cpuinfo );
164+ char * line = NULL ;
166165 size_t len = 0 ;
167166 uint32_t lastPartId = UINT32_MAX ;
168167 uint32_t num = 0 ;
169- while (getline (& line , & len , cpuinfo ) != -1 )
168+ while (ffStrbufGetline (& line , & len , cpuinfo ))
170169 {
171170 if (!ffStrStartsWith (line , "CPU part\t: " )) continue ;
172171 uint32_t partId = (uint32_t ) strtoul (line + strlen ("CPU part\t: " ), NULL , 16 );
@@ -220,19 +219,18 @@ static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId)
220219#endif
221220
222221static const char * parseCpuInfo (
223- FF_MAYBE_UNUSED FILE * cpuinfo ,
224- FF_MAYBE_UNUSED FFCPUResult * cpu ,
225- FF_MAYBE_UNUSED FFstrbuf * cpuPhysicalId ,
222+ FFstrbuf * cpuinfo ,
223+ FFCPUResult * cpu ,
226224 FF_MAYBE_UNUSED FFstrbuf * physicalCoresBuffer ,
227225 FF_MAYBE_UNUSED FFstrbuf * cpuMHz ,
228226 FF_MAYBE_UNUSED FFstrbuf * cpuIsa ,
229227 FF_MAYBE_UNUSED FFstrbuf * cpuUarch ,
230228 FF_MAYBE_UNUSED FFstrbuf * cpuImplementer )
231229{
232- FF_AUTO_FREE char * line = NULL ;
230+ char * line = NULL ;
233231 size_t len = 0 ;
234232
235- while (getline (& line , & len , cpuinfo ) != -1 )
233+ while (ffStrbufGetline (& line , & len , cpuinfo ))
236234 {
237235 //Stop after reasonable information is acquired
238236 if ((* line == '\0' || * line == '\n' )
@@ -248,9 +246,6 @@ static const char* parseCpuInfo(
248246 #if !(__arm__ || __aarch64__ )
249247 (cpu -> name .length == 0 && ffParsePropLine (line , "model name :" , & cpu -> name )) ||
250248 (cpu -> vendor .length == 0 && ffParsePropLine (line , "vendor_id :" , & cpu -> vendor )) ||
251- //Is it cheaper to just parse every physical id or to check if it's already set to the parsed value?
252- (cpuPhysicalId -> length == 0 && ffParsePropLine (line , "physical id:" , cpuPhysicalId )) ||
253- (cpuPhysicalId -> length > 0 && ffParsePropLine (line , "physical id:" , cpuPhysicalId )) ||
254249 (physicalCoresBuffer -> length == 0 && ffParsePropLine (line , "cpu cores :" , physicalCoresBuffer )) ||
255250 (cpuMHz -> length == 0 && ffParsePropLine (line , "cpu MHz :" , cpuMHz )) ||
256251 #endif
@@ -469,28 +464,45 @@ FF_MAYBE_UNUSED static void detectArmSoc(FFCPUResult* cpu)
469464 }
470465}
471466
467+ FF_MAYBE_UNUSED static uint16_t getCPUCount (FFstrbuf * cpuinfo )
468+ {
469+ const char * p = cpuinfo -> chars ;
470+ uint64_t bits = 0 ;
471+
472+ while ((p = memmem (p , cpuinfo -> length - (uint32_t ) (p - cpuinfo -> chars ), "\nphysical id\t:" , strlen ("\nphysical id\t:" ))))
473+ {
474+ if (!p ) break ;
475+ p += strlen ("\nphysical id\t:" );
476+ char * pend ;
477+ uint32_t id = (uint32_t ) strtoul (p , & pend , 10 );
478+ p = pend ;
479+ bits |= 1 << id ;
480+ }
481+
482+ return (uint16_t ) __builtin_popcountll (bits );
483+ }
484+
472485const char * ffDetectCPUImpl (const FFCPUOptions * options , FFCPUResult * cpu )
473486{
474- FF_AUTO_CLOSE_FILE FILE * cpuinfo = fopen ( "/proc/cpuinfo" , "r" );
475- if ( cpuinfo == NULL )
476- return "fopen (\"/proc/cpuinfo\", \"r \") failed" ;
487+ FF_STRBUF_AUTO_DESTROY cpuinfo = ffStrbufCreateA ( PROC_FILE_BUFFSIZ );
488+ if (! ffReadFileBuffer ( "/proc/ cpuinfo" , & cpuinfo ) || cpuinfo . length == 0 )
489+ return "ffReadFileBuffer (\"/proc/cpuinfo\") failed" ;
477490
478491 cpu -> temperature = options -> temp ? detectCPUTemp () : FF_CPU_TEMP_UNSET ;
479492
480- FF_STRBUF_AUTO_DESTROY cpuPhysicalId = ffStrbufCreate ();
481493 FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate ();
482494 FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate ();
483495 FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate ();
484496 FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate ();
485497 FF_STRBUF_AUTO_DESTROY cpuImplementerStr = ffStrbufCreate ();
486498
487- const char * error = parseCpuInfo (cpuinfo , cpu , & cpuPhysicalId , & physicalCoresBuffer , & cpuMHz , & cpuIsa , & cpuUarch , & cpuImplementerStr );
499+ const char * error = parseCpuInfo (& cpuinfo , cpu , & physicalCoresBuffer , & cpuMHz , & cpuIsa , & cpuUarch , & cpuImplementerStr );
488500 if (error ) return error ;
489501
490502 cpu -> coresLogical = (uint16_t ) get_nprocs_conf ();
491503 cpu -> coresOnline = (uint16_t ) get_nprocs ();
492504 cpu -> coresPhysical = (uint16_t ) ffStrbufToUInt (& physicalCoresBuffer , cpu -> coresLogical );
493- cpu -> cpuCount = ( uint16_t ) ffStrbufToUInt ( & cpuPhysicalId , 1 ) + 1 ; //Assuming at least 1 CPU is present otherwise we wouldn't get this far
505+ cpu -> cpuCount = getCPUCount ( & cpuinfo );
494506
495507 // Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
496508 ffCPUDetectSpeedByCpuid (cpu );
@@ -525,7 +537,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
525537 #endif
526538
527539 if (cpu -> name .length == 0 )
528- detectArmName (cpuinfo , cpu , cpuImplementer );
540+ detectArmName (& cpuinfo , cpu , cpuImplementer );
529541 #endif
530542
531543 return NULL ;
0 commit comments