Mutual Exclusion By Shiran Mizrahi. Critical Section class Counter { private int value = 1; //counter starts at one public Counter(int c) { //constructor.

Slides:



Advertisements
Similar presentations
Mutual Exclusion – SW & HW By Oded Regev. Outline: Short review on the Bakery algorithm Short review on the Bakery algorithm Black & White Algorithm Black.
Advertisements

Synchronization. How to synchronize processes? – Need to protect access to shared data to avoid problems like race conditions – Typical example: Updating.
CSC321 Concurrent Programming: §3 The Mutual Exclusion Problem 1 Section 3 The Mutual Exclusion Problem.
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Process Synchronization Continued 7.2 The Critical-Section Problem.
6.852: Distributed Algorithms Spring, 2008 Class 13.
Silberschatz, Galvin and Gagne ©2007 Operating System Concepts with Java – 7 th Edition, Nov 15, 2006 Chapter 6 (a): Synchronization.
Concurrency: Mutual Exclusion and Synchronization - Chapter 5 (Part 2)
1 Chapter 2 Synchronization Algorithms and Concurrent Programming Gadi Taubenfeld © 2007 Synchronization Algorithms and Concurrent Programming Gadi Taubenfeld.
Chapter 6 Process Synchronization Bernard Chen Spring 2007.
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts – 9 th Edition Chapter 5: Process Synchronization.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
Multiprocessor Synchronization Algorithms ( ) Lecturer: Danny Hendler The Mutual Exclusion problem.
1 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Process Synchronization. Module 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores.
1 Operating Systems, 122 Practical Session 5, Synchronization 1.
Chair of Software Engineering Concurrent Object-Oriented Programming Prof. Dr. Bertrand Meyer Lecture 4: Mutual Exclusion.
Mutual Exclusion.
CH7 discussion-review Mahmoud Alhabbash. Q1 What is a Race Condition? How could we prevent that? – Race condition is the situation where several processes.
China’s Software Industry August 2006 Instructor: Hengming Zou, Ph.D.
Mutual Exclusion Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified by Rajeev Alur for CIS 640, Spring.
Chapter 3 The Critical Section Problem
1 Course Syllabus 1. Introduction - History; Views; Concepts; Structure 2. Process Management - Processes; State + Resources; Threads; Unix implementation.
Parallel Processing (CS526) Spring 2012(Week 6).  A parallel algorithm is a group of partitioned tasks that work with each other to solve a large problem.
THIRD PART Algorithms for Concurrent Distributed Systems: The Mutual Exclusion problem.
CPSC 668Set 7: Mutual Exclusion with Read/Write Variables1 CPSC 668 Distributed Algorithms and Systems Fall 2009 Prof. Jennifer Welch.
CPSC 668Set 6: Mutual Exclusion in Shared Memory1 CPSC 668 Distributed Algorithms and Systems Fall 2006 Prof. Jennifer Welch.
1 Operating Systems, 112 Practical Session 5, Synchronization 1.
The Critical-Section Problem
1 Course Syllabus 1. Introduction - History; Views; Concepts; Structure 2. Process Management - Processes; State + Resources; Threads; Unix implementation.
Race Conditions Critical Sections Deker’s Algorithm.
1 Tuesday, June 20, 2006 "The box said that I needed to have Windows 98 or better... so I installed Linux." - LinuxNewbie.org.
Chapter 6: Process Synchronization. Outline Background Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores Classic Problems.
Bakery Algorithm - Proof
CPSC 668Set 8: More Mutex with Read/Write Variables1 CPSC 668 Distributed Algorithms and Systems Fall 2009 Prof. Jennifer Welch.
Concurrency in Distributed Systems: Mutual exclusion.
Instructor: Umar KalimNUST Institute of Information Technology Operating Systems Process Synchronization.
Operating Systems CSE 411 CPU Management Oct Lecture 13 Instructor: Bhuvan Urgaonkar.
The Critical Section Problem
Mutual Exclusion Presented by: Rohan Sen (Distributed Algorithms Ch. 10)
28/10/1999POS-A1 The Synchronization Problem Synchronization problems occur because –multiple processes or threads want to share data; –the executions.
Process Synchronization Continued 7.2 Critical-Section Problem 7.3 Synchronization Hardware 7.4 Semaphores.
THIRD PART Algorithms for Concurrent Distributed Systems: The Mutual Exclusion problem.
Mutual Exclusion Using Atomic Registers Lecturer: Netanel Dahan Instructor: Prof. Yehuda Afek B.Sc. Seminar on Distributed Computation Tel-Aviv University.
CY2003 Computer Systems Lecture 04 Interprocess Communication.
1 Chapter 2 Synchronization Algorithms and Concurrent Programming Gadi Taubenfeld © 2014 Synchronization Algorithms and Concurrent Programming Synchronization.
CSCE 668 DISTRIBUTED ALGORITHMS AND SYSTEMS Spring 2014 Prof. Jennifer Welch CSCE 668 Set 8: More Mutex with Read/Write Variables 1.
1 Concurrent Processes. 2 Cooperating Processes  Operating systems allow for the creation and concurrent execution of multiple processes  concurrency.
Operating Systems CMPSC 473 Mutual Exclusion Lecture 11: October 5, 2010 Instructor: Bhuvan Urgaonkar.
Monitors and Blocking Synchronization Dalia Cohn Alperovich Based on “The Art of Multiprocessor Programming” by Herlihy & Shavit, chapter 8.
Hwajung Lee. Mutual Exclusion CS p0 p1 p2 p3 Some applications are:  Resource sharing  Avoiding concurrent update on shared data  Controlling the.
6.852: Distributed Algorithms Spring, 2008 Class 14.
Homework-6 Questions : 2,10,15,22.
Bakery Algorithm - Proof
CSCE 668 DISTRIBUTED ALGORITHMS AND SYSTEMS
Background on the need for Synchronization
Concurrent Distributed Systems
CSCE 668 DISTRIBUTED ALGORITHMS AND SYSTEMS
The Critical-Section Problem
Course Syllabus 1. Introduction - History; Views; Concepts; Structure
Grades.
Course Syllabus 1. Introduction - History; Views; Concepts; Structure
Multiprocessor Synchronization Algorithms ( )
Course Syllabus 1. Introduction - History; Views; Concepts; Structure
Chapter 6: Synchronization Tools
Course Syllabus 1. Introduction - History; Views; Concepts; Structure
Distributed Computing
Course Syllabus 1. Introduction - History; Views; Concepts; Structure
Syllabus 1. Introduction - History; Views; Concepts; Structure
Presentation transcript:

Mutual Exclusion By Shiran Mizrahi

Critical Section class Counter { private int value = 1; //counter starts at one public Counter(int c) { //constructor initializes counter value = c; } public int inc() { //increment value & return prior value int temp = value; //start of danger zone value = temp+1; //end of danger zone return temp; }

Critical Section The problem occurs if two threads both read the value field at the line marked “start of danger zone”, and then both update that field at the line marked “end of danger zone”. int temp = value; value = temp+1;

Critical Section Value read 1 write 2 read 2 write 3 write time int temp = value; value = temp+1;

The mutual exclusion problem remainder code entry code critical section exit code The problem is to design the entry and exit code in a way that guarantees that the mutual exclusion and deadlock-freedom properties are satisfied.

Good properties Mutual Exclusion: No two threads are in their critical sections at the same time. Deadlock-freedom: If a thread is trying to enter its critical section, then some thread, not necessarily the same one, eventually enters its critical section. Starvation-freedom: If a thread is trying to enter its critical section, then this thread must eventually enter its critical section. Starvation-freedom is a stronger property than Deadlock-freedom. Mutual Exclusion: No two threads are in their critical sections at the same time. Deadlock-freedom: If a thread is trying to enter its critical section, then some thread, not necessarily the same one, eventually enters its critical section. Starvation-freedom: If a thread is trying to enter its critical section, then this thread must eventually enter its critical section. Starvation-freedom is a stronger property than Deadlock-freedom.

Discussion Topics The mutual exclusion problem and proposed algorithms Peterson’s algorithm Kessels’ single-writer algorithm Tournament algorithms The Filter algorithm The Bakery algorithm The mutual exclusion problem and proposed algorithms Peterson’s algorithm Kessels’ single-writer algorithm Tournament algorithms The Filter algorithm The Bakery algorithm

Proposed solutions for two threads We begin with two inadequate but interesting algorithms

Some notations A  B event A precedes event B CS A thread A is in the critical section write A (x=v) the event in which thread A writes to x read A (x==v) the event in which thread A reads from x

Algorithm 1 Thread 0 flag[0] = true while (flag[1]) {} critical section flag[0]=false Thread 1 flag[1] = true while (flag[0]) {} critical section flag[1]=false

Mutual Exclusion Algorithm 1 satisfies mutual exclusion

Proof Assume in the contrary that two threads can be in their critical section at the same time. From the code we can see: write 0 (flag[0]=true)  read 0 (flag[1]==false)  CS 0 write 1 (flag[1]=true)  read 1 (flag[0]==false)  CS 1 From the assumption: read 0 (flag[1]==false)  write 1 (flag[1]=true) Thread 0 flag[0] = true while (flag[1]) {} critical section flag[0]=false Thread 1 flag[1] = true while (flag[0]) {} critical section flag[1]=false

Proof We get: write 0 (flag[0]=true)  read 0 (flag[1]==false)  write 1 (flag[1]=true)  read 1 (flag[0]==false) That means that thread 0 writes (flag[0]=true) and then thread 1 reads that (flag[0]==false), a contradiction. Thread 0 flag[0] = true while (flag[1]) {} critical section flag[0]=false Thread 1 flag[1] = true while (flag[0]) {} critical section flag[1]=false

Deadlock freedom Thread 0 flag[0] = true while (flag[1]) {} critical section flag[0]=false Thread 1 flag[1] = true while (flag[0]) {} critical section flag[1]=false Algorithm 1 fails dead-lock freedom: Concurrent execution can deadlock. If both threads write flag[0]=true and flag[1]=true before reading (flag[0]) and (flag[1]) then both threads wait forever.

Algorithm 2 Thread 0 victim = 0; while (victim == 0) {}; critical section Thread 1 victim = 1; while (victim == 1) {}; critical section

Mutual Exclusion Algorithm 2 satisfies mutual exclusion

Proof Assume in the contrary that two threads can be in their critical section at the same time. From the code we can see: write 0 (victim=0)  read 0 (victim==1)  CS 0 write 1 (victim=1)  read 1 (victim==0)  CS 1 Thread 0 victim = 0; while (victim == 0) {}; critical section Thread 1 victim = 1; while (victim == 1) {}; critical section

Proof Since thread 1 must assign 1 to victim between the events write 0 (victim=0) and read 0 (victim==1), and since this assignment is the last, we get: write 0 (victim=0)  write 1 (victim=1)  read 0 (victim==1) Once victim is set to 1, it does not change, so every read will return 1, and this is a contradiction to the former equation: write 1 (victim=1)  read 1 (victim==0)  CS 1 Thread 0 victim = 0; while (victim == 0) {}; critical section Thread 1 victim = 1; while (victim == 1) {}; critical section

Deadlock freedom Algorithm 2 also fails deadlock freedom. It deadlocks if one thread runs completely before the other. Thread 0 victim = 0; while (victim == 0) {}; critical section Thread 1 victim = 1; while (victim == 1) {}; critical section

Algorithms for Two Threads We’ll describe two algorithms that solve the mutual exclusion problem for two Threads. They are also deadlock-free and starvation free.

Peterson ’ s Algorithm Thread 0 flag[0] = true victim = 0 while (flag[1] and victim == 0) {skip} critical section flag[0] = false Thread 1 flag[1] = true victim = 1 while (flag[0] and victim == 1) {skip} critical section flag[1] = false

Peterson ’ s Algorithm 0/1 indicates that the thread is contending for the critical section by setting flag[0]/flag[1] to true. victim shows who got last Then if the value of flag[i] is true then there is no contending by other thread and the thread can start executing the critical section. Otherwise the first who writes to victim is also the first to get into the critical section Thread 0 flag[0] = true victim = 0 while (flag[1] and victim == 0) {skip} critical section flag[0] = false Thread 1 flag[1] = true victim = 1 while (flag[0] and victim == 1) {skip} critical section flag[1] = false

Schematic for Peterson’s mutual exclusion algorithm Indicate contending flag[i] := true Indicate contending flag[i] := true Barrier victim := i Barrier victim := i Contention? flag[j] = true ? Contention? flag[j] = true ? critical section exit code flag[i] = false exit code flag[i] = false First to cross the barrier? victim = j ? First to cross the barrier? victim = j ? yes no / maybe no The structure shows that the first thread to cross the barrier is the one which gets to enter the critical section. When there is no contention a thread can enter the critical section immediately.

Mutual Exclusion Peterson’s algorithm satisfies mutual exclusion

Proof Assume in the contrary that two threads can be in their critical section at the same time. From the code we see: (*) write 0 (flag[0]=true)  write 0 (victim=0)  read 0 (flag[1])  read 0 (victim)  CS 0 write 1 (flag[1]=true)  write 1 (victim=1)  read 1 (flag[0])  read 1 (victim)  CS 1 Thread 0 flag[0] = true victim = 0 while (flag[1] and victim == 0) {skip} critical section flag[0] = false Thread 1 flag[1] = true victim = 1 while (flag[0] and victim == 1) {skip} critical section flag[1] = false

Proof Assume that the last thread to write to victim was 0. Then: write 1 (victim=1)  write 0 (victim=0) This implies that thread 0 read that victim=0 in equation (*) Since thread 0 is in the critical section, it must have read flag[1] as false, so: write 0 (victim=0)  read 0 (flag[1]==false) Thread 0 flag[0] = true victim = 0 while (flag[1] and victim == 0) {skip} critical section flag[0] = false Thread 1 flag[1] = true victim = 1 while (flag[0] and victim == 1) {skip} critical section flag[1] = false

Proof Then, we get: write 1 (flag[1]=true)  write 1 (victim=1)  write 0 (victim=0)  read 0 (flag[1]==false) Thus: write 1 (flag[1]=true)  read 0 (flag[1]==false) There was no other write to flag[1] before the critical section execution and this yields a contradiction. Thread 0 flag[0] = true victim = 0 while (flag[1] and victim == 0) {skip} critical section flag[0] = false Thread 1 flag[1] = true victim = 1 while (flag[0] and victim == 1) {skip} critical section flag[1] = false

Starvation freedom Peterson’s algorithm is starvation-free

Proof Assume to the contrary that the algorithm is not starvation-free Then one of the threads, say thread 0, is forced to remain in its entry code forever Thread 0 flag[0] = true victim = 0 while (flag[1] and victim == 0) {skip} critical section flag[0] = false Thread 1 flag[1] = true victim = 1 while (flag[0] and victim == 1) {skip} critical section flag[1] = false

Proof This implies that at some later point thread 1 will do one of the following three things: 1. Stay in its remainder forever 2. Stay in its entry code forever, not succeeding and proceeding into its critical section 3. Repeatedly enter and exit its critical section Thread 0 flag[0] = true victim = 0 while (flag[1] and victim == 0) {skip} critical section flag[0] = false Thread 1 flag[1] = true victim = 1 while (flag[0] and victim == 1) {skip} critical section flag[1] = false We’ll show that each of the three possible cases leads to a contradiction.

Proof In the first case flag[1] is false, and hence thread 0 can proceed. The second case is impossible since victim is either 0 or 1, and hence it always enables at least one of the threads to proceed. In the third case, when thread 1 exit its critical section and tries to enter its critical section again, it will set victim to 1 and will never change it back to 0, enabling thread 0 to proceed. Thread 0 flag[0] = true victim = 0 while (flag[1] and victim == 0) {skip} critical section flag[0] = false Thread 1 flag[1] = true victim = 1 while (flag[0] and victim == 1) {skip} critical section flag[1] = false

Kessels’ single-writer Algorithm What if we replace the multi-writer register victim with two single- writer registers. What is new algorithm? Answer (Kessels’ Alg.) victim = 0  victim[0] =victim[1] victim = 1  victim[0]  victim[1]

Kessels’ single-writer Algorithm Thread 0 flag[0] = true local[0] = victim[1] victim[0] = local[0] while (flag[1] and local[0]=victim[1]) {skip} critical section flag[0] = false Thread 1 flag[1] = true local[1]=1-victim[0] victim[1] = local[1] while (flag[0] and local[1]  victim[0])) {skip} critical section flag[1] = false Thread 0 can write the registers victim[0] and flag[0] and read the registers victim[1] and flag[1] Thread 1 can write the registers victim[1] and flag[1] and read the registers victim[0] and flag[0]

Solutions for Many Threads How can we use a two-thread algorithm to construct an algorithm for many threads?

Tournament Algorithms

A simple method which enables the construction an algorithm for n threads from any given algorithm for two threads. Each thread is progressing from the leaf to the root, where at each level of the tree it participates in a two thread mutual exclusion algorithm. As a thread advanced towards the root, it plays the role of thread 0 when it arrives from the left subtree, or of thread 1 when it arrives from the right subtree.

The Filter Algorithm for n Threads A direct generalization of Peterson’s algorithm to multiple threads. The Peterson algorithm used a two-element boolean flag array to indicate whether a thread is interested in entering the critical section. The filter algorithm generalizes this idea with an N-element integer level array, where the value of level[i] indicates the latest level that thread i is interested in entering. ncs cs level n-1

Filter There are n-1 “waiting rooms” called levels At each level – At least one enters level – At least one blocked if many try Only one thread makes it through ncs cs level 0 level n-1

The Filter Algorithm Thread i for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((  k != i level[k] >= L) and victim[L] == i ) {} } critical section level[i] = 0;

Thread i for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((  k != i level[k] >= L) and victim[L] == i ) {} } critical section level[i] = 0; Filter One level at a time

Filter Thread i for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((  k != i level[k] >= L) and victim[L] == i ) {} } critical section level[i] = 0; Announce intention to enter level L

Filter Thread i for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((  k != i level[k] >= L) and victim[L] == i ) {} } critical section level[i] = 0; Give priority to anyone but me (at every level)

Filter Thread i for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((  k != i level[k] >= L) and victim[L] == i ) {} } critical section level[i] = 0; Wait as long as someone else is at same or higher level, and I’m designated victim. Thread enters level L when it completes the loop.

Claim There are at most n-L threads enter level L Proof: by induction on L and by contradiction At L=0 – trivial Assume that there are at most n-L+1 threads at level L-1. Assume that there are n-L+1 threads at level L Let A be the last thread to write victim[L] and B any other thread at level L

Proof structure ncs cs Assumed to enter L-1 By way of contradiction all enter L n-L+1 = 4 A B Last to write victim[L] Show that A must have seen B at level L and since victim[L] == A could not have entered

Proof From the code we get: From the assumption: write B (level[B]=L)  write B (victim[L]=B) write A (victim[L]=A)  read A (level[B]) write B (victim[L]=B)  write A (victim[L]=A) for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((  k != i level[k] >= L) and victim[L] == i ) {} } critical section level[i] = 0;

Proof When combining all we get: Since B is at level L, when A reads level[B], it reads a value greater than or equal L and so A couldn’t completed its loop and still waiting (remember that victim=A), a contradiction. write B (level[B]=L)  read A (level[B]) for (int L = 1; L < n; L++) { level[i] = L; victim[L] = i; while ((  k != i level[k] >= L) and victim[L] == i ) {} } critical section level[i] = 0;

A conclusion The filter algorithm satisfies mutual exclusion At level n-1 there are at most n-(n-1)=1 threads, which means at most one thread in the critical section

Starvation-freedom Filter Lock satisfies properties: – Just like Peterson algorithm at any level – So no one starves

Fairness Starvation freedom guarantees that if a thread is trying to enter its critical section, it will eventually do so There is no guarantee about how long it will take We wish for fairness: if thread A enters the entry code before thread B, then A should enter the critical section first

Bounded waiting We divide our method into two parts: Doorway interval: - Written D A - always finishes in finite steps Waiting interval: - Written W A - may take unbounded steps entry code exit code critical section remainder doorway waiting

The mutual exclusion problem Mutual Exclusion Deadlock-freedom Starvation-freedom FIFO

r-Bounded Waiting For threads A and B: – If D A k  D B j A’s k-th doorway precedes B’s j-th doorway – Then CS A k  CS B j+r A’s k-th critical section precedes B’s (j+r)-th critical section B cannot overtake A by more than r times First-come-first-served means r = 0.

Fairness in Filter Algorithm Filter satisfies properties: – No one starves – But very weak fairness Not r-bounded for any r! – That’s pretty lame…

Bakery Algorithm The idea is similar to a line at the bakery A customer takes a number greater than numbers of other customers Each of the threads gets a unique identifier

Bakery Algorithm Thread i flag[i]=true; number[i] = max(number[0], …,number[n-1])+1; while (  k!= i flag[k] && (number[i],i) > (number[k],k)) {}; critical section flag[i] = false;

Bakery Algorithm flag[i]=true; number[i] = max(number[0], …,number[n-1])+1; while (  k!= i flag[k] && (number[i],i) > (number[k],k)) {}; critical section flag[i] = false; Doorway

Bakery Algorithm flag[i]=true; number[i] = max(number[0], …,number[n-1])+1; while (  k!= i flag[k] && (number[i],i) > (number[k],k)) {}; critical section flag[i] = false; I’m interested

Bakery Algorithm flag[i]=true; number[i] = max(number[0], …,number[n-1])+1; while (  k!= i flag[k] && (number[i],i) > (number[k],k)) {}; critical section flag[i] = false; Take an number numbers are always increasing!

Bakery Algorithm flag[i]=true; number[i] = max(number[0], …,number[n-1])+1; while (  k!= i flag[k] && (number[i],i) > (number[k],k)) {}; critical section flag[i] = false; Someone is interested

Bakery Algorithm flag[i]=true; number[i] = max(number[0], …,number[n-1])+1; while (  k!= i flag[k] && (number[i],i) > (number[k],k)) {}; critical section flag[i] = false; There is someone with a lower number and identifier. pair (a,b) > (c,d) if a>c, or a=c and b>d (lexicographic order)

Deadlock freedom The bakery algorithm is deadlock free Some waiting thread A has a unique least (number[A],A) pair, and that thread can enter the critical section

FIFO The bakery algorithm is first-come-first- served If D A  D B then A’s number is earlier – write A (number[A])  read B (number[A])  write B (number[B])  read B (flag[A]) So B is locked out while flag[A] is true flag[i]=true; number[i] = max(number[0], …,number[n-1])+1; while (  k!= i flag[k] && (number[i],i) > (number[k],k)) {}; critical section flag[i] = false;

Starvation freedom The bakery algorithm satisfies deadlock freedom and first-come-first-served and those properties implies starvation freedom

Mutual Exclusion Suppose A and B in CS together Suppose A has an earlier number When B entered, it must have seen – flag[A] is false, or – number[A] > number[B] flag[i]=true; number[i] = max(number[0], …,number[n-1])+1; while (  k!= i flag[k] && (number[i],i) > (number[k],k)) {}; critical section flag[i] = false;

Mutual Exclusion numbers are strictly increasing so B must have seen (flag[A] == false) numbering B  read B (flag[A])  write A (flag[A])  numbering A Which contradicts the assumption that A has an earlier number flag[i]=true; number[i] = max(number[0], …,number[n-1])+1; while (  k!= i flag[k] && (number[i],i) > (number[k],k)) {}; critical section flag[i] = false;

The End