Skip to main content

fluxbench_core/
lib.rs

1#![warn(missing_docs)]
2//! FluxBench Core - Worker Runtime
3//!
4//! This crate provides the execution environment for benchmarks:
5//! - `Bencher` struct for iteration-based benchmarking
6//! - High-precision timing (RDTSC with Instant fallback)
7//! - Global allocator interceptor for memory tracking
8//! - CPU affinity pinning for stable TSC readings
9
10mod allocator;
11mod bencher;
12mod measure;
13mod worker;
14
15pub use allocator::{TrackingAllocator, current_allocation, reset_allocation_counter};
16pub use bencher::{Bencher, BenchmarkResult, IterationMode, run_benchmark_loop};
17/// Whether this platform provides hardware cycle counters (x86_64 RDTSCP or AArch64 CNTVCT_EL0).
18/// When `false`, cycle counts are reported as 0 and only wall-clock nanoseconds are available.
19pub use measure::HAS_CYCLE_COUNTER;
20pub use measure::Instant;
21pub use measure::Timer;
22pub use worker::WorkerMain;
23
24/// Benchmark definition registered via `#[flux::bench]`
25#[derive(Debug, Clone)]
26pub struct BenchmarkDef {
27    /// Unique identifier
28    pub id: &'static str,
29    /// Human-readable name
30    pub name: &'static str,
31    /// Group this benchmark belongs to
32    pub group: &'static str,
33    /// Severity level for CI reporting
34    pub severity: Severity,
35    /// Regression threshold percentage
36    pub threshold: f64,
37    /// Absolute time budget in nanoseconds
38    pub budget_ns: Option<u64>,
39    /// Tags for filtering
40    pub tags: &'static [&'static str],
41    /// Function pointer to the wrapper
42    pub runner_fn: fn(&mut Bencher),
43    /// Source file path
44    pub file: &'static str,
45    /// Source line number
46    pub line: u32,
47    /// Module path
48    pub module_path: &'static str,
49    /// Per-benchmark warmup override (nanoseconds)
50    pub warmup_ns: Option<u64>,
51    /// Per-benchmark measurement override (nanoseconds)
52    pub measurement_ns: Option<u64>,
53    /// Per-benchmark fixed sample count
54    pub samples: Option<u64>,
55    /// Per-benchmark minimum iterations
56    pub min_iterations: Option<u64>,
57    /// Per-benchmark maximum iterations
58    pub max_iterations: Option<u64>,
59    /// Benchmark IDs that must run before this one
60    pub depends_on: &'static [&'static str],
61}
62
63/// Severity levels for CI integration
64#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
65pub enum Severity {
66    /// Critical benchmark - regression fails the build
67    Critical,
68    /// Warning level - logged but doesn't fail
69    Warning,
70    /// Informational only
71    Info,
72}
73
74/// Group definition for organizing benchmarks
75#[derive(Debug, Clone)]
76pub struct GroupDef {
77    /// Group identifier
78    pub id: &'static str,
79    /// Human-readable description
80    pub description: &'static str,
81    /// Tags for filtering
82    pub tags: &'static [&'static str],
83    /// Parent group (for nested groups)
84    pub parent: Option<&'static str>,
85}
86
87/// Chart type for dashboard layout
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub enum ChartType {
90    /// Violin plot
91    Violin,
92    /// Bar chart
93    Bar,
94    /// Scatter plot
95    Scatter,
96    /// Line chart
97    Line,
98    /// Histogram
99    Histogram,
100}
101
102/// Chart definition for dashboard
103#[derive(Debug, Clone)]
104pub struct ChartDef {
105    /// Chart title
106    pub title: &'static str,
107    /// Chart type
108    pub chart_type: ChartType,
109    /// Grid position (row, col)
110    pub position: (u32, u32),
111    /// Items to display (benchmark IDs)
112    pub items: &'static [&'static str],
113    /// Optional target line
114    pub target_line: Option<f64>,
115}
116
117/// Report/dashboard definition
118#[derive(Debug, Clone)]
119pub struct ReportDef {
120    /// Dashboard title
121    pub title: &'static str,
122    /// Grid layout (rows, cols)
123    pub layout: (u32, u32),
124    /// Charts in the dashboard
125    pub charts: &'static [ChartDef],
126}
127
128/// Comparison group - groups multiple benchmarks for side-by-side comparison
129#[derive(Debug, Clone)]
130pub struct CompareDef {
131    /// Comparison identifier
132    pub id: &'static str,
133    /// Human-readable title
134    pub title: &'static str,
135    /// Benchmark IDs to compare
136    pub benchmarks: &'static [&'static str],
137    /// Optional baseline benchmark (first one if not specified)
138    pub baseline: Option<&'static str>,
139    /// Metric to compare (default: mean)
140    pub metric: &'static str,
141    /// Group for chart generation (comparisons with same group form a chart)
142    pub group: Option<&'static str>,
143    /// X-axis value for this comparison point (e.g., "1", "10", "100")
144    pub x: Option<&'static str>,
145    /// Series labels (display names) - must match benchmarks array length
146    /// If not specified, benchmark IDs are used as labels
147    pub series: Option<&'static [&'static str]>,
148}
149
150// Collect all registered benchmarks
151inventory::collect!(BenchmarkDef);
152inventory::collect!(GroupDef);
153inventory::collect!(ReportDef);
154inventory::collect!(CompareDef);
155
156/// Anchor to prevent LTO from stripping inventory entries
157#[used]
158#[doc(hidden)]
159pub static REGISTRY_ANCHOR: fn() = || {
160    for _ in inventory::iter::<BenchmarkDef> {}
161    for _ in inventory::iter::<GroupDef> {}
162    for _ in inventory::iter::<ReportDef> {}
163    for _ in inventory::iter::<CompareDef> {}
164};