hardware 0.0.9

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
use core::sync::atomic::{AtomicUsize, Ordering};

static PERF_START: AtomicUsize = AtomicUsize::new(0);
static PERF_END: AtomicUsize = AtomicUsize::new(0);
static PERF_SAMPLE_COUNT: AtomicUsize = AtomicUsize::new(0);

#[derive(Copy, Clone)]
pub struct Perf {
    pub start_ticks: u64,
    pub end_ticks: u64,
}

pub fn read_timestamp() -> u64 {
    match crate::arch::detect_arch() {
        crate::arch::Architecture::X86_64 => crate::arch::x86_64::cpu::tsc::read_tsc(),
        crate::arch::Architecture::AArch64 => {
            crate::arch::aarch64::cpu::system_regs::read_cntvct_el0()
        }
        _ => 0,
    }
}

pub fn start() -> Perf {
    let ts = read_timestamp();
    PERF_START.store(ts as usize, Ordering::Release);
    Perf {
        start_ticks: ts,
        end_ticks: 0,
    }
}

pub fn stop(p: &Perf) -> Perf {
    let ts = read_timestamp();
    PERF_END.store(ts as usize, Ordering::Release);
    PERF_SAMPLE_COUNT.fetch_add(1, Ordering::Relaxed);
    Perf {
        start_ticks: p.start_ticks,
        end_ticks: ts,
    }
}

pub fn elapsed(p: &Perf) -> u64 {
    p.end_ticks.wrapping_sub(p.start_ticks)
}

pub fn sample_count() -> usize {
    PERF_SAMPLE_COUNT.load(Ordering::Acquire)
}

pub fn last_start() -> usize {
    PERF_START.load(Ordering::Acquire)
}

pub fn last_end() -> usize {
    PERF_END.load(Ordering::Acquire)
}