@@ -619,19 +619,14 @@ static const char* parseCpuInfo(
619619 return NULL ;
620620}
621621
622- static uint32_t getFrequency (FFstrbuf * basePath , const char * cpuinfoFileName , const char * scalingFileName , FFstrbuf * buffer ) {
623- uint32_t baseLen = basePath -> length ;
624- ffStrbufAppendS (basePath , cpuinfoFileName );
625- bool ok = ffReadFileBuffer (basePath -> chars , buffer );
626- ffStrbufSubstrBefore (basePath , baseLen );
622+ static uint32_t getFrequency (int policyFd , const char * cpuinfoFileName , const char * scalingFileName , FFstrbuf * buffer ) {
623+ bool ok = ffReadFileBufferRelative (policyFd , cpuinfoFileName , buffer );
627624 if (ok ) {
628625 return (uint32_t ) (ffStrbufToUInt (buffer , 0 ) / 1000 );
629626 }
630627
631628 if (scalingFileName ) {
632- ffStrbufAppendS (basePath , scalingFileName );
633- ok = ffReadFileBuffer (basePath -> chars , buffer );
634- ffStrbufSubstrBefore (basePath , baseLen );
629+ ok = ffReadFileBufferRelative (policyFd , scalingFileName , buffer );
635630 if (ok ) {
636631 return (uint32_t ) (ffStrbufToUInt (buffer , 0 ) / 1000 );
637632 }
@@ -640,55 +635,38 @@ static uint32_t getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, co
640635 return 0 ;
641636}
642637
643- static uint8_t getNumCores (FFstrbuf * basePath , FFstrbuf * buffer ) {
644- uint32_t baseLen = basePath -> length ;
645- ffStrbufAppendS (basePath , "/affected_cpus" );
646- bool ok = ffReadFileBuffer (basePath -> chars , buffer );
647- ffStrbufSubstrBefore (basePath , baseLen );
648- if (ok ) {
649- return (uint8_t ) (ffStrbufCountC (buffer , ' ' ) + 1 );
650- }
651-
652- ffStrbufAppendS (basePath , "/related_cpus" );
653- ok = ffReadFileBuffer (basePath -> chars , buffer );
654- ffStrbufSubstrBefore (basePath , baseLen );
655- if (ok ) {
656- return (uint8_t ) (ffStrbufCountC (buffer , ' ' ) + 1 );
657- }
658-
659- return 0 ;
660- }
661-
662638static bool detectFrequency (FFCPUResult * cpu , const FFCPUOptions * options ) {
663- FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS ( "/sys/devices/system/cpu/cpufreq/" ) ;
664- FF_AUTO_CLOSE_DIR DIR * dir = opendir (path . chars );
639+ const char * basePath = "/sys/devices/system/cpu/cpufreq/" ;
640+ FF_AUTO_CLOSE_DIR DIR * dir = opendir (basePath );
665641 if (!dir ) {
666642 return false;
667643 }
644+ int freqFd = dirfd (dir );
668645
669646 FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate ();
670- uint32_t baseLen = path .length ;
671647
672648 struct dirent * entry ;
673649 while ((entry = readdir (dir )) != NULL ) {
674650 if (ffStrStartsWith (entry -> d_name , "policy" ) && ffCharIsDigit (entry -> d_name [strlen ("policy" )])) {
675- ffStrbufAppendS (& path , entry -> d_name );
651+ FF_AUTO_CLOSE_FD int policyFd = openat (freqFd , entry -> d_name , O_RDONLY | O_DIRECTORY | O_CLOEXEC | O_PATH );
652+ if (policyFd < 0 ) {
653+ continue ;
654+ }
676655
677- uint32_t fmax = getFrequency (& path , "/ cpuinfo_max_freq" , "/ scaling_max_freq" , & buffer );
656+ uint32_t fmax = getFrequency (policyFd , "cpuinfo_max_freq" , "scaling_max_freq" , & buffer );
678657 if (fmax == 0 ) {
679658 continue ;
680659 }
681660
682661 if (cpu -> frequencyMax >= fmax ) {
683662 if (!options -> showPeCoreCount ) {
684- ffStrbufSubstrBefore (& path , baseLen );
685663 continue ;
686664 }
687665 } else {
688666 cpu -> frequencyMax = fmax ;
689667 }
690668
691- uint32_t fbase = getFrequency (& path , "/ base_frequency" , NULL , & buffer );
669+ uint32_t fbase = getFrequency (policyFd , "base_frequency" , NULL , & buffer );
692670 if (fbase > 0 ) {
693671 cpu -> frequencyBase = cpu -> frequencyBase > fbase ? cpu -> frequencyBase : fbase ;
694672 }
@@ -702,9 +680,10 @@ static bool detectFrequency(FFCPUResult* cpu, const FFCPUOptions* options) {
702680 if (cpu -> coreTypes [ifreq ].freq == 0 ) {
703681 cpu -> coreTypes [ifreq ].freq = freq ;
704682 }
705- cpu -> coreTypes [ifreq ].count += getNumCores (& path , & buffer );
683+ if (ffReadFileBufferRelative (policyFd , "affected_cpus" , & buffer )) {
684+ cpu -> coreTypes [ifreq ].count += ffStrbufCountC (& buffer , ' ' ) + 1 ;
685+ }
706686 }
707- ffStrbufSubstrBefore (& path , baseLen );
708687 }
709688 }
710689 return true;
@@ -773,6 +752,7 @@ static const char* detectPhysicalCores(FFCPUResult* cpu) {
773752
774753 FF_AUTO_CLOSE_DIR DIR * dir = fdopendir (dfd );
775754 if (!dir ) {
755+ close (dfd );
776756 return "fdopendir(dfd) failed" ;
777757 }
778758
@@ -785,7 +765,7 @@ static const char* detectPhysicalCores(FFCPUResult* cpu) {
785765 continue ;
786766 }
787767
788- FF_AUTO_CLOSE_FD int cpuxfd = openat (dirfd (dir ), entry -> d_name , O_RDONLY | O_DIRECTORY );
768+ FF_AUTO_CLOSE_FD int cpuxfd = openat (dirfd (dir ), entry -> d_name , O_RDONLY | O_DIRECTORY | O_CLOEXEC );
789769 if (cpuxfd < 0 ) {
790770 continue ;
791771 }
@@ -801,42 +781,36 @@ static const char* detectPhysicalCores(FFCPUResult* cpu) {
801781 unsigned long long id = strtoul (buf , NULL , 10 );
802782 if (__builtin_expect (id > 64 , false)) { // Do 129-socket boards exist?
803783 pkgHigh |= 1ULL << (id - 64 );
804- } else {
784+ } else if ( __builtin_expect ( id <= 64 , true)) {
805785 pkgLow |= 1ULL << id ;
806786 }
807787 }
808788
809789 // Check if the directory contains a file named "topology/core_cpus_list"
810- // that lists the physical cores in the package .
790+ // that lists the logical cores in the same physical core .
811791
812792 len = ffReadFileDataRelative (cpuxfd , "topology/core_cpus_list" , sizeof (buf ) - 1 , buf );
813793 if (len > 0 ) {
814- buf [len ] = '\0' ; // low-high or low
815-
816- for (const char * p = buf ; * p ;) {
817- char * pend ;
818- uint32_t coreId = (uint32_t ) strtoul (p , & pend , 10 );
819- if (pend == p ) {
820- break ;
821- }
794+ buf [len ] = '\0' ; // low[-high, low-high, ...]
822795
823- bool found = false;
824- FF_LIST_FOR_EACH (uint32_t , id , cpuList ) {
825- if (* id == coreId ) {
826- // This core is already counted
827- found = true;
828- break ;
829- }
830- }
831- if (!found ) {
832- * FF_LIST_ADD (uint32_t , cpuList ) = coreId ;
833- }
796+ char * pend ;
797+ // We assume that the different physical cores exposes different logical core ids,
798+ // so that the first `low` is always different between different physical cores.
799+ uint32_t coreId = (uint32_t ) strtoul (buf , & pend , 10 );
800+ if (pend == buf ) {
801+ break ;
802+ }
834803
835- p = strchr (pend , ',' );
836- if (!p ) {
804+ bool found = false;
805+ FF_LIST_FOR_EACH (uint32_t , id , cpuList ) {
806+ if (* id == coreId ) {
807+ // This core is already counted
808+ found = true;
837809 break ;
838810 }
839- ++ p ;
811+ }
812+ if (!found ) {
813+ * FF_LIST_ADD (uint32_t , cpuList ) = coreId ;
840814 }
841815 }
842816 }
0 commit comments