mirror of
https://github.com/MariaDB/server.git
synced 2025-08-09 22:24:09 +03:00
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.
This commit is contained in:
@@ -77,7 +77,7 @@ C_MODE_START
|
|||||||
/**
|
/**
|
||||||
A cycle timer.
|
A cycle timer.
|
||||||
|
|
||||||
On clang, we use __builtin_readcyclecounter().
|
On clang we use __builtin_readcyclecounter(), except for AARCH64.
|
||||||
On other compilers:
|
On other compilers:
|
||||||
|
|
||||||
On IA-32 and AMD64, we use the RDTSC instruction.
|
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 IBM S/390 System z we use the STCK instruction.
|
||||||
On ARM, we probably should use the Generic Timer, but should figure out
|
On ARM, we probably should use the Generic Timer, but should figure out
|
||||||
how to ensure that it can be accessed.
|
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,
|
Sadly, we have nothing for the Digital Alpha, MIPS, Motorola m68k,
|
||||||
HP PA-RISC or other non-mainstream (or obsolete) processors.
|
HP PA-RISC or other non-mainstream (or obsolete) processors.
|
||||||
@@ -125,7 +128,7 @@ C_MODE_START
|
|||||||
*/
|
*/
|
||||||
static inline ulonglong my_timer_cycles(void)
|
static inline ulonglong my_timer_cycles(void)
|
||||||
{
|
{
|
||||||
# if __has_builtin(__builtin_readcyclecounter)
|
# if __has_builtin(__builtin_readcyclecounter) && !defined (__aarch64__)
|
||||||
return __builtin_readcyclecounter();
|
return __builtin_readcyclecounter();
|
||||||
# elif defined _WIN32 || defined __i386__ || defined __x86_64__
|
# elif defined _WIN32 || defined __i386__ || defined __x86_64__
|
||||||
return __rdtsc();
|
return __rdtsc();
|
||||||
@@ -164,6 +167,12 @@ static inline ulonglong my_timer_cycles(void)
|
|||||||
__asm__ __volatile__ ("stck %0" : "=Q" (result) : : "cc");
|
__asm__ __volatile__ ("stck %0" : "=Q" (result) : : "cc");
|
||||||
return result;
|
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)
|
#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
|
||||||
/* gethrtime may appear as either cycle or nanosecond counter */
|
/* gethrtime may appear as either cycle or nanosecond counter */
|
||||||
return (ulonglong) gethrtime();
|
return (ulonglong) gethrtime();
|
||||||
@@ -221,6 +230,7 @@ C_MODE_END
|
|||||||
#define MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME 25
|
#define MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME 25
|
||||||
#define MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME 26
|
#define MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME 26
|
||||||
#define MY_TIMER_ROUTINE_ASM_S390 28
|
#define MY_TIMER_ROUTINE_ASM_S390 28
|
||||||
|
#define MY_TIMER_ROUTINE_AARCH64 29
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -362,6 +362,8 @@ void my_timer_init(MY_TIMER_INFO *mti)
|
|||||||
mti->cycles.routine= MY_TIMER_ROUTINE_ASM_GCC_SPARC32;
|
mti->cycles.routine= MY_TIMER_ROUTINE_ASM_GCC_SPARC32;
|
||||||
#elif defined(__GNUC__) && defined(__s390__)
|
#elif defined(__GNUC__) && defined(__s390__)
|
||||||
mti->cycles.routine= MY_TIMER_ROUTINE_ASM_S390;
|
mti->cycles.routine= MY_TIMER_ROUTINE_ASM_S390;
|
||||||
|
#elif defined(__GNUC__) && defined (__aarch64__)
|
||||||
|
mti->cycles.routine= MY_TIMER_ROUTINE_AARCH64;
|
||||||
#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
|
#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
|
||||||
mti->cycles.routine= MY_TIMER_ROUTINE_GETHRTIME;
|
mti->cycles.routine= MY_TIMER_ROUTINE_GETHRTIME;
|
||||||
#else
|
#else
|
||||||
|
Reference in New Issue
Block a user