07 Race Conditions
07 Race Conditions
Critical Sections
Dekkers Algorithm
Announcements
CS 414 Homework this Wednesday, Feb 7th
Scheduling criteria
CPU utilization, Throughput, Turnaround, Waiting, Response
Predictability: variance in any of these measures
Scheduling algorithms
FCFS, SJF, SRTF, RR
Multilevel (Feedback-)Queue Scheduling
Goals to Today
Introduction to Synchronization
..or: the trickiest bit of this course
Background
Race Conditions
The Critical-Section Problem
Dekkers Solution
Background
Concurrent access to shared data may result in data
inconsistency
while (true) {
while (true) {
/* produce an item and */
/* put in nextProduced */ while (count == 0)
; // do nothing b/c empty
while (count == BUFFER_SIZE)
; // do nothing b/c full nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
buffer [in] = nextProduced;
count--;
in = (in + 1) % BUFFER_SIZE;
count++;
/* consume the item */
}
/* in nextConsumed */
}
Race Condition
count++ not atomic operation. Could be implemented as
register1 = count
register1 = register1 + 1
count = register1
count-- not atomic operation. Could be implemented as
register2 = count
register2 = register2 - 1
count = register2
T1 T2
time
CSEnter(); CSEnter();
Critical section Critical section
CSExit(); CSExit();
T1 T2
Critical Section Goals
Perhaps they loop (perhaps not!)
T1 T2
CSEnter(); CSEnter();
Critical section Critical section
CSExit(); CSExit();
T1 T2
Critical Section Goals
We would like
Safety (aka mutual exclusion)
No more than one thread can be in a critical section at any time.
Liveness (aka progress)
A thread that is seeking to enter the critical section will eventually succeed
Bounded waiting
A bound must exist on the number of times that other threads are allowed
to enter their critical sections after a thread has made a request to enter its
critical section and before that request is granted
Assume that each process executes at a nonzero speed
No assumption concerning relative speed of the N processes
Now ask:
Is this Safe? Live? Bounded waiting?
Solving the problem: Take 2
A different idea (assumes just two threads):
Have a boolean flag, inside[i]. Initially false.
Code isnt live: with bad luck, both threads could
CSEnter(int i) be looping,CSExit(int
with 0 lookingi)at 1, and 1 looking at 0
{ {
inside[i] = true; Inside[i] = false;
while(inside[i^1]) continue; }
}
Now ask:
Is this Safe? Live? Bounded waiting?
Solving the problem: Take 3
Another broken solution, for two threads
Have a turn variable, Code
turn,isnt
initially 1. 1 cant enter unless
live: thread
thread 0 did first, and vice-versa. But perhaps
CSEnter(int i) CSExit(int
one thread i) many times and the
needs to enter
{ other
{ fewer times, or not at all
while(turn != i) continue; turn = i ^ 1;
} }
Now ask:
Is this Safe? Live? Bounded waiting?
A solution that works
Dekkers Algorithm (1965)
(book: Exercise 6.1)
CSEnter(int i)
{
inside[i] = true;
while(inside[J]) CSExit(int i)
{ {
if (turn == J) turn = J;
{ inside[i] = false;
inside[i] = false; }
while(turn == J) continue;
inside[i] = true;
}
}}
Napkin analysis of Dekkers
algorithm:
Safety: No process will enter its CS without setting
its inside flag. Every process checks the other
process inside flag after setting its own. If both are
set, the turn variable is used to allow only one
process to proceed.
Liveness: The turn variable is only considered
when both processes are using, or trying to use,
the resource
Bounded waiting: The turn variable ensures
alternate access to the resource when both are
competing for access
Why does it work?
Safety: Suppose thread 0 is in the CS.
Then inside[0] is true.
If thread 1 was simultaneously trying to enter, then turn must
equal 0 and thread 1 waits
If thread 1 tries to enter now, it sets turn to 0 and waits
Liveness: Suppose thread 1 wants to enter and
cant (stuck in while loop)
Thread 0 will eventually exit the CS
When inside[0] becomes false, thread 1 can enter
If thread 0 tries to reenter immediately, it sets turn=1
and hence will wait politely for thread 1 to go first!
Postscript
Dekkers algorithm does not provide strict alternation
Initially, a thread can enter critical section without accessing turn