| Crates.io | axiom-spinlock |
| lib.rs | axiom-spinlock |
| version | 0.1.0 |
| created_at | 2025-10-29 17:33:19.405447+00 |
| updated_at | 2025-10-29 17:33:19.405447+00 |
| description | A lightweight, no_std-compatible spinlock and exponential backoff implementation for low-level concurrent systems. |
| homepage | |
| repository | https://github.com/LOKESH-999/axiom-spinlock |
| max_upload_size | |
| id | 1907015 |
| size | 25,410 |
A lightweight, no_std-compatible spinlock and exponential backoff implementation for low-level concurrent systems.
This crate provides a minimal, efficient spin-based mutual exclusion primitive (SpinLock<T>) together with an adaptive exponential BackOff utility to reduce contention in busy-wait loops.
The implementation focuses on environments where blocking is not an option (kernels, embedded runtimes, custom executors), so it avoids OS-level mutexes and context switching.
core only).std feature (default) to enable thread yielding.SpinLock<T>: atomic test-and-set spinlock with RAII guard (SpinGuard).BackOff: exponential backoff with configurable start, relax/reset and optional std yielding.This repository builds the crate axiom-spinlock (see Cargo.toml).
Using SpinLock:
use axiom_spinlock::SpinLock;
let lock = SpinLock::new(0);
{
let mut guard = lock.lock();
*guard += 1;
} // unlocked when `guard` is dropped
assert_eq!(*lock.lock(), 1);
// convenience API
lock.with_lock(|v| *v += 1);
Using BackOff:
use axiom_spinlock::BackOff;
let backoff = BackOff::new();
for _ in 0..5 {
backoff.wait();
}
A minimal spin-based mutual exclusion primitive:
const fn new(data: T) -> Self — create a new lock.fn lock(&self) -> SpinGuard<'_, T> — acquire the lock (blocks by spinning); returns a guard that releases on drop.unsafe fn unlock(&self) — unsafely release the lock (only call if you own the lock).fn try_lock(&self) -> Option<SpinGuard<'_, T>> — try to acquire without blocking.fn try_lock_for(&self, spins: usize) -> Option<SpinGuard<'_, T>> — attempt to acquire within a fixed number of spin attempts.fn is_locked(&self) -> bool — check whether the lock is currently held.fn with_lock<R>(&self, f: impl FnOnce(&mut T) -> R) -> R — convenience wrapper to run a closure while holding the lock.Notes:
AtomicBool with Acquire/Release ordering.Deref and DerefMut for ergonomic access.SpinLock is marked Send/Sync when T: Send.A simple exponential backoff manager used to reduce contention in spin loops.
const fn new() -> BackOff — default start value.const fn new_with(start: u32) -> BackOff — create with custom start.fn wait(&self) — perform one backoff step (spins, doubles internal counter up to MAX_SPIN, optionally yields with std).fn relax(&self) — reduce current spin intensity.fn current(&self) -> u32 — get current spin iteration value.fn reset(&self) — reset to default start.fn reset_to(&self, spin: u32) — reset to explicit value.#[cfg(feature = "std")] fn yield_now(&self) — explicit yield (only when compiled with std).Implementation details:
core::hint::spin_loop() to inform the CPU of busy-wait.std feature (the crate defaults to enabling this), std::thread::yield_now() is called once contention exceeds a threshold.src/main.rs)The repository includes an example program that creates a static SpinLock<i64> and spawns 100 threads, each incrementing the shared counter 1_000_000 times. This is useful to stress-test the lock, but be aware it is CPU-intensive.
To run the example (default features include std):
cargo run --release
Expect the program to be CPU-bound and run for a while depending on your CPU.
Build the project:
cargo build
Run tests (crate default features include std — if you want to test no_std behavior you must change features accordingly):
cargo test
std (default): Enables std::thread::yield_now() during prolonged backoff and allows examples/tests that spawn threads.The crate is implemented to be usable without std by disabling this feature in embedded or kernel contexts.
SpinLock only for short critical sections.SpinLock is not reentrant.unlock() is unsafe and should only be used by code that truly owns the lock.Cargo.toml contains author and repository metadata.This crate is intentionally small and targeted for embedded/low-level use cases. It pairs a tiny spinlock with a configurable backoff to provide a lightweight synchronization primitive where OS-level primitives are unavailable or undesired.