Critical Section in Process Synchronization: Race Conditions and Correctness Worked Step by Step
See how two sensible updates to x can finish at 6, 7, or 8. The worked trace connects race conditions to mutual exclusion, progress, bounded waiting, and safe synchronization choices.
KnowledgeGate Team
Exam prep & CS education

Two processes can each execute a perfectly sensible statement and still corrupt a shared result. The trouble begins when the machine interleaves the statement's read, compute, and write steps. A single interleaving trace connects critical section, race condition, mutual exclusion, progress, and bounded waiting, starting with x = 5. Correctness depends on ordering, not memorised definitions in isolation.
Locate the critical section before trying to protect it
A process alternates among an entry section, critical section, exit section, and remainder section. Entry requests permission, exit releases it, and remainder work does not need the protected resource.
The critical section is code that reads or changes shared state, such as a variable, queue, file structure, or device state. The shared object is not the critical section, and neither is the entire process.
Suppose shared integer x = 5. Process P1 executes x = x + 1, while P2 executes x = x + 2. Both statements are critical sections because each performs a read-modify-write operation on the same x. A calculation involving only a process-local value stays in the remainder section. The CS Fundamentals route places this idea within the broader subject.
The three requirements of a correct critical-section solution
Mutual exclusion means that at most one process may be inside its critical section for the protected resource at a time. In this example, P1 and P2 must not overlap the complete read-modify-write sequence on x.
Progress applies when the critical section is empty and processes want to enter. Processes staying in their remainder sections cannot postpone the choice indefinitely.
Bounded waiting is separate. After a process requests entry, there must be a finite bound on how many times others may enter first. Progress prevents needless postponement. Bounded waiting prevents one requester from starving while others enter.
A correctness argument cannot depend on one process always being faster than another. Mutual exclusion alone is also insufficient. An entry protocol may prevent overlap yet deadlock, or it may let a particular requester wait without a finite bound.
Worked trace: two safe-looking assignments lose an update
Treat each load, add, and store as a separate step, so the source assignment is not indivisible. With x = 5, P1 uses LOAD r1 <- x, ADD r1 <- r1 + 1, STORE x <- r1. P2 uses LOAD r2 <- x, ADD r2 <- r2 + 2, STORE x <- r2.
step | P1 | P2 | shared x |
|---|---|---|---|
initial |
| ||
1 |
|
| |
2 |
|
| |
3 |
|
| |
4 |
|
| |
5 |
|
| |
6 |
|
|
The final value is 7, so P1's increment is lost. In contrast, serial orders give (5 + 1) + 2 = 8 and (5 + 2) + 1 = 8.
If both processes load 5 but the stores are reversed, P1 stores last and the result is 6. If either update finishes before the other load, the second process reads the updated value and produces 8. Thus the exact possible set is {6, 7, 8}. A race condition makes the result depend on timing, and neither 6 nor 7 matches serial execution.

Why obvious entry protocols fail
Consider a naive shared Boolean lock = 0. P1 reads 0; before it writes, P2 also reads 0. Both write lock = 1 and enter. Because check and set are separate, mutual exclusion fails. With an atomic read-modify-write primitive, only one process can observe and claim the available state.
Strict alternation fails differently. Let turn = 0, use the entry rule while (turn != i), and set turn = 1 - i on exit. If P0 stays in its remainder section while only P1 wants to enter, P1 must wait even though the critical section is empty. Mutual exclusion may still hold, but progress fails.
Disabling interrupts is a kernel technique for limited contexts, not a general user-process proof or a portable multiprocessor solution by itself. Entry and exit need a suitable atomic primitive or proven algorithm, not an ordinary check followed later by an ordinary write.

Map the problem to the right synchronization tool
A mutex provides lock and unlock around a critical section, normally with ownership semantics. A binary semaphore can gate one unit of access. A counting semaphore initialised to k permits k acquisitions, so it does not give single-resource mutual exclusion when k > 1. A spinlock repeatedly checks atomic state and suits only an understood waiting tradeoff.
Peterson's algorithm is a conceptual bridge for two processes. Intent flags stop an uninterested process from controlling the choice, while turn resolves simultaneous interest. Its textbook proof relies on atomic shared reads and writes plus the model's memory-order assumptions. It is not a production mutex replacement.
After you can enumerate the x = 5 outcomes and identify the first failing entry step, use Process Synchronization and Semaphores to trace Peterson's solution and wait/signal semantics. Then Semaphore Trace Tables for Three Classic Problems applies those semantics to producer-consumer, readers-writers, and dining philosophers.
Traps that make a correct-looking answer wrong
Keep the vocabulary exact. Shared data is the protected resource. Code touching that resource is the critical section. A race condition is timing-dependent behaviour. A race can exist even when one run happens to finish at 8; that single execution does not prove the program safe.
Keep failure properties separate. A mutual-exclusion violation means overlapping entry. Deadlock means participants cannot progress. Starvation means one requester can be bypassed indefinitely while others continue. Busy waiting describes how a process waits, not whether its algorithm is correct.
Check the arithmetic against the trace. Ending at 7 loses P1's +1; reversing only the stores ends at 6 and loses P2's +2; either serial order ends at 8. Under this model, exclude 5 and 9. Never treat source-level x = x + c as atomic unless guaranteed.
How exam-style questions test the critical-section problem
Common question forms ask you to identify the critical section, enumerate final values from an interleaving, match a claim to mutual exclusion, progress, or bounded waiting, find the first violating step in an entry protocol, or decide whether an atomic primitive closes a check-then-set race.
Use these answer-first checks:
Both processes read
lock = 0before either writes, so mutual exclusion can fail.With
turn = 0, uninterestedP0, and waitingP1, progress fails.If
P1can be bypassed1, 2, 3, ...times with no finite bound, bounded waiting fails.Protecting the complete
LOAD-ADD-STOREupdate makes either serial order finish atx = 8.
For focused practice, work through Process Synchronization MCQs: 12 Solved GATE Questions and explain each answer using the property or interleaving that decides it.
The short version and the next step
Locate the shared read-modify-write code.
Show how its individual steps can interleave.
Demand mutual exclusion, progress, and bounded waiting.
Choose a primitive or algorithm whose atomicity assumptions support those properties.
The unprotected outcomes are {6, 7, 8}, while either protected serial order gives 8. Cover the timeline and reconstruct all six steps from x = 5, then explain aloud why 7 is a race result, not merely a calculation mistake. For wider CS revision, continue with Computer Science Fundamentals for Placements.
Keep learning

System Calls and Dual Mode in OS: Mode-Bit Trace, Worked Example and Exam Traps
Follow one read() call across the user-kernel boundary, calculate its stated overhead, and learn the distinctions that make system-call questions easier.

Semaphores and Process Ordering in OS: P/V Traces, Worked Examples and GATE Traps
Learn one consistent semaphore convention, then trace ordering constraints, shared-variable updates, bounded-buffer permits, rendezvous, and deadlock step by step.

Round Robin Scheduling Explained: Gantt Charts, Waiting Time and GATE Traps
Learn a fixed Round Robin queue convention, trace staggered arrivals, calculate CT, TAT, WT and RT, and see how quantum size and context-switch cost change results.

Paging and TLB Explained: Address Translation, EMAT and Exam Traps
Follow one virtual address from its VPN through the TLB to a physical frame, then calculate page-table size, TLB reach and effective memory access time.