Fix timer support on macOS under ARM64
parent
594a7afce6
commit
9fef2a114e
|
|
@ -64,7 +64,7 @@ bool BlockTimer::sLog = false;
|
|||
std::string BlockTimer::sLogName = "";
|
||||
bool BlockTimer::sMetricLog = false;
|
||||
|
||||
#if LL_LINUX
|
||||
#if LL_LINUX || (LL_DARWIN && LL_ARM64)
|
||||
U64 BlockTimer::sClockResolution = 1000000000; // Nanosecond resolution
|
||||
#else
|
||||
U64 BlockTimer::sClockResolution = 1000000; // Microsecond resolution
|
||||
|
|
|
|||
|
|
@ -30,9 +30,14 @@
|
|||
#include "llinstancetracker.h"
|
||||
#include "lltrace.h"
|
||||
#include "lltreeiterators.h"
|
||||
#include "llprocessor.h"
|
||||
|
||||
#if LL_X86 || LL_X86_64
|
||||
#if LL_WINDOWS
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define LL_FAST_TIMER_ON 1
|
||||
|
|
@ -68,35 +73,10 @@ public:
|
|||
//
|
||||
// Windows implementation of CPU clock
|
||||
//
|
||||
|
||||
//
|
||||
// NOTE: put back in when we aren't using platform sdk anymore
|
||||
//
|
||||
// because MS has different signatures for these functions in winnt.h
|
||||
// need to rename them to avoid conflicts
|
||||
//#define _interlockedbittestandset _renamed_interlockedbittestandset
|
||||
//#define _interlockedbittestandreset _renamed_interlockedbittestandreset
|
||||
//#include <intrin.h>
|
||||
//#undef _interlockedbittestandset
|
||||
//#undef _interlockedbittestandreset
|
||||
|
||||
//inline U32 getCPUClockCount32()
|
||||
//{
|
||||
// U64 time_stamp = __rdtsc();
|
||||
// return (U32)(time_stamp >> 8);
|
||||
//}
|
||||
//
|
||||
//// return full timer value, *not* shifted by 8 bits
|
||||
//inline U64 getCPUClockCount64()
|
||||
//{
|
||||
// return __rdtsc();
|
||||
//}
|
||||
|
||||
|
||||
#if LL_FASTTIMER_USE_RDTSC
|
||||
|
||||
// shift off lower 8 bits for lower resolution but longer term timing
|
||||
// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
|
||||
#if LL_FASTTIMER_USE_RDTSC
|
||||
static U32 getCPUClockCount32()
|
||||
{
|
||||
unsigned __int64 val = __rdtsc();
|
||||
|
|
@ -159,23 +139,37 @@ public:
|
|||
#endif // (LL_LINUX) && !(defined(__i386__) || defined(__amd64__))
|
||||
|
||||
|
||||
#if (LL_LINUX || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
|
||||
#if LL_DARWIN && LL_ARM64
|
||||
//
|
||||
// Mac+Linux FAST x86 implementation of CPU clock
|
||||
// Mac implementation of CPU clock - non-x86.
|
||||
//
|
||||
static U64 getCPUClockCount64()
|
||||
{
|
||||
return clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
|
||||
}
|
||||
|
||||
static U32 getCPUClockCount32()
|
||||
{
|
||||
U32 low(0),high(0);
|
||||
__asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) );
|
||||
return (low>>8) | (high<<24);
|
||||
return (U32)(getCPUClockCount64() >> 8);
|
||||
}
|
||||
#endif // LL_DARWIN && LL_ARM64
|
||||
|
||||
#if (LL_LINUX || LL_DARWIN) && (LL_X86 || LL_X86_64)
|
||||
//
|
||||
// Mac+Linux FAST x86 implementation of CPU clock
|
||||
//
|
||||
#if LL_FASTTIMER_USE_RDTSC
|
||||
static U32 getCPUClockCount32()
|
||||
{
|
||||
U64 time_stamp = __rdtsc() >> 8U;
|
||||
return static_cast<U32>(time_stamp);
|
||||
}
|
||||
|
||||
static U64 getCPUClockCount64()
|
||||
{
|
||||
U32 low(0),high(0);
|
||||
__asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) );
|
||||
return (U64)low | ( ((U64)high) << 32);
|
||||
return static_cast<U64>(__rdtsc());
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static BlockTimerStatHandle& getRootTimeBlock();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue