summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorTzachi Zidenberg <tsahee@amazon.com>2020-07-06 13:43:30 +0300
committerTzachi Zidenberg <tsahee@amazon.com>2020-07-23 15:07:13 +0300
commitc76b45a5242f50d00c16f0bbf1dbecd4e359e02c (patch)
tree262571433ede080aa64d6c9d57dbc551d080549d /include
parent5f2628d1eea21d9732f582b77782b072e5e04014 (diff)
downloadmariadb-git-c76b45a5242f50d00c16f0bbf1dbecd4e359e02c.tar.gz
MDEV-23249: Support aarch64 architecture timer
aarch64 timer is available to userspace via arch register. clang's __builtin_readcyclecounter is wrong for aarch64 (reads the PMU cycle counter instead of the archi-timer register), so we don't use it. my_rdtsc unit-test on AWS m6g shows: frequency: 121830845 resolution: 1 overhead: 1 This counter is not strictly increasing, but it is non-decreasing.
Diffstat (limited to 'include')
-rw-r--r--include/my_rdtsc.h14
1 files changed, 12 insertions, 2 deletions
diff --git a/include/my_rdtsc.h b/include/my_rdtsc.h
index a2e5afcb79f..33d722764d4 100644
--- a/include/my_rdtsc.h
+++ b/include/my_rdtsc.h
@@ -77,7 +77,7 @@ C_MODE_START
/**
A cycle timer.
- On clang, we use __builtin_readcyclecounter().
+ On clang we use __builtin_readcyclecounter(), except for AARCH64.
On other compilers:
On IA-32 and AMD64, we use the RDTSC instruction.
@@ -88,6 +88,9 @@ C_MODE_START
On IBM S/390 System z we use the STCK instruction.
On ARM, we probably should use the Generic Timer, but should figure out
how to ensure that it can be accessed.
+ On AARCH64, we use the generic timer base register. We override clang
+ implementation for aarch64 as it access a PMU register which is not
+ guarenteed to be active.
Sadly, we have nothing for the Digital Alpha, MIPS, Motorola m68k,
HP PA-RISC or other non-mainstream (or obsolete) processors.
@@ -125,7 +128,7 @@ C_MODE_START
*/
static inline ulonglong my_timer_cycles(void)
{
-# if __has_builtin(__builtin_readcyclecounter)
+# if __has_builtin(__builtin_readcyclecounter) && !defined (__aarch64__)
return __builtin_readcyclecounter();
# elif defined _WIN32 || defined __i386__ || defined __x86_64__
return __rdtsc();
@@ -164,6 +167,12 @@ static inline ulonglong my_timer_cycles(void)
__asm__ __volatile__ ("stck %0" : "=Q" (result) : : "cc");
return result;
}
+#elif defined(__GNUC__) && defined (__aarch64__)
+ {
+ ulonglong result;
+ __asm __volatile("mrs %0, CNTVCT_EL0" : "=&r" (result));
+ return result;
+ }
#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
/* gethrtime may appear as either cycle or nanosecond counter */
return (ulonglong) gethrtime();
@@ -221,6 +230,7 @@ C_MODE_END
#define MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME 25
#define MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME 26
#define MY_TIMER_ROUTINE_ASM_S390 28
+#define MY_TIMER_ROUTINE_AARCH64 29
#endif