Outline Announcements Basic Synchronization Principles continued Semaphores Boundedbuffer
Outline • Announcements • Basic Synchronization Principles – continued – Semaphores – Bounded-buffer problem – Read-writer’s problem Please turn in Homework #2 12/24/2021 COP 4610 1
Announcements • The second quiz will be at the end of class on this Thursday – October 9, 2003 – It will be closed-book and closed-note – It will cover the materials until today with emphasis on scheduling – It requires to compute average wait time and turnaround time (or something like that) and you need a calculator 12/24/2021 COP 4610 2
Announcements – cont. • Demonstration of Lab 1 – You can sign up to demonstrate your program tomorrow during the recitation session – During the demo, Mr. Chen will ask you questions besides demonstration 12/24/2021 COP 4610 3
Comments on Scheduling Algorithms Process Arrival Time P 1 0. 0 7 P 2 2. 0 4 P 3 4. 0 1 P 4 5. 0 4 • Wait time and turnaround time • Round robin Burst Time – Where should we place the newly arrived ones? 12/24/2021 COP 4610 4
Interacting Processes - review • Independent process – Cannot affect or be affected by the other processes in the system – Does not share any data with other processes • Interacting process – Can affect or be affected by the other processes – Shares data with other processes – We focus on interacting processes through physically or logically shared memory 12/24/2021 COP 4610 5
Bounded-Buffer – review 12/24/2021 COP 4610 6
Bounded-Buffer - cont. • Suppose we have one producer and one consumer, the variable counter is 5 – Producer: counter = counter +1 P 1: load counter, r 1 P 2: add r 1, #1, r 2 P 3: store r 2, counter – Consumer: counter = counter - 1 C 1: load counter, r 1 C 2: add r 1, #-1, r 2 C 3: store r 2, counter 12/24/2021 COP 4610 7
Bounded-Buffer - cont. • A particular execution sequence – P 1: load counter, r 1 – P 2: add r 1, #1, r 2 --- Context switch ---– C 1: load counter, r 1 – C 2: add r 1, #-1, r 2 – C 3: store r 2, counter --- Context switch ---– P 3: store r 2, counter – What is the value of counter? 12/24/2021 COP 4610 8
Bounded-Buffer - cont. • A particular execution sequence – C 1: load counter, r 1 – C 2: add r 1, #-1, r 2 --- Context switch ---– P 1: load counter, r 1 – P 2: add r 1, #1, r 2 – P 3: store r 2, counter --- Context switch ---– C 3: store r 2, counter – What is the value of counter this time? 12/24/2021 COP 4610 9
Bounded-Buffer - cont. • A particular execution sequence – C 1: load counter, r 1 – C 2: add r 1, #-1, r 2 – C 3: store r 2, counter --- Context switch ---– P 1: load counter, r 1 – P 2: add r 1, #1, r 2 – P 3: store r 2, counter --- Context switch ---– What is the value of counter this time? 12/24/2021 COP 4610 10
Race Condition • Race condition – When several processes access and manipulate the same data concurrently, there is a race among the processes – The outcome of the execution depends on the particular order in which the access takes place – This is called a race condition 12/24/2021 COP 4610 11
Traffic Intersections 12/24/2021 COP 4610 12
A Semaphore 12/24/2021 COP 4610 13
The Critical-Section Problem • n processes all competing to use some shared data • Each process has code segments, called critical section, in which the shared data is accessed. • Problem – ensure that when one process is executing in its critical section, no other process is allowed to execute in its critical section, called mutual exclusion 12/24/2021 COP 4610 14
The Critical-Section Problem – cont. • Structure of process Pi repeat entry section critical section exit section reminder section until false; 12/24/2021 COP 4610 15
Requirements for Critical-Section Solutions • Mutual Exclusion. – If process Pi is executing in its critical section, then no other processes can be executing in their critical sections. • Progress – If no process is executing in its critical section and there exist some processes that wish to enter their critical section, then the selection of the processes that will enter the critical section next cannot be postponed indefinitely. • Bounded Waiting – A bound must exist on the number of times that other processes are allowed to enter their critical sections after a process has made a request to enter its critical section and before that request is granted. 12/24/2021 COP 4610 16
Solution through Disabling Interrupts • In a uni-processor system, an interrupt causes the race condition – The scheduler can be called in the interrupt handler, resulting in context switch and data inconsistency 12/24/2021 COP 4610 17
Solution through Disabling Interrupts – cont. • Process Pi repeat disable. Interrupts(); //entry section critical section enable. Interrupts(); //exit section reminder section until false; 12/24/2021 COP 4610 18
Solution through Disabling Interrupts – cont. 12/24/2021 COP 4610 19
Solution through Disabling Interrupts – cont. • This solution may affect the behavior of the I/O system – Interrupts can be disabled for an arbitrarily long time • The interrupts can be disabled permanently if the program contains an infinite loop in its critical section – User programs are not allowed to enable and disable interrupts directly • However, if the operating system can provide system calls, a user can use the system calls for synchronization – Called semaphores and related system calls 12/24/2021 COP 4610 20
Software Attempt to Solve the Problem • Only 2 processes, P 1 and P 2 • General structure of process Pi (other process Pj) repeat entry section critical section exit section reminder section until false; • Processes may share some common variables to synchronize their actions. 12/24/2021 COP 4610 21
Algorithm 1 • Shared variables: – var turn: (0. . 1); initially turn = 0 – turn - i Pi can enter its critical section • Process Pi repeat while turn i do no-op; critical section turn : = j; reminder section until false; • Satisfies mutual exclusion, but not progress 12/24/2021 COP 4610 22
Algorithm 2 • Shared variables – var flag: array [0. . 1] of boolean; initially flag [0] = flag [1] = false. – flag [i] = true Pi ready to enter its critical section • Process Pi repeat flag[i] : = true; while flag[j] do no-op; critical section flag [i] : = false; remainder section until false; • Satisfies mutual exclusion, but not progress requirement. 12/24/2021 COP 4610 23
Algorithm 2 – version 1 • Shared variables – var flag: array [0. . 1] of boolean; initially flag [0] = flag [1] = false. – flag [i] = true Pi ready to enter its critical section • Process Pi repeat while flag[j] do no-op; flag[i] : = true; critical section flag [i] : = false; remainder section until false; • Does not satisfy mutual exclusion 12/24/2021 COP 4610 24
Algorithm 3 • Combined shared variables of algorithms 1 and 2. • Process Pi repeat flag [i] : = true; turn : = j; while (flag [j] and turn = j) do no-op; critical section flag [i] : = false; remainder section until false; • Meets all three requirements; solves the critical-section problem for two processes. 12/24/2021 COP 4610 25
Bakery Algorithm Critical section for n processes • Before entering its critical section, process receives a number. Holder of the smallest number enters the critical section. • If processes Pi and Pj receive the same number, if i < j, then Pi is served first; else Pj is served first. • The numbering scheme always generates numbers in increasing order of enumeration; i. e. , 1, 2, 3, 3, 4, 5. . . 12/24/2021 COP 4610 26
Bakery Algorithm – cont. • Notation < lexicographical order (ticket #, process id #) – (a, b) < c, d) if a < c or if a = c and b < d – max (a 0, …, an-1) is a number, k, such that k ai for i - 0, …, n – 1 • Shared data var choosing: array [0. . n – 1] of boolean; number: array [0. . n – 1] of integer, Data structures are initialized to false and 0 respectively 12/24/2021 COP 4610 27
Bakery Algorithm (Cont. ) repeat choosing[i] : = true; number[i] : = max(number[0], number[1], …, number [n – 1])+1; choosing[i] : = false; for j : = 0 to n – 1 do begin while choosing[j] do no-op; while number[j] 0 and (number[j], j) < (number[i], i) do no-op; end; critical section number[i] : = 0; remainder section until false; 12/24/2021 COP 4610 28
Algorithm 4 • Shared variables: – boolean lock; initially lock = FALSE – lock is FALSE Pi can enter its critical section • Process P 1 Process P 2 repeat while (lock) do no-op; lock = TRUE; critical section lock = FALSE; reminder section until false; repeat while (lock) do no-op; lock = TRUE; critical section lock = FALSE reminder section until false; 12/24/2021 COP 4610 29
Busy Wait Condition shared boolean lock = FALSE; shared double balance; Code for p 1 Code for p 2 COP 4610 Interrupt lock = FALSE Interrupt 12/24/2021 lock = TRUE p 2 p 1 /* Acquire the lock */ while(lock) ; lock = TRUE; /* Execute critical sect */ balance = balance - amount; /* Release lock */ lock = FALSE; Blocked at while /* Acquire the lock */ while(lock) ; lock = TRUE; /* Execute critical sect */ balance = balance + amount; /* Release lock */ lock = FALSE; 30
Synchronization Hardware • Test and modify the content of a word atomically (indivisibly) – The procedure cannot be interrupted until it has completed the routine – Implemented as a test-and-set instruction boolean Test-and-Set (boolean target) { boolean tmp = target; target = true; return tmp; } 12/24/2021 COP 4610 31
Test and Set Instruction – cont. • TS(m): [Reg_i = memory[m]; memory[m] = TRUE; ] Data CC Register R 3 … m FALSE Primary Memory (a) Before Executing TS 12/24/2021 FALSE =0 TRUE Primary Memory (b) After Executing TS COP 4610 32
Mutual Exclusion with Test-and-Set • Shared data: boolean lock ; – Initially false • Process Pi repeat while Test-and-Set (lock) do no-op; critical section lock = false; remainder section until false; 12/24/2021 COP 4610 33
Semaphores • Semaphore S – integer variable • can only be accessed via two indivisible (atomic) operations – As if they were a single machine instruction wait (S): while S 0 do no-op; S : = S – 1; signal (S): S : = S + 1; 12/24/2021 COP 4610 34
Two Types of Semaphores • Counting semaphore – integer value can range over an unrestricted domain. • Binary semaphore – integer value can range only between 0 and 1 – Can be simpler to implement. • Can implement a counting semaphore S using binary semaphores. 12/24/2021 COP 4610 35
Example: Critical Section of n Processes • Shared variables – var mutex : semaphore – initially mutex = 1 • Process Pi repeat wait(mutex); critical section signal(mutex); remainder section until false; 12/24/2021 COP 4610 36
Shared Account Balance Problem Proc_0() {. . . /* Enter the CS */ P(mutex); balance += amount; V(mutex); . . . } proc_1() {. . . /* Enter the CS */ P(mutex); balance -= amount; V(mutex); . . . } semaphore mutex = 1; fork(proc_0, 0); fork(proc_1, 0); 12/24/2021 COP 4610 37
Sharing Two Variables proc_A() { while(TRUE) { <compute section A 1>; update(x); /* Signal proc_B */ V(s 1); <compute section A 2>; /* Wait for proc_B */ P(s 2); retrieve(y); } } proc_B() { while(TRUE) { /* Wait for proc_A */ P(s 1); retrieve(x); <compute section B 1>; update(y); /* Signal proc_A */ V(s 2); <compute section B 2>; } } semaphore s 1 = 0; semaphore s 2 = 0; fork(proc_A, 0); fork(proc_B, 0); 12/24/2021 COP 4610 38
Bounded Buffer Problem Empty Pool Producer Consumer Full Pool 12/24/2021 COP 4610 39
Bounded Buffer Problem – cont. producer() { consumer() { buf_type *next, *here; while(TRUE) { produce_item(next); /* Claim full buffer */ /* Claim an empty */ P(full); P(empty); P(mutex); here = obtain(full); here = obtain(empty); V(mutex); copy_buffer(here, next); copy_buffer(next, here); P(mutex); release(here, empty. Pool); release(here, full. Pool); V(mutex); /* Signal an empty buffer */ /* Signal a full buffer */ V(empty); V(full); consume_item(next); } } semaphore mutex = 1; semaphore full = 0; /* A general (counting) semaphore */ semaphore empty = N; /* A general (counting) semaphore */ buf_type buffer[N]; fork(producer, 0); fork(consumer, 0); 12/24/2021 COP 4610 40
Bounded Buffer Problem – cont. producer() { consumer() { buf_type *next, *here; while(TRUE) { produce_item(next); /* Claim full buffer */ /* Claim an empty */ P(full); P(empty); P(mutex); here = obtain(full); here = obtain(empty); V(mutex); copy_buffer(here, next); copy_buffer(next, here); P(mutex); release(here, empty. Pool); release(here, full. Pool); V(mutex); /* Signal an empty buffer */ /* Signal a full buffer */ V(empty); V(full); consume_item(next); } } semaphore mutex = 1; semaphore full = 0; /* A general (counting) semaphore */ semaphore empty = N; /* A general (counting) semaphore */ buf_type buffer[N]; fork(producer, 0); fork(consumer, 0); 12/24/2021 COP 4610 41
Bounded Buffer Problem – cont. consumer() { producer() { buf_type *next, *here; while(TRUE) { /* Claim full buffer */ produce_item(next); P(mutex); /* Claim an empty */ P(full); P(empty); here = obtain(full); P(mutex); V(mutex); here = obtain(empty); copy_buffer(here, next); V(mutex); P(mutex); copy_buffer(next, here); release(here, empty. Pool); P(mutex); V(mutex); release(here, full. Pool); /* Signal an empty buffer */ V(mutex); V(empty); /* Signal a full buffer */ consume_item(next); V(full); } } semaphore mutex = 1; semaphore full = 0; /* A general (counting) semaphore */ semaphore empty = N; /* A general (counting) semaphore */ buf_type buffer[N]; fork(producer, 0); fork(consumer, 0); 12/24/2021 COP 4610 42
Readers-Writers Problem Writers Readers 12/24/2021 COP 4610 43
Readers-Writers Problem (2) Writer Writer Reader Reader Shared Resource 12/24/2021 COP 4610 44
Readers-Writers Problem (3) Writer Writer Reader Reader Shared Resource 12/24/2021 COP 4610 45
Readers-Writers Problem (4) Reader Reader Writer Writer Shared Resource 12/24/2021 COP 4610 46
Readers-writers with active readers 12/24/2021 COP 4610 47
First and Second Policy 12/24/2021 COP 4610 48
First Solution writer() { reader() { while(TRUE) { <other computing>; P(write. Block); P(mutex); /* Critical section */ read. Count++; access(resource); if(read. Count == 1) V(write. Block); P(write. Block); } V(mutex); } /* Critical section */ access(resource); P(mutex); read. Count--; • First reader competes with writers if(read. Count == 0) V(write. Block); • Last reader signals writers V(mutex); } } resource. Type *resource; int read. Count = 0; semaphore mutex = 1; semaphore write. Block = 1; fork(reader, 0); fork(writer, 0); 12/24/2021 COP 4610 49
First Solution (2) reader() { while(TRUE) { <other computing>; P(mutex); read. Count++; if(read. Count == 1) P(write. Block); V(mutex); /* Critical section */ access(resource); P(mutex); read. Count--; if(read. Count == 0) V(write. Block); V(mutex); } } resource. Type *resource; int read. Count = 0; semaphore mutex = 1; semaphore write. Block = 1; fork(reader, 0); fork(writer, 0); 12/24/2021 writer() { while(TRUE) { <other computing>; P(write. Block); /* Critical section */ access(resource); V(write. Block); } } • First reader competes with writers • Last reader signals writers • Any writer must wait for all readers • Readers can starve writers • “Updates” can be delayed forever • May not be what we want COP 4610 50
Writer Precedence reader() { while(TRUE) { <other computing>; 4 P(read. Block); P(mutex 1); read. Count++; if(read. Count == 1) P(write. Block); V(mutex 1); V(read. Block); 2 1 access(resource); P(mutex 1); read. Count--; if(read. Count == 0) V(write. Block); V(mutex 1); writer() { while(TRUE) { <other computing>; P(mutex 2); write. Count++; if(write. Count == 1) P(read. Block); 3 V(mutex 2); P(write. Block); access(resource); V(write. Block); P(mutex 2) write. Count--; if(write. Count == 0) V(read. Block); V(mutex 2); } } int read. Count = 0, write. Count = 0; semaphore mutex = 1, mutex 2 = 1; semaphore read. Block = 1, write. Pending = 1; fork(reader, 0); 12/24/2021 COP 4610 51 fork(writer, 0);
Writer Precedence (2) reader() { writer() { while(TRUE) { <other computing>; P(mutex 2); 4 P(write. Pending); P(read. Block); write. Count++; P(mutex 1); if(write. Count == 1) read. Count++; P(read. Block); 3 if(read. Count == 1) V(mutex 2); 2 P(write. Block); V(mutex 1); access(resource); V(read. Block); V(write. Block); 1 V(write. Pending); P(mutex 2) access(resource); write. Count--; P(mutex 1); if(write. Count == 0) read. Count--; V(read. Block); if(read. Count == 0) V(mutex 2); V(write. Block); } V(mutex 1); } } } int read. Count = 0, write. Count = 0; semaphore mutex = 1, mutex 2 = 1; semaphore read. Block = 1, write. Pending = 1; fork(reader, 0); 12/24/2021 COP 4610 52 fork(writer, 0);
The Sleepy Barber • Barber can cut one person’s hair at a time • Other customers wait in a waiting room Entrance to Waiting Room (sliding door) Shop Exit Entrance to Barber’s Room (sliding door) Waiting Room 12/24/2021 COP 4610 53
Sleepy Barber customer() { while(TRUE) { customer = next. Customer(); if(empty. Chairs == 0) continue; P(chair); P(mutex); empty. Chairs--; take. Chair(customer); V(mutex); V(waiting. Customer); } } barber() { while(TRUE) { P(waiting. Customer); P(mutex); empty. Chairs++; take. Customer(); V(mutex); V(chair); } } semaphore mutex = 1, chair = N, waiting. Customer = 0; int empty. Chairs = N; fork(customer, 0); fork(barber, 0); 12/24/2021 COP 4610 54
Implementing Semaphores • Minimize effect on the I/O system • Processes are only blocked on their own critical sections (not critical sections that they should not care about) • If disabling interrupts, be sure to bound the time they are disabled 12/24/2021 COP 4610 55
Implementing Semaphores Using Interrupts class semaphore { int value; public: semaphore(int v = 1) { value = v; }; P(){ disable. Interrupts(); while(value == 0) { enable. Interrupts(); disable. Interrupts(); } value--; enable. Interrupts(); }; V(){ disable. Interrupts(); value++; enable. Interrupts(); }; }; 12/24/2021 COP 4610 56
Using the TS Instruction boolean s = FALSE; . . . while(TS(s)) ; <critical section> s = FALSE; . . . 12/24/2021 semaphore s = 1; . . . P(s) ; <critical section> V(s); . . . COP 4610 57
Implementing the General Semaphore struct semaphore { int value = <initial value>; boolean mutex = FALSE; boolean hold = TRUE; }; shared struct semaphore s; P(struct semaphore s) { while(TS(s. mutex)) ; s. value--; if(s. value < 0) ( s. mutex = FALSE; while(TS(s. hold)) ; } else s. mutex = FALSE; } 12/24/2021 V(struct semaphore s) { while(TS(s. mutex)) ; s. value++; if(s. value <= 0) ( while(!s. hold) ; s. hold = FALSE; } s. mutex = FALSE; } COP 4610 58
Semaphore Implementation – cont. • Semaphores implemented using interrupt disabling and test-and-set require busy waiting – This type of semaphores is often called spinlock 12/24/2021 COP 4610 59
Semaphore Implementation – cont. • Define a semaphore as a structure typedef struct { int value; queue L; } semaphore; • Assume two simple operations: – block suspends the process that invokes it. – wakeup(P) resumes the execution of a blocked process P. 12/24/2021 COP 4610 60
Semaphore Implementation - cont. • Semaphore operations now defined as P(S): S. value = S. value – 1; if S. value < 0 then begin add this process to S. L; block; end; 12/24/2021 COP 4610 61
Semaphore Implementation - cont. V(S): S. value = S. value + 1; if S. value 0 then begin remove a process P from S. L; wakeup(P); end; 12/24/2021 COP 4610 62
Semaphore Implementation - cont. • Semaphores are resources in the above implementation 12/24/2021 COP 4610 63
Issues Using Semaphores • Deadlock – two or more processes are waiting indefinitely for an event that can be caused by only one of the waiting processes. • Let S and Q be two semaphores initialized to 1 P 0 P(S); P(Q); V(S); V(Q) P 1 P(Q); P(S); V(Q); V(S); • Starvation – indefinite blocking – A process may never be removed from the semaphore queue in which it is suspended. 12/24/2021 COP 4610 64
Active vs. Passive Semaphores • A process can dominate the semaphore – Performs V operation, but continues to execute – Performs another P operation before releasing the CPU – Called a passive implementation of V • Active implementation calls scheduler as part of the V operation. – Changes semantics of semaphore! – Cause people to rethink solutions 12/24/2021 COP 4610 65
Summary • Processes that share data need to be synchronized – Otherwise, a race condition may exist • Semaphores are the basic mechanism underlying synchronization and can be used to solve different synchronization problems – Critical section problem – Bounded-buffer problem – Readers-writers problem 12/24/2021 COP 4610 66
- Slides: 66