CS2106 Tutorial 4
Chen Minqi
Clarification: Default initial task ordering
- In a question where there is no explicit initial order between tasks (e.g. all have the same priority or start at the same time) we can assume that the order is implied by their numbering.
- You do not need to try out every combination.
- Tutorial 1 (the quesiton on FIFO) & tutorial 3 (question 2 on RR)
Q1. Describe what a race condition is.
- A race condition is a condition where the final outcome of several parallel [1] threads [2] updating shared storage [3] depends on which thread completes updating first.
- This generally leads to incorrect solutions, i.e. solutions that are different from one where the threads run sequentially.
[1] Only occur between two or more threads. We cannot have race conditions inside a single thread.
[2] Not CPUs / cores.
[3] Don't use 'memory'.
Suppose two identical tasks update a shared variable tmp using tmp++
Can a race condition occur? Why or why not?
LD R1, tmp # Load tmp into R1
ADD R1, R1, 1 # Increment
SW R1, tmp # Store result into memoryQ2. Describe what "atomicity" means.
- Atomicity means that the steps taken in an instruction, or the steps taken in a group of instructions, are executed as one complete unit without possibility of interruption.
- In our example in Q1, atomicity means that all 3 instructions are executed completely without possibility of the thread being interrupted in between.
The kernel often disables interrupts to guarantee atomicity. Explain how this works.
- Uniprocessor operating systems may disable interrupts to guarantee atomicity.
- Context switching does not happen without interrupts, and therefore there is no possibility of race condition.
- Not enough for a multiprocessor system.
Why it's a bad idea to allow user processes to achieve atomicity in the same way.
- Malicious programs can lock down the system.
- User programs are not well tested. Operating system software is usually thoroughly tested before release.
Q3. Can the following mechanisms enforce mutual exclusion?
If yes, list the advantages and disadvantages.
Disabling Interrupts
Effective?
Yes (for uni-processor systems).
Reason: see previous question.
Advantages?
Easy to implement.
Disadvantages?
Requires kernel privileges.
A hung process can block the entire system.
Extra help needed for multi-processor systems.
Lock Variables
Effective?
No.
Race condition on the lock variable itself.
(see lecture 4 slide pg 18)
Advantages?
-
Disadvantages?
-
Strict Alternation
Effective?
Yes (but...)
Not possible to have a race condition on the turn variable, and only one CS can be run depending on the variable itself.
Advantages?
Simple implementation.
Disadvantages?
Busy waiting.
Possible starvation.
Peterson's Solution
Effective?
Yes. If two processes want to enter CS, the first one to indicate interest (turn!=process) will enter first.
Advantages?
Purely software based solution.
Non-CS code will not block another CS.
Disadvantages?
Busy waiting.
Harder to understand and implement, especially for more than 2 processes.
(Did you know: it took people two decades to arrive at Persons's algorithm?)
Sleep/Wake up
Nothing to do with mutex.
It deals with deadlocks instead :]
Extra: Some definitions
- Starvation: a task is perpetually denied necessary resources to process its work.
- Deadlock: two or more competing tasks are each waiting for the other to finish, and thus neither ever does.
- Livelock*: two or more tasks whose states are constantly changing with regard to one another, but none progressing.
Q4. Explain how the “turn” variable in Peterson’s Solution prevents deadlock.
- We are talking about deadlock without priority issues (i.e. not lecture slide 26)

interested[0] = true;
turn = 0;
while(interested[1] == true &&
turn == 0); /* loop */
/* cs */
interested[0] = false;interested[1] = true;
turn = 1;
while(interested[0] == true &&
turn == 1); /* loop */
/* cs */
interested[1] = false;interested[0] = true;
while(interested[1] == true);
while(interested[1] == true);
while(interested[1] == true);
while(interested[1] == true);
/* will not reach here
interested[0] = false; */
interested[1] = true;
while(interested[0] == true);
while(interested[0] == true);
while(interested[0] == true);
while(interested[0] == true);
/* will not reach here
interested[1] = false; */Adding the turn variable means that only one process can be stuck in the while loop. The other will proceed to their CS (and eventually change turn variable again to free the other process).
Copy of Copy of CS2106 Tutorial 4
By Chen Minqi
Copy of Copy of CS2106 Tutorial 4
- 704