perf: use atomics for controller progress and state

This commit is contained in:
Michael Aaron Murphy 2026-04-14 16:27:53 +02:00
parent 93dd775f3c
commit 971374f60b
No known key found for this signature in database
GPG key ID: B2732D4240C9212C
3 changed files with 29 additions and 10 deletions

8
Cargo.lock generated
View file

@ -538,6 +538,12 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "atomic_float"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "628d228f918ac3b82fe590352cc719d30664a0c13ca3a60266fe02c7132d480a"
[[package]] [[package]]
name = "atomicwrites" name = "atomicwrites"
version = "0.4.2" version = "0.4.2"
@ -1349,6 +1355,7 @@ name = "cosmic-files"
version = "1.0.9" version = "1.0.9"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"atomic_float",
"bzip2", "bzip2",
"compio", "compio",
"cosmic-client-toolkit", "cosmic-client-toolkit",
@ -1378,6 +1385,7 @@ dependencies = [
"notify-debouncer-full", "notify-debouncer-full",
"notify-rust", "notify-rust",
"num_cpus", "num_cpus",
"num_enum",
"open", "open",
"ordermap", "ordermap",
"paste", "paste",

View file

@ -64,6 +64,8 @@ filetime = "0.2"
tracing = "0.1.44" tracing = "0.1.44"
tracing-subscriber = { version = "0.3.22", features = ["env-filter"] } tracing-subscriber = { version = "0.3.22", features = ["env-filter"] }
thiserror = "2.0.18" thiserror = "2.0.18"
atomic_float = "1.1.0"
num_enum = "0.7.6"
# Completion-based IO runtime to enable io_uring / IOCP file IO support. # Completion-based IO runtime to enable io_uring / IOCP file IO support.
[dependencies.compio] [dependencies.compio]

View file

@ -1,7 +1,11 @@
use std::sync::{Arc, Mutex}; use atomic_float::AtomicF32;
use num_enum::{IntoPrimitive, TryFromPrimitive};
use std::sync::Arc;
use std::sync::atomic::{self, AtomicU16};
use tokio::sync::Notify; use tokio::sync::Notify;
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)]
#[repr(u16)]
pub enum ControllerState { pub enum ControllerState {
Cancelled, Cancelled,
Failed, Failed,
@ -11,8 +15,8 @@ pub enum ControllerState {
#[derive(Debug)] #[derive(Debug)]
struct ControllerInner { struct ControllerInner {
state: Mutex<ControllerState>, state: AtomicU16,
progress: Mutex<f32>, progress: AtomicF32,
notify: Notify, notify: Notify,
} }
@ -27,8 +31,8 @@ impl Default for Controller {
Self { Self {
primary: true, primary: true,
inner: Arc::new(ControllerInner { inner: Arc::new(ControllerInner {
state: Mutex::new(ControllerState::Running), state: AtomicU16::new(ControllerState::Running.into()),
progress: Mutex::new(0.0), progress: AtomicF32::new(0.0),
notify: Notify::new(), notify: Notify::new(),
}), }),
} }
@ -50,19 +54,24 @@ impl Controller {
} }
pub fn progress(&self) -> f32 { pub fn progress(&self) -> f32 {
*self.inner.progress.lock().unwrap() self.inner.progress.load(atomic::Ordering::Relaxed)
} }
pub fn set_progress(&self, progress: f32) { pub fn set_progress(&self, progress: f32) {
*self.inner.progress.lock().unwrap() = progress; self.inner
.progress
.swap(progress, atomic::Ordering::Relaxed);
} }
pub fn state(&self) -> ControllerState { pub fn state(&self) -> ControllerState {
*self.inner.state.lock().unwrap() ControllerState::try_from(self.inner.state.load(atomic::Ordering::Relaxed))
.unwrap_or(ControllerState::Failed)
} }
pub fn set_state(&self, state: ControllerState) { pub fn set_state(&self, state: ControllerState) {
*self.inner.state.lock().unwrap() = state; self.inner
.state
.store(state.into(), atomic::Ordering::Relaxed);
self.inner.notify.notify_waiters(); self.inner.notify.notify_waiters();
} }