diff --git a/Cargo.toml b/Cargo.toml index aece7c6..e240a46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["codegen", "examples", "performance_measurement", "performance_measur [package] name = "worktable" -version = "0.9.0-beta0.2.0" +version = "0.9.0-beta0.2.1" edition = "2024" authors = ["Handy-caT"] license = "MIT" @@ -46,7 +46,7 @@ tracing = "0.1" url = { version = "2", optional = true } uuid = { version = "1.10.0", features = ["v4", "v7"] } walkdir = { version = "2", optional = true } -worktable_codegen = { path = "codegen", version = "=0.9.0-beta0.2.0" } +worktable_codegen = { path = "codegen", version = "=0.9.0-beta0.2.1" } [dev-dependencies] chrono = "0.4.43" diff --git a/codegen/Cargo.toml b/codegen/Cargo.toml index da37a32..d4acd9a 100644 --- a/codegen/Cargo.toml +++ b/codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "worktable_codegen" -version = "0.9.0-beta0.2.0" +version = "0.9.0-beta0.2.1" edition = "2024" license = "MIT" description = "WorkTable codegeneration crate" @@ -19,4 +19,4 @@ syn = { version = "2.0.74", features = ["full"] } quote = "1.0.36" proc-macro2 = "1.0.86" convert_case = "0.6.0" -indexmap = "2" \ No newline at end of file +indexmap = "2" diff --git a/src/lock/mod.rs b/src/lock/mod.rs index 9720c98..578fe00 100644 --- a/src/lock/mod.rs +++ b/src/lock/mod.rs @@ -17,6 +17,9 @@ use parking_lot::Mutex; pub use map::LockMap; pub use row_lock::{FullRowLock, RowLock}; +/// Maximum number of spin iterations before falling back to async waiting. +const MAX_SPINS: u32 = 12; + /// RAII guard that automatically unlocks a [`Lock`] when dropped. /// /// The [`Lock`] is automatically released when the [`LockGuard`] is @@ -144,12 +147,21 @@ impl Future for LockWait { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + // Fast path: already unlocked if !self.locked.load(Ordering::Acquire) { return Poll::Ready(()); } - self.waker.register(cx.waker()); + // Spin phase: try up to MAX_SPINS before going async + for _ in 0..MAX_SPINS { + std::hint::spin_loop(); + if !self.locked.load(Ordering::Acquire) { + return Poll::Ready(()); + } + } + // Async phase: register waker and wait + self.waker.register(cx.waker()); if self.locked.load(Ordering::Acquire) { Poll::Pending } else {