Master the fundamental concepts of lock-free & wait-free programming through this focused micro-challenge.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksC11 stdatomic.h and C++ std::atomic expose memory_order_relaxed, acquire, release, and seq_cst. Lock-free stacks, queues, and reference counts rely on pairing release stores with acquire loads so published data is visible without mutex overhead. Getting ordering wrong produces bugs that reproduce only on ARM or under load.
relaxed for pure counters. release after writing payload, acquire before reading it. seq_cst is the safe default when learning; tighten later for performance.
cLoading…
atomic_thread_fence is rarely needed when every access uses atomicsKeep the relevant documentation open while you implement. When your output disagrees with the reference, trace one failing case by hand before changing random lines.
You will implement a flag synchronization pattern using acquire/release atomics. This exercise asks you to publish a struct pointer safely without a mutex.
Litmus tests are tiny multi-threaded programs used to pin down exactly what a memory model allows. Write a checker that enumerates every outcome of a litmus test under three models: sequential consistency (sc), x86 tso, and a relaxed model with C11-style acquire/release and fences. Use it to see why store buffering needs a fence on x86, and why message passing needs release/acquire on weakly ordered CPUs.
cLoading…
Operations: W x v (store), Wrel x v (release store), Wsc x v, R x r (load into register r), Racq x r (acquire load), Rsc x r, and F (full fence). Memory starts at 0. Register names are global to the test.
An execution is an interleaving of all operations in which each load reads the latest store to its location (memory is multi-copy atomic). Within a thread, a later operation B may execute before an earlier operation A only if the model permits reordering the pair:
F between them, and never for two accesses to the same location.sc.sc, A is an acquire load (nothing moves above it), or B is a release store (nothing moves below it).Enumerate every execution that respects the pairs that must stay ordered, and collect the distinct final register values.
cLoading…
check echoes its arguments exactly as typed.bad operation: TEXT, thread: at most 4 threads, thread: at most 8 operations in total, model: sc, tso or relaxed, check: unknown register, and check: run a model first.Input:
cLoading…
Output:
cLoading…
Hidden tests cover message passing under tso and relaxed with and without release/acquire, load buffering, IRIW with plain and acquire loads, sc operations, fences in relaxed mode, and malformed operations.