summaryrefslogtreecommitdiff
path: root/indra/llcommon/llprocessor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llprocessor.cpp')
-rw-r--r--indra/llcommon/llprocessor.cpp61
1 files changed, 52 insertions, 9 deletions
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index 2e94651083..a6ecad2cf7 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -628,6 +628,8 @@ private:
#elif LL_DARWIN
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/IOKitLib.h>
#include <mach/machine.h>
#include <sys/sysctl.h>
@@ -638,25 +640,58 @@ public:
{
getCPUIDInfo();
uint64_t frequency = getSysctlInt64("hw.cpufrequency");
- if (!frequency)
+ if(frequency == 0) // Attempt to query IO Services for pcore frequency
{
- auto tbfrequency = getSysctlInt64("hw.tbfrequency");
- struct clockinfo clockrate;
- auto clockrate_len = sizeof(clockrate);
- if (!sysctlbyname("kern.clockrate", &clockrate, &clockrate_len, NULL, 0))
- frequency = tbfrequency * clockrate.hz;
+ 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<U8> 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;
}
@@ -664,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 ) )
@@ -684,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;