use std::sync::atomic::{AtomicU8, Ordering};
static ENABLED: AtomicU8 = AtomicU8::new(0);
pub fn trace_enabled() -> bool {
match ENABLED.load(Ordering::Relaxed) {
1 => true,
2 => false,
_ => {
let on = std::env::var("LOGOS_TIER_TRACE")
.map(|v| !v.is_empty() && v != "0")
.unwrap_or(false);
ENABLED.store(if on { 1 } else { 2 }, Ordering::Relaxed);
on
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ExecTier {
Bytecode,
Warm,
NativeForge,
NativeAot,
}
impl ExecTier {
pub fn label(self) -> &'static str {
match self {
ExecTier::Bytecode => "bytecode",
ExecTier::Warm => "warm",
ExecTier::NativeForge => "native(forge)",
ExecTier::NativeAot => "native(aot)",
}
}
}
pub fn format_transition(fi: usize, name: &str, to: ExecTier) -> String {
if name.is_empty() {
format!("[tier] fn#{fi} -> {}", to.label())
} else {
format!("[tier] fn#{fi} '{name}' -> {}", to.label())
}
}
pub fn trace_transition(fi: usize, name: &str, to: ExecTier) {
if trace_enabled() {
eprintln!("{}", format_transition(fi, name, to));
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn transition_lines_format_with_and_without_a_name() {
assert_eq!(
format_transition(3, "fib", ExecTier::Warm),
"[tier] fn#3 'fib' -> warm"
);
assert_eq!(
format_transition(7, "quicksort", ExecTier::NativeForge),
"[tier] fn#7 'quicksort' -> native(forge)"
);
assert_eq!(
format_transition(0, "", ExecTier::NativeAot),
"[tier] fn#0 -> native(aot)"
);
assert_eq!(
format_transition(1, "main", ExecTier::Bytecode),
"[tier] fn#1 'main' -> bytecode"
);
}
}