x86_64: prefix rdtsc with lfence, or use rdtscp if available
a strong monotonicity is a property of system_time(). Performance should be a bit impacted (around 10%). removed omit-frame-pointer hints as the compiler generates the same without. Change-Id: I920145d616604f32b38d9e134ce83f3e0e848bc7 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5690 Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
99071c0c0b
commit
a6e9176bc5
|
@ -4,6 +4,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <x86intrin.h>
|
||||
|
@ -13,26 +15,79 @@ static uint64_t cv_factor;
|
|||
static uint64_t cv_factor_nsec;
|
||||
|
||||
|
||||
extern "C" void
|
||||
__x86_setup_system_time(uint64_t cv, uint64_t cv_nsec)
|
||||
{
|
||||
cv_factor = cv;
|
||||
cv_factor_nsec = cv_nsec;
|
||||
}
|
||||
|
||||
|
||||
extern "C" [[gnu::optimize("omit-frame-pointer")]] int64_t
|
||||
system_time()
|
||||
static int64_t
|
||||
__system_time_lfence()
|
||||
{
|
||||
__builtin_ia32_lfence();
|
||||
__uint128_t time = static_cast<__uint128_t>(__rdtsc()) * cv_factor;
|
||||
return time >> 64;
|
||||
}
|
||||
|
||||
|
||||
extern "C" [[gnu::optimize("omit-frame-pointer")]] int64_t
|
||||
system_time_nsecs()
|
||||
static int64_t
|
||||
__system_time_rdtscp()
|
||||
{
|
||||
uint32_t aux;
|
||||
__uint128_t time = static_cast<__uint128_t>(__rdtscp(&aux)) * cv_factor;
|
||||
return time >> 64;
|
||||
}
|
||||
|
||||
|
||||
static int64_t
|
||||
__system_time_nsecs_lfence()
|
||||
{
|
||||
__builtin_ia32_lfence();
|
||||
__uint128_t t = static_cast<__uint128_t>(__rdtsc()) * cv_factor_nsec;
|
||||
return t >> 32;
|
||||
}
|
||||
|
||||
|
||||
static int64_t
|
||||
__system_time_nsecs_rdtscp()
|
||||
{
|
||||
uint32_t aux;
|
||||
__uint128_t t = static_cast<__uint128_t>(__rdtscp(&aux)) * cv_factor_nsec;
|
||||
return t >> 32;
|
||||
}
|
||||
|
||||
|
||||
static int64_t (*sSystemTime)(void) = __system_time_lfence;
|
||||
static int64_t (*sSystemTimeNsecs)(void) = __system_time_nsecs_lfence;
|
||||
|
||||
|
||||
// from kernel/arch/x86/arch_cpu.h
|
||||
#define IA32_FEATURE_AMD_EXT_RDTSCP (1 << 27) // rdtscp instruction
|
||||
|
||||
|
||||
extern "C" void
|
||||
__x86_setup_system_time(uint64_t cv, uint64_t cv_nsec)
|
||||
{
|
||||
cv_factor = cv;
|
||||
cv_factor_nsec = cv_nsec;
|
||||
|
||||
cpuid_info cpuInfo;
|
||||
get_cpuid(&cpuInfo, 0x80000000, 0);
|
||||
if (cpuInfo.eax_0.max_eax >= 0x80000001) {
|
||||
get_cpuid(&cpuInfo, 0x80000001, 0);
|
||||
if ((cpuInfo.regs.edx & IA32_FEATURE_AMD_EXT_RDTSCP)!= 0) {
|
||||
sSystemTime = __system_time_rdtscp;
|
||||
sSystemTimeNsecs = __system_time_nsecs_rdtscp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" int64_t
|
||||
system_time()
|
||||
{
|
||||
return sSystemTime();
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern "C" int64_t
|
||||
system_time_nsecs()
|
||||
{
|
||||
return sSystemTimeNsecs();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue