Skip to content
← All Rust tracks

Atomics, Send/Sync and the Memory Model

Rust

Explore atomic operations, memory ordering and the Send and Sync traits. Learn what tests can reveal and where concurrency reasoning needs stronger tools.

This track uses Rust. You can make it your practice mode to browse related content across the site.

8 exercises

4 articles

Explore freely. Sign in to keep your progress.

Your learning sequence

  1. 1 Not solved yet. Atomics: counters, flags and fetch_* Practice · Medium
  2. 2 Not solved yet. CAS loops: compare_exchange and fetch_update Practice · Hard
  3. 3 Choosing atomic memory orderings Read
  4. 4 Not solved yet. A store-buffer memory-model interpreter Practice · Hard
  5. 5 Not solved yet. A single-producer single-consumer ring buffer Practice · Hard
  6. 6 Send and Sync as unsafe auto traits Read
  7. 7 False sharing: when separate counters compete for a cache line Read
  8. 8 Not solved yet. OnceLock: initialize shared state once Practice · Medium
  9. 9 Not solved yet. static mut and the edition-2024 wall Practice · Medium
  10. 10 Not solved yet. Build a spinlock from AtomicBool and UnsafeCell Practice · Hard
  11. 11 Not solved yet. Tree traversal with indexed storage and shared locks Practice · Medium
  12. 12 What passing concurrency tests tells you Read

Check yourself

4 questions · not saved while you're signed out

Use these questions to check your understanding and compare explanations. Your score does not affect track completion.

0 / 4 correct

With one writer, initially zero data and a false flag, which ordering pair ensures the assertion holds if the reader sees true?

Choose one answer to reveal the explanations. Answers are kept only while this page is open.

use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};

fn publish(data: &AtomicUsize, ready: &AtomicBool) {
    data.store(42, Ordering::Relaxed);
    ready.store(true, Ordering::Release);
}

fn read_if_ready(data: &AtomicUsize, ready: &AtomicBool) {
    if ready.load(Ordering::Acquire) {
        assert_eq!(data.load(Ordering::Relaxed), 42);
    }
}

fn main() {
    let data = AtomicUsize::new(0);
    let ready = AtomicBool::new(false);
    std::thread::scope(|scope| {
        scope.spawn(|| publish(&data, &ready));
        read_if_ready(&data, &ready);
    });
}
Question 1 of 4