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 worksYou cannot free a node while another thread may still read it through an old pointer. Epoch-based reclamation batches retired nodes and frees them only after every thread passes a global epoch boundary. Userspace RCU and Folly's hazptr variants solve the same problem.
Each thread enters a critical section by recording the current epoch. Retire nodes to a per-thread list. Advance global epoch; when all threads observe epoch E, free nodes retired before E.
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 add epoch reclamation to a lock-free stack so freed nodes are not reused too early. This exercise asks you to run a concurrent pop/push stress test without use-after-free.
A lock-free structure cannot free() a node the moment it unlinks it, because another thread may still hold a pointer it loaded a moment earlier. Epoch-based reclamation (EBR) solves this. Threads pin themselves to the current global epoch while touching shared nodes. Unlinked nodes are retired with the epoch they were retired in. The epoch advances only when every pinned thread has caught up, and a node retired in epoch e is freed once the global epoch reaches e + 2. At that point nobody can still hold it. Simulate EBR, including a stalled reader that blocks all reclamation.
cLoading…
Threads and nodes are created on first mention. The global epoch starts at 0.
blocked: T is still pinned at epoch e, N nodes waiting names the first such thread in order of first appearance. Otherwise the epoch increments, the advancing thread (if pinned) moves with it, and every retired node whose retire epoch + 2 <= the new epoch is freed, in order of first mention.USE AFTER FREE (X was freed);unsafe: not pinned (X may be freed at any moment);ok, plus (retired, but still protected) if the node is retired.already pinned, not pinned, X was already retired / X was already freed, and unknown operation.cLoading…
Every command is echoed as T OP[ NODE]: before its result. state lists threads in order of first appearance, then retired nodes (none if there are none), then the total number freed.
Input:
cLoading…
Output:
cLoading…
Hidden tests cover a stalled reader that holds many retired nodes back, re-pinning so the epoch can move on, several retirements in different epochs, reads outside a pinned section, retiring a node twice, double enter/exit, and unknown operations.