From 9fef2a114ea7eb6c42dd29e94ba5dc3451eb4560 Mon Sep 17 00:00:00 2001 From: Rye Date: Mon, 3 Feb 2025 11:48:18 -0500 Subject: Fix timer support on macOS under ARM64 --- indra/llcommon/llprocessor.cpp | 57 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) (limited to 'indra/llcommon/llprocessor.cpp') diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index a783e18e49..a6ecad2cf7 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -628,6 +628,8 @@ private: #elif LL_DARWIN +#include +#include #include #include @@ -638,17 +640,58 @@ public: { getCPUIDInfo(); uint64_t frequency = getSysctlInt64("hw.cpufrequency"); + if(frequency == 0) // Attempt to query IO Services for pcore frequency + { + CFMutableDictionaryRef arm_io_matching = IOServiceMatching("AppleARMIODevice"); + io_iterator_t iter; + kern_return_t ret = IOServiceGetMatchingServices(kIOMasterPortDefault, arm_io_matching, &iter); + if(ret == KERN_SUCCESS) + { + io_object_t obj; + while ((obj = IOIteratorNext(iter))) + { + io_name_t obj_class; + ret = IOObjectGetClass(obj, obj_class); + if(ret == KERN_SUCCESS) + { + io_name_t obj_name; + ret = IORegistryEntryGetName(obj, obj_name); + if(ret == KERN_SUCCESS) + { + if (strncmp(obj_name, "pmgr", sizeof(obj_name)) == 0) + { + CFTypeRef cfData = IORegistryEntryCreateCFProperty(obj, CFSTR("voltage-states5-sram"), kCFAllocatorDefault, 0); // pcore frequency + if(cfData) + { + CFIndex size = CFDataGetLength((CFDataRef)cfData); + std::vector databuf(size); + CFDataGetBytes((CFDataRef)cfData, CFRangeMake(0, size), databuf.data()); + + frequency = 0x00000000FFFFFFFF & ((databuf[size-5] << 24) | (databuf[size-6] << 16) | (databuf[size-7] << 8) | (databuf[size-8])); + CFRelease(cfData); + } + break; + } + } + } + } + } + } + if (frequency == 0) // fallback to clockrate and tbfrequency + { + frequency = getSysctlClockrate() * getSysctlInt64("hw.tbfrequency"); + } setInfo(eFrequency, (F64)frequency / (F64)1000000); } - virtual ~LLProcessorInfoDarwinImpl() {} + virtual ~LLProcessorInfoDarwinImpl() = default; private: int getSysctlInt(const char* name) { int result = 0; size_t len = sizeof(int); - int error = sysctlbyname(name, (void*)&result, &len, NULL, 0); + int error = sysctlbyname(name, (void*)&result, &len, nullptr, 0); return error == -1 ? 0 : result; } @@ -656,7 +699,7 @@ private: { uint64_t value = 0; size_t size = sizeof(value); - int result = sysctlbyname(name, (void*)&value, &size, NULL, 0); + int result = sysctlbyname(name, (void*)&value, &size, nullptr, 0); if ( result == 0 ) { if ( size == sizeof( uint64_t ) ) @@ -676,6 +719,14 @@ private: return result == -1 ? 0 : value; } + uint64_t getSysctlClockrate() + { + struct clockinfo clockrate{}; + size_t size = sizeof(clockrate); + int error = sysctlbyname("kern.clockrate", &clockrate, &size, nullptr, 0); + return error == -1 ? 0 : clockrate.hz; + } + void getCPUIDInfo() { size_t len = 0; -- cgit v1.2.3