read_time_counter port for the RISCV family. (#1378)

This commit is contained in:
David CARLIER 2023-07-24 12:14:07 +01:00 committed by GitHub
parent f0563475c3
commit b064eb3994
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,7 +3,13 @@
#[cfg(target_arch = "aarch64")]
use core::arch::asm;
#[cfg(not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64")))]
#[cfg(not(any(
target_arch = "x86_64",
target_arch = "x86",
target_arch = "aarch64",
target_arch = "riscv64",
target_arsch = "riscv32"
)))]
use crate::bolts::current_nanos;
// TODO: Add more architectures, using C code, see
@ -44,13 +50,58 @@ pub fn read_time_counter() -> u64 {
v
}
/// Read a timestamp for measurements
///
/// Fetches the full 64 bits of the cycle counter in one instruction.
#[cfg(target_arch = "riscv64")]
#[must_use]
pub fn read_time_counter() -> u64 {
let mut v: u64;
unsafe {
asm!("rdcycle {v}", v = out(reg) v);
}
v
}
/// Read a timestamp for measurements
///
/// Fetches the high 32 bits of the cycle counter, its low end
/// If the high part has changed, we branch again.
/// FIXME: see if the latter is overkill.
#[cfg(target_arch = "riscv32")]
#[must_use]
pub fn read_time_counter() -> u64 {
let mut v: u64;
let mut hg: u32;
let mut lw: u32;
let mut cmp: u32;
unsafe {
asm!("jmp%=:",
"rdcycleh {hg}",
"rdcycle {lw}",
"rdcycleh {cmp}",
"bne {hg} {cmp}, jmp%=",
hg = out(reg) hg,
lw = out(reg) lw,
cmp = out(reg) cmp);
v = ((hg as u64) << 32) | lw as u64;
}
v
}
/// Read a timestamp for measurements.
///
/// This function is a wrapper around different ways to get a timestamp, fast.
/// In this way, an experiment only has to
/// change this implementation rather than every instead of [`read_time_counter`]
/// On unsupported architectures, it's falling back to normal system time, in millis.
#[cfg(not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64")))]
#[cfg(not(any(
target_arch = "x86_64",
target_arch = "x86",
target_arch = "aarch64",
target_arch = "riscv64",
target_arch = "riscv32"
)))]
#[must_use]
pub fn read_time_counter() -> u64 {
current_nanos()