Race Condition and Locking Clinic
Retrieval Prompts
- State, from memory, the three correctness properties of the critical-section problem.
- Describe the load-modify-store decomposition of
counter++in pseudo-assembly. - Name the hardware primitives that make correct locks possible (TAS, CAS, LL/SC, fetch-add).
- State the two reasons a ticket lock is fairer than a TAS spinlock.
- Write, in one line, when a spinlock is preferable to a blocking mutex and when the reverse holds.
Compare and Distinguish
Separate these pairs clearly in your own words:
- a data race versus a race condition (hint: every data race is a race condition; not every race condition is a data race)
- mutual exclusion versus bounded waiting
- a spinlock versus a blocking mutex under a short critical section with preemptible holders
- coarse-grained versus fine-grained locking with regard to correctness obligations
volatile(in C/C++) versus_Atomic/std::atomic
Common Mistake Check
For each statement, identify the error and give the fix:
- "Reading a shared
intis atomic, so I can read it without a lock while another thread writes it." - "The test suite passed 1000 times; therefore the code has no race."
- "I used
if (!predicate) cond_wait(&cv, &m);because the signaler just woke someone, so the predicate must be true." - "My critical section is a single instruction, so I don't need a lock."
- "I only use spinlocks because they don't do a syscall, so they're always faster."
Mini Application
For each scenario, do all four:
- identify the shared state
- identify the critical section and the invariant it must preserve
- write the smallest interleaving that breaks the invariant under no synchronization
- write the smallest fix using pthread mutex / condvar / atomics
Scenarios:
- A reference-counted object where multiple threads can call
acquire()(increment) andrelease()(decrement, free at zero). - A global
bool ready = false; int data;where one thread writesdata, then setsready = true, and other threads spin onreadybefore readingdata. - A hash table that supports
get,put, anddelete, with 90% reads and 10% writes in the workload. - A linked list where threads can insert at the head and scan front-to-back.
Evidence Check
This page is complete only if, for each scenario above, you can:
- exhibit a concrete interleaving (with a table like the one in concept 1)
- name the Coffman/critical-section property at stake
- point at the specific pthread primitive or atomic operation you used and justify the memory ordering