Master the fundamental concepts of lock-free & wait-free programming through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
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 worksWait-free guarantees every thread completes its operation in a bounded number of steps regardless of others. Lock-free only promises system-wide progress. Wait-free stacks and counters exist but often cost more atomic operations or memory than practical lock-free versions.
Wait-free snapshot and some counter implementations use helping: slow threads assist others to finish partial operations. Most production queues stop at lock-free.
cLoading…
Keep 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 study a wait-free counter or stack algorithm and implement a simplified version. This exercise requires explaining the progress guarantee difference with a concurrent test.
Lock-free means that some thread always makes progress. Wait-free means that every thread finishes each operation within a bounded number of its own steps, however it is scheduled. A CAS-loop counter is only lock-free: an unlucky thread can lose every CAS for ever. fetch_add is wait-free, and so is a sharded counter (one slot per thread, summed on read). Run all three under the same adversarial schedule and measure the steps each operation needs.
cLoading…
The schedule is a list of turns. Each turn, the named thread performs one step of its current increment. A thread that has finished its K increments ignores its turns.
counter += 1. Done.slot[thread] += 1. Done. The final counter is the sum of all slots.An operation's length is the number of that thread's own steps from its start to its completion. An operation still running at the end of the schedule counts as (still running).
cLoading…
Print the three versions in the order fetch_add, CAS loop, sharded. The wait-free line uses the longest operation (at least 1). Errors: ops: 1..1000, schedule: unknown thread NAME, and run: no threads.
Input:
cLoading…
Output:
cLoading…
Hidden tests cover a schedule that starves one CAS thread completely, three threads, a victim that only finishes once the others are done, schedules longer than the work needed, and unknown thread names.