use std::time::Duration;
use core_affinity::CoreId;
use crate::bench::preflight;
use crate::bench::tsc::calibrate_hz;
pub mod adapters;
pub mod report;
pub mod spmc;
pub mod spsc;
pub use report::LatencyReport;
pub struct TwoCoreCtx {
pub producer_core: CoreId,
pub consumer_core: CoreId,
pub clock: quanta::Clock,
pub tsc_hz: u64,
}
impl TwoCoreCtx {
pub fn discover_and_preflight() -> Self {
let cores = core_affinity::get_core_ids().expect("core_affinity::get_core_ids failed");
assert!(
cores.len() >= 2,
"need at least 2 separate cores for cross-core benches"
);
let producer_core = cores[0];
let consumer_core = cores[1];
let used = [producer_core.id, consumer_core.id];
Self::preflight(&used);
Self::mlockall();
let tsc_hz = calibrate_hz(Duration::from_millis(200));
Self {
producer_core,
consumer_core,
clock: quanta::Clock::new(),
tsc_hz,
}
}
pub fn used_cpu_ids(&self) -> [usize; 2] {
[self.producer_core.id, self.consumer_core.id]
}
fn preflight(used_cores: &[usize]) {
let mut r = preflight::PreflightReport::default();
preflight::release_build(&mut r);
preflight::cores_online(&mut r, used_cores);
preflight::cores_isolated(&mut r, used_cores);
preflight::cores_nohz_full(&mut r, used_cores);
preflight::cores_performance_governor(&mut r, used_cores);
preflight::turbo_disabled(&mut r);
preflight::cores_distinct_physical(&mut r, used_cores);
preflight::cores_smt_siblings_quiet(&mut r, used_cores);
preflight::cores_share_l3(&mut r, used_cores);
preflight::tsc_invariant_and_nonstop(&mut r);
r.finish();
}
fn mlockall() {
unsafe {
let rc = libc::mlockall(libc::MCL_CURRENT | libc::MCL_FUTURE);
assert_eq!(rc, 0, "mlockall failed (need CAP_IPC_LOCK or sudo)");
}
}
}