@@ -628,6 +628,8 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl
628
628
629
629
#elif LL_DARWIN
630
630
631
+ #include < CoreFoundation/CoreFoundation.h>
632
+ #include < IOKit/IOKitLib.h>
631
633
#include < mach/machine.h>
632
634
#include < sys/sysctl.h>
633
635
@@ -638,25 +640,66 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl
638
640
{
639
641
getCPUIDInfo ();
640
642
uint64_t frequency = getSysctlInt64 (" hw.cpufrequency" );
643
+ if (frequency == 0 ) // Attempt to query IO Services for pcore frequency
644
+ {
645
+ CFMutableDictionaryRef arm_io_matching = IOServiceMatching (" AppleARMIODevice" );
646
+ io_iterator_t iter;
647
+ kern_return_t ret = IOServiceGetMatchingServices (kIOMasterPortDefault , arm_io_matching, &iter);
648
+ if (ret == KERN_SUCCESS)
649
+ {
650
+ io_object_t obj;
651
+ while ((obj = IOIteratorNext (iter)))
652
+ {
653
+ io_name_t obj_class;
654
+ ret = IOObjectGetClass (obj, obj_class);
655
+ if (ret == KERN_SUCCESS)
656
+ {
657
+ io_name_t obj_name;
658
+ ret = IORegistryEntryGetName (obj, obj_name);
659
+ if (ret == KERN_SUCCESS)
660
+ {
661
+ if (strncmp (obj_name, " pmgr" , sizeof (obj_name)) == 0 )
662
+ {
663
+ CFTypeRef cfData = IORegistryEntryCreateCFProperty (obj, CFSTR (" voltage-states5-sram" ), kCFAllocatorDefault , 0 ); // pcore frequency
664
+ if (cfData)
665
+ {
666
+ CFIndex size = CFDataGetLength ((CFDataRef)cfData);
667
+ std::vector<U8> databuf (size);
668
+ CFDataGetBytes ((CFDataRef)cfData, CFRangeMake (0 , size), databuf.data ());
669
+
670
+ frequency = 0x00000000FFFFFFFF & ((databuf[size-5 ] << 24 ) | (databuf[size-6 ] << 16 ) | (databuf[size-7 ] << 8 ) | (databuf[size-8 ]));
671
+ CFRelease (cfData);
672
+ }
673
+ break ;
674
+ }
675
+ }
676
+ }
677
+ }
678
+ }
679
+ }
680
+ if (frequency == 0 ) // fallback to clockrate and tbfrequency
681
+ {
682
+ frequency = getSysctlClockrate () * getSysctlInt64 (" hw.tbfrequency" );
683
+ }
641
684
setInfo (eFrequency, (F64)frequency / (F64)1000000 );
642
685
}
643
686
644
- virtual ~LLProcessorInfoDarwinImpl () {}
687
+ virtual ~LLProcessorInfoDarwinImpl () = default ;
645
688
646
689
private:
647
690
int getSysctlInt (const char * name)
648
691
{
649
692
int result = 0 ;
650
693
size_t len = sizeof (int );
651
- int error = sysctlbyname (name, (void *)&result, &len, NULL , 0 );
694
+ int error = sysctlbyname (name, (void *)&result, &len, nullptr , 0 );
652
695
return error == -1 ? 0 : result;
653
696
}
654
697
655
698
uint64_t getSysctlInt64 (const char * name)
656
699
{
657
700
uint64_t value = 0 ;
658
701
size_t size = sizeof (value);
659
- int result = sysctlbyname (name, (void *)&value, &size, NULL , 0 );
702
+ int result = sysctlbyname (name, (void *)&value, &size, nullptr , 0 );
660
703
if ( result == 0 )
661
704
{
662
705
if ( size == sizeof ( uint64_t ) )
@@ -676,6 +719,14 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl
676
719
return result == -1 ? 0 : value;
677
720
}
678
721
722
+ uint64_t getSysctlClockrate ()
723
+ {
724
+ struct clockinfo clockrate{};
725
+ size_t size = sizeof (clockrate);
726
+ int error = sysctlbyname (" kern.clockrate" , &clockrate, &size, nullptr , 0 );
727
+ return error == -1 ? 0 : clockrate.hz ;
728
+ }
729
+
679
730
void getCPUIDInfo ()
680
731
{
681
732
size_t len = 0 ;
0 commit comments