diff options
Diffstat (limited to 'indra/llcommon/llprocessor.cpp')
| -rw-r--r-- | indra/llcommon/llprocessor.cpp | 57 | 
1 files changed, 54 insertions, 3 deletions
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 <CoreFoundation/CoreFoundation.h> +#include <IOKit/IOKitLib.h>  #include <mach/machine.h>  #include <sys/sysctl.h> @@ -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<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;      } @@ -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;  | 
