feat(agent): add safe lowlevel extension point
This commit is contained in:
@@ -22,4 +22,5 @@ tempfile.workspace = true
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
asm-lowlevel = []
|
||||||
legacy-powershell = []
|
legacy-powershell = []
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct CpuFeatures {
|
||||||
|
pub architecture: String,
|
||||||
|
pub backend: &'static str,
|
||||||
|
pub features: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_cpu_features() -> CpuFeatures {
|
||||||
|
let mut features = Vec::new();
|
||||||
|
collect_cpu_features(&mut features);
|
||||||
|
features.sort();
|
||||||
|
features.dedup();
|
||||||
|
|
||||||
|
CpuFeatures {
|
||||||
|
architecture: std::env::consts::ARCH.to_string(),
|
||||||
|
backend: super::LOWLEVEL_BACKEND,
|
||||||
|
features,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||||
|
fn collect_cpu_features(features: &mut Vec<String>) {
|
||||||
|
for (name, detected) in [
|
||||||
|
("sse2", std::is_x86_feature_detected!("sse2")),
|
||||||
|
("sse4.2", std::is_x86_feature_detected!("sse4.2")),
|
||||||
|
("avx", std::is_x86_feature_detected!("avx")),
|
||||||
|
("avx2", std::is_x86_feature_detected!("avx2")),
|
||||||
|
("aes", std::is_x86_feature_detected!("aes")),
|
||||||
|
] {
|
||||||
|
if detected {
|
||||||
|
features.push(name.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||||
|
fn collect_cpu_features(features: &mut Vec<String>) {
|
||||||
|
for name in compile_time_features() {
|
||||||
|
features.push(name.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
not(any(target_arch = "x86", target_arch = "x86_64")),
|
||||||
|
target_arch = "aarch64"
|
||||||
|
))]
|
||||||
|
fn compile_time_features() -> &'static [&'static str] {
|
||||||
|
&[
|
||||||
|
#[cfg(target_feature = "aes")]
|
||||||
|
"aes",
|
||||||
|
#[cfg(target_feature = "neon")]
|
||||||
|
"neon",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
not(any(target_arch = "x86", target_arch = "x86_64")),
|
||||||
|
not(target_arch = "aarch64")
|
||||||
|
))]
|
||||||
|
fn compile_time_features() -> &'static [&'static str] {
|
||||||
|
&[]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cpu_features_have_architecture_and_backend() {
|
||||||
|
let features = get_cpu_features();
|
||||||
|
|
||||||
|
assert!(!features.architecture.trim().is_empty());
|
||||||
|
assert!(!features.backend.trim().is_empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//! Safe low-level extension point for future agent optimizations.
|
||||||
|
//!
|
||||||
|
//! The default implementation is pure Rust. The `asm-lowlevel` feature is a
|
||||||
|
//! reserved integration point for future platform-specific CPU and timing
|
||||||
|
//! probes implemented through `core::arch`, inline assembly, or native OS
|
||||||
|
//! calls. Keep any future `unsafe` code isolated inside this module.
|
||||||
|
|
||||||
|
pub mod cpu;
|
||||||
|
pub mod timing;
|
||||||
|
|
||||||
|
pub use cpu::{CpuFeatures, get_cpu_features};
|
||||||
|
pub use timing::{high_precision_time_ns, monotonic_ticks};
|
||||||
|
|
||||||
|
#[cfg(feature = "asm-lowlevel")]
|
||||||
|
pub const LOWLEVEL_BACKEND: &str = "asm-lowlevel-ready-rust-fallback";
|
||||||
|
|
||||||
|
#[cfg(not(feature = "asm-lowlevel"))]
|
||||||
|
pub const LOWLEVEL_BACKEND: &str = "rust";
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
use std::sync::OnceLock;
|
||||||
|
use std::time::{Instant, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
|
static MONOTONIC_START: OnceLock<Instant> = OnceLock::new();
|
||||||
|
|
||||||
|
pub fn monotonic_ticks() -> u128 {
|
||||||
|
MONOTONIC_START
|
||||||
|
.get_or_init(Instant::now)
|
||||||
|
.elapsed()
|
||||||
|
.as_nanos()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn high_precision_time_ns() -> u128 {
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.as_nanos()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn monotonic_ticks_do_not_go_backwards() {
|
||||||
|
let first = monotonic_ticks();
|
||||||
|
let second = monotonic_ticks();
|
||||||
|
|
||||||
|
assert!(second >= first);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn high_precision_time_is_epoch_based() {
|
||||||
|
assert!(high_precision_time_ns() > 1_000_000_000);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
mod collectors;
|
mod collectors;
|
||||||
mod config;
|
mod config;
|
||||||
|
pub mod lowlevel;
|
||||||
mod telemetry;
|
mod telemetry;
|
||||||
mod transport;
|
mod transport;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user