Skip to content

Commit b242145

Browse files
author
Rye
committed
Fix getting cpu frequency on apple silicon
1 parent 82c3cc6 commit b242145

File tree

1 file changed

+54
-3
lines changed

1 file changed

+54
-3
lines changed

indra/llcommon/llprocessor.cpp

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,8 @@ class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl
628628

629629
#elif LL_DARWIN
630630

631+
#include <CoreFoundation/CoreFoundation.h>
632+
#include <IOKit/IOKitLib.h>
631633
#include <mach/machine.h>
632634
#include <sys/sysctl.h>
633635

@@ -638,25 +640,66 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl
638640
{
639641
getCPUIDInfo();
640642
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+
}
641684
setInfo(eFrequency, (F64)frequency / (F64)1000000);
642685
}
643686

644-
virtual ~LLProcessorInfoDarwinImpl() {}
687+
virtual ~LLProcessorInfoDarwinImpl() = default;
645688

646689
private:
647690
int getSysctlInt(const char* name)
648691
{
649692
int result = 0;
650693
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);
652695
return error == -1 ? 0 : result;
653696
}
654697

655698
uint64_t getSysctlInt64(const char* name)
656699
{
657700
uint64_t value = 0;
658701
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);
660703
if ( result == 0 )
661704
{
662705
if ( size == sizeof( uint64_t ) )
@@ -676,6 +719,14 @@ class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl
676719
return result == -1 ? 0 : value;
677720
}
678721

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+
679730
void getCPUIDInfo()
680731
{
681732
size_t len = 0;

0 commit comments

Comments
 (0)