一、使用ARMv8提供的独立定时器CNTVCT_EL0
System counter是Arm64下独立于CPU core的计数器,在系统上电时,会给此计数器设置固定的频率。一个映射System counter计数器内容的寄存器为CNTVCT_EL0,可在用户态下读取此寄存器获取counter值。而CNTFRQ_EL0保存的是counter的频率值(详细内容参考《【ARMv8】通用定时器总结》)。通过下面的函数实现获取counter值及频率值:
static inline uint64_t
arm64_cntvct(void)
{
uint64_t tsc;
asm volatile("mrs %0, cntvct_el0" : "=r" (tsc));
return tsc;
}static inline uint64_t
arm64_cntfrq(void)
{
uint64_t freq;
asm volatile("mrs %0, cntfrq_el0" : "=r" (freq));
return freq;
}static inline uint64_t
rdtsc(void)
{
return arm64_cntvct();
}
arm64_cntvct 这个函数需要进行换算的,读取寄存器 cntvct_el0,只是获取了固定频率下的寄存器的值,这个值仅仅是单调自增,代表“晶振”几次,并不是生活中时间单位秒 或者ns;
代码修改如下