Week 9 - Threading, Send, Sync, and the Memory Model¶
9.1 Conceptual Core¶
Send= "safe to transfer ownership to another thread."Sync= "safe to share by&Tacross threads" (equivalently:&T: Send).- These are auto traits: structurally derived. A struct is
Sendif all its fields areSend, etc. Opt-out by including aPhantomData<*const ()>or by using!Send/!Syncnegative impls (nightly). - Memory model: Rust's memory model is, today, the C++20 memory model (consume order excluded). You must internalize the happens-before relation, the meaning of
Relaxed,Acquire,Release,AcqRel,SeqCst, and the difference between synchronization and visibility.
9.2 Mechanical Detail¶
std::thread::spawnvsthread::scope: scoped threads (stable since 1.63) allow borrowing from the parent stack frame because the join is guaranteed before the borrow ends. This is the right default for most parallelism.- Atomics (
AtomicUsize,AtomicPtr<T>,AtomicBool, etc.): the API surface is small but every method takes anOrdering. The orderings are: Relaxed-no synchronization; only atomicity. Used for counters where ordering doesn't matter (e.g., metrics).Acquire/Release-pairwise synchronization. AReleasestore synchronizes with anAcquireload that observes the value, establishing happens-before from the store-side's prior writes to the load-side's subsequent reads.AcqRel-both, on RMW (read-modify-write) operations.SeqCst-total order across allSeqCstoperations system-wide. Strongest, slowest, safest if you do not yet know what you're doing.fence: standalone memory barriers. Rarely needed; usually a smell that the abstraction should be different.- Spin loops:
std::hint::spin_loop()emitspause(x86) /yield(ARM). Critical for short-wait spinlocks; missing this hint hurts SMT performance and burns power.
9.3 Lab-"A Correct Spinlock"¶
Implement Spinlock<T> from scratch using AtomicBool:
- lock() spins with Relaxed load, then Acquire CAS.
- unlock() Release stores false.
- Returns a SpinlockGuard<'_, T> whose Drop unlocks.
- Verify with loom (run all interleavings-see week 10) that no two threads enter the critical section.
9.4 Idiomatic & Clippy Drill¶
clippy::mutex_atomic,clippy::mutex_integer,clippy::needless_collect,clippy::should_implement_trait. The first two flag the anti-pattern ofMutex<bool>whereAtomicBoolsuffices.
9.5 Production Hardening Slice¶
- Add a
loomfeature gate to your spinlock crate. Runcargo test --features loomin CI. Fail the build on any model-checker violation.