Spinlock Types and Public API
Relevant source files
This document covers the three main spinlock types exposed by the kspin crate and their public interface. These types provide different levels of protection suitable for various kernel contexts. For detailed implementation internals, see Core Implementation Architecture. For comprehensive usage guidelines and safety requirements, see Usage Guidelines and Safety.
Spinlock Type Overview
The kspin crate provides three specialized spinlock types, each offering a different balance between performance and protection. All types are implemented as type aliases of the generic BaseSpinLock with different guard types from the kernel_guard crate.
| Spinlock Type | Guard Type | Protection Level | Use Context |
|---|---|---|---|
| SpinRaw | NoOp | No protection | Preemption and IRQ-disabled contexts |
| SpinNoPreempt | NoPreempt | Disables preemption | IRQ-disabled contexts |
| SpinNoIrq | NoPreemptIrqSave | Disables preemption + IRQs | Any context |
Sources: src/lib.rs(L10 - L36)
Type Hierarchy and Guard Relationships
flowchart TD
subgraph subGraph2["Core Implementation (src/base.rs)"]
BaseSpinLock["BaseSpinLock<G, T>Generic spinlock"]
BaseSpinLockGuard["BaseSpinLockGuard<'a, G, T>RAII guard"]
end
subgraph subGraph1["kernel_guard Crate Guards"]
NoOp["NoOpDoes nothing"]
NoPreempt["NoPreemptDisables preemption"]
NoPreemptIrqSave["NoPreemptIrqSaveDisables preemption + IRQs"]
end
subgraph subGraph0["Public API Types (src/lib.rs)"]
SpinRaw["SpinRaw<T>BaseSpinLock<NoOp, T>"]
SpinNoPreempt["SpinNoPreempt<T>BaseSpinLock<NoPreempt, T>"]
SpinNoIrq["SpinNoIrq<T>BaseSpinLock<NoPreemptIrqSave, T>"]
SpinRawGuard["SpinRawGuard<'a, T>BaseSpinLockGuard<'a, NoOp, T>"]
SpinNoPreemptGuard["SpinNoPreemptGuard<'a, T>BaseSpinLockGuard<'a, NoPreempt, T>"]
SpinNoIrqGuard["SpinNoIrqGuard<'a, T>BaseSpinLockGuard<'a, NoPreemptIrqSave, T>"]
end
SpinNoIrq --> BaseSpinLock
SpinNoIrq --> NoPreemptIrqSave
SpinNoIrq --> SpinNoIrqGuard
SpinNoIrqGuard --> BaseSpinLockGuard
SpinNoPreempt --> BaseSpinLock
SpinNoPreempt --> NoPreempt
SpinNoPreempt --> SpinNoPreemptGuard
SpinNoPreemptGuard --> BaseSpinLockGuard
SpinRaw --> BaseSpinLock
SpinRaw --> NoOp
SpinRaw --> SpinRawGuard
SpinRawGuard --> BaseSpinLockGuard
Sources: src/lib.rs(L6 - L36)
Public API Structure
flowchart TD
subgraph subGraph2["RAII Lifecycle"]
acquire["Guard AcquisitionProtection enabled"]
critical["Critical SectionData access"]
release["Guard DropProtection disabled"]
end
subgraph subGraph1["Guard Operations"]
deref["Deref::deref()→ &T"]
deref_mut["DerefMut::deref_mut()→ &mut T"]
drop_guard["Drop::drop()→ ()"]
end
subgraph subGraph0["Spinlock Operations"]
new["new(data: T)→ SpinLock<T>"]
lock["lock()→ Guard<'_, T>"]
try_lock["try_lock()→ Option<Guard<'_, T>>"]
is_locked["is_locked()→ bool"]
end
acquire --> deref
acquire --> deref_mut
critical --> drop_guard
deref --> critical
deref_mut --> critical
drop_guard --> release
lock --> acquire
new --> lock
new --> try_lock
try_lock --> acquire
Sources: src/lib.rs(L8) README.md(L19 - L32)
Type Definitions and Documentation
SpinRaw
SpinRaw<T> provides the fastest spinlock implementation with no built-in protection mechanisms. It is defined as BaseSpinLock<NoOp, T> where the NoOp guard performs no protection operations.
Key Characteristics:
- Zero protection overhead
- Requires manual IRQ and preemption management
- Must be used in preemption-disabled and IRQ-disabled contexts
- Cannot be used in interrupt handlers
Sources: src/lib.rs(L29 - L33)
SpinNoPreempt
SpinNoPreempt<T> disables kernel preemption during lock acquisition and critical sections. It is defined as BaseSpinLock<NoPreempt, T>.
Key Characteristics:
- Automatically disables preemption when acquiring the lock
- Safe from task switching but not from interrupts
- Must be used in IRQ-disabled contexts
- Cannot be used in interrupt handlers
Sources: src/lib.rs(L10 - L15)
SpinNoIrq
SpinNoIrq<T> provides the highest level of protection by disabling both kernel preemption and local IRQs. It is defined as BaseSpinLock<NoPreemptIrqSave, T>.
Key Characteristics:
- Disables both preemption and IRQs
- Safe to use in any context including IRQ-enabled environments
- Highest protection overhead but maximum safety
- Can be used in interrupt handlers
Sources: src/lib.rs(L20 - L24)
Associated Guard Types
Each spinlock type has a corresponding guard type that implements the RAII pattern:
SpinRawGuard<'a, T>forSpinRaw<T>SpinNoPreemptGuard<'a, T>forSpinNoPreempt<T>SpinNoIrqGuard<'a, T>forSpinNoIrq<T>
These guards provide mutable access to the protected data through Deref and DerefMut implementations, and automatically release the lock when dropped.
Sources: src/lib.rs(L17 - L18) src/lib.rs(L26 - L27) src/lib.rs(L35 - L36)
Usage Example from Public Documentation
The crate provides standard usage patterns as demonstrated in the README:
// Raw spinlock - fastest, requires manual protection
let data = SpinRaw::new(());
let mut guard = data.lock();
/* critical section, does nothing while trying to lock. */
drop(guard);
// Preemption-disabled spinlock
let data = SpinNoPreempt::new(());
let mut guard = data.lock();
/* critical section, preemption are disabled. */
drop(guard);
// Full protection spinlock
let data = SpinNoIrq::new(());
let mut guard = data.lock();
/* critical section, both preemption and IRQs are disabled. */
drop(guard);
Sources: README.md(L16 - L33)