Skip to main content

fluxbench_core/
lib.rs

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