use std::sync::atomic::{AtomicBool, AtomicI32, AtomicI64, AtomicU32, AtomicU64, Ordering};
pub static SHUTDOWN: AtomicBool = AtomicBool::new(false);
pub const RT_STATUS_NEEDS_RESAMPLER_REBUILD: u64 = 1 << 0;
pub const RT_STATUS_RESAMPLER_REBUILD_FAILED: u64 = 1 << 1;
pub const RT_STATUS_RT_IS_FIFO: u64 = 1 << 2;
pub const RT_STATUS_HAS_CLIPPED: u64 = 1 << 3;
pub const RT_STATUS_IS_SILENT: u64 = 1 << 4;
pub const RT_STATUS_GC_OVERFLOW: u64 = 1 << 5;
pub const RT_STATUS_IS_FADING: u64 = 1 << 6;
pub const RT_STATUS_MODEL_LOAD_FAILED: u64 = 1 << 7;
pub const RT_STATUS_HEAP_ALLOC: u64 = 1 << 8;
pub const RT_STATUS_RESAMP_SWAP_PENDING: u64 = 1 << 10;
pub const RT_STATUS_HUGEPAGE_OK: u64 = 1 << 11;
pub const RT_STATUS_DEGRADE_REDUCED: u64 = 1 << 12;
pub const RT_STATUS_DEGRADE_MINIMAL: u64 = 1 << 13;
pub const RT_STATUS_NEEDS_CABSIM_REBUILD: u64 = 1 << 9;
pub const RT_STATUS_GC_CORRUPTED: u64 = 1 << 14;
pub const RT_STATUS_A2_FALLBACK_TRIGGERED: u64 = 1 << 15;
pub const RT_STATUS_SLIMMABLE_SLICE_FAILED: u64 = 1 << 16;
pub const RT_STATUS_NEEDS_SLIMMABLE_REBUILD: u64 = 1 << 17;
pub const RT_STATUS_THP_ACTIVE: u64 = 1 << 18;
pub const RT_STATUS_NEEDS_OS_REBUILD: u64 = 1 << 19;
pub const RT_STATUS_HOST_CONTRACT_VIOLATION: u64 = 1 << 20;
pub const RT_STATUS_SLIMMABLE_RESET_FAILED: u64 = 1 << 21;
pub const RT_STATUS_NEEDS_QUANTUM_LOG: u64 = 1 << 23;
pub const RT_STATUS_GC_TIER3: u64 = 1 << 22;
#[repr(align(128))]
pub struct RtStatusFlags {
pub active_rate: AtomicU32,
pub active_rate_changed: AtomicU32,
pub requested_pw_rate: AtomicU32,
pub requested_nam_rate: AtomicU32,
pub rt_priority: AtomicI32,
pub dsp_overloads: AtomicU32,
pub dsp_cycle_time: AtomicU64,
pub last_n_samples: AtomicU32,
pub latency_hist: crate::dsp::telemetry::LatencyHistogram,
pub degrade_transitions_total: AtomicU32,
pub status_bits: AtomicU64,
pub confirmed_priority: AtomicI32,
pub rt_policy: AtomicI32,
pub rt_cpu: AtomicI32,
pub flags_seen: AtomicU64,
pub xruns: AtomicU32,
pub drains: AtomicU32,
pub requested_cabsim_partition_size: AtomicU32,
pub requested_slimmable_ch: AtomicU32,
pub requested_os_factor: AtomicU32,
pub requested_pw_quantum: AtomicU32,
pub previous_quantum: AtomicU32,
pub pw_buffer_miss: AtomicU32,
pub playback_miss: AtomicU32,
pub capture_pw_now: AtomicI64,
pub capture_pw_ticks: AtomicU64,
pub capture_pw_delay: AtomicI64,
pub playback_pw_now: AtomicI64,
pub playback_pw_ticks: AtomicU64,
pub playback_pw_delay: AtomicI64,
pub rt_affinity_err: AtomicI32,
pub rt_sched_err: AtomicI32,
pub rt_getsched_err: AtomicI32,
pub rt_target_cpu: AtomicI32,
}
impl RtStatusFlags {
#[cold]
pub fn new() -> Self {
Self {
active_rate: AtomicU32::new(0),
active_rate_changed: AtomicU32::new(0),
requested_pw_rate: AtomicU32::new(0),
requested_nam_rate: AtomicU32::new(48_000),
rt_priority: AtomicI32::new(-1),
dsp_overloads: AtomicU32::new(0),
dsp_cycle_time: AtomicU64::new(0),
last_n_samples: AtomicU32::new(0),
latency_hist: crate::dsp::telemetry::LatencyHistogram::new(),
degrade_transitions_total: AtomicU32::new(0),
status_bits: AtomicU64::new(0),
confirmed_priority: AtomicI32::new(-1),
rt_policy: AtomicI32::new(-1),
rt_cpu: AtomicI32::new(-1),
flags_seen: AtomicU64::new(0),
xruns: AtomicU32::new(0),
drains: AtomicU32::new(0),
requested_cabsim_partition_size: AtomicU32::new(0),
requested_slimmable_ch: AtomicU32::new(0),
requested_os_factor: AtomicU32::new(0),
requested_pw_quantum: AtomicU32::new(0),
previous_quantum: AtomicU32::new(0),
pw_buffer_miss: AtomicU32::new(0),
playback_miss: AtomicU32::new(0),
capture_pw_now: AtomicI64::new(0),
capture_pw_ticks: AtomicU64::new(0),
capture_pw_delay: AtomicI64::new(0),
playback_pw_now: AtomicI64::new(0),
playback_pw_ticks: AtomicU64::new(0),
playback_pw_delay: AtomicI64::new(0),
rt_affinity_err: AtomicI32::new(0),
rt_sched_err: AtomicI32::new(0),
rt_getsched_err: AtomicI32::new(0),
rt_target_cpu: AtomicI32::new(-1),
}
}
#[inline(always)]
pub fn set_flag(&self, flag: u64) {
self.status_bits.fetch_or(flag, Ordering::Relaxed);
}
#[inline(always)]
pub fn clear_flag(&self, flag: u64) {
self.status_bits.fetch_and(!flag, Ordering::Relaxed);
}
#[inline(always)]
pub fn check_flag(&self, flag: u64) -> bool {
(self.status_bits.load(Ordering::Relaxed) & flag) != 0
}
#[inline(always)]
pub fn set_flag_release(&self, flag: u64) {
self.status_bits.fetch_or(flag, Ordering::Release);
}
#[inline(always)]
pub fn clear_flag_relaxed(&self, flag: u64) {
self.status_bits.fetch_and(!flag, Ordering::Relaxed);
}
#[inline(always)]
pub fn clear_flag_release(&self, flag: u64) {
self.status_bits.fetch_and(!flag, Ordering::Release);
}
#[inline(always)]
pub fn check_flag_acquire(&self, flag: u64) -> bool {
(self.status_bits.load(Ordering::Acquire) & flag) != 0
}
#[inline(always)]
pub fn check_and_clear_flag(&self, flag: u64) -> bool {
let old = self.status_bits.fetch_and(!flag, Ordering::Relaxed);
let active = (old & flag) != 0;
if active {
self.flags_seen.fetch_or(flag, Ordering::Relaxed);
}
active
}
}
impl Default for RtStatusFlags {
fn default() -> Self {
Self::new()
}
}