Chapter 5: Process Synchronization Operating System Concepts Essentials – 2nd Edition Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.2 Silberschatz, Galvin and Gagne ©2013 Objectives Present concept of process synchronization. Introduce critical-section problem Solutions ensure consistency of shared data Present SW and HW solutions of critical-section problem Examine several classical process-synchronization problems Explore several tools used to solve process synchronization problems Operating System Concepts Essentials – 2nd Edition 5.3 Silberschatz, Galvin and Gagne ©2013 Background Processes can execute concurrently Can be interrupted at any time... Partially complete execution Concurrent access to shared data may result in data inconsistency Maintaining data consistency requires mechanisms to ensure orderly execution of cooperating processes Operating System Concepts Essentials – 2nd Edition 5.4 Silberschatz, Galvin and Gagne ©2013 Background E.g., producer-consumer problem: Fills all items in array counter keeps track of # items in buffer Initially, counter set to 0 counter incremented by producer after it produces counter decremented by consumer after it consumes Operating System Concepts Essentials – 2nd Edition 5.5 Silberschatz, Galvin and Gagne ©2013 Producer while (true) { /* produce an item in next produced */ while (counter == BUFFER_SIZE) ; /* do nothing */ buffer[in] = next_produced; in = (in + 1) % BUFFER_SIZE; counter++; } Operating System Concepts Essentials – 2nd Edition 5.6 Silberschatz, Galvin and Gagne ©2013 Consumer while (true) { while (counter == 0) ; /* do nothing */ next_consumed = buffer[out]; out = (out + 1) % BUFFER_SIZE; counter--; /* consume the item in next consumed */ } Operating System Concepts Essentials – 2nd Edition 5.7 Silberschatz, Galvin and Gagne ©2013 Race Condition counter++ implemented as register1 = counter register1 = register1 + 1 counter = register1 counter-- implemented as register2 = counter register2 = register2 – 1 counter = register2 Operating System Concepts Essentials – 2nd Edition 5.8 Silberschatz, Galvin and Gagne ©2013 Race Condition Consider this execution interleaving with “counter = 5” register1 register1 register2 register2 counter = counter = = counter = register1 + 1 = counter = register2 – 1 register1 register2 {register1 = 5} {register1 = 6} {register2 = 5} {register2 = 4} {counter = 6} {counter = 4} What should counter equal? Operating System Concepts Essentials – 2nd Edition 5.9 Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.10 Silberschatz, Galvin and Gagne ©2013 Critical Section Problem Each process has critical section of code When one process in critical section, no other may be in its critical section Critical section problem = protocol to solve this Each process must ask permission to enter critical section in entry section May follow critical section with exit section, then remainder section Operating System Concepts Essentials – 2nd Edition 5.11 Silberschatz, Galvin and Gagne ©2013 Critical Section General structure of process Pi Operating System Concepts Essentials – 2nd Edition 5.12 Silberschatz, Galvin and Gagne ©2013 Algorithm for Process Pi do { while (turn == j); critical section turn = j; remainder section } while (true); Operating System Concepts Essentials – 2nd Edition 5.13 Silberschatz, Galvin and Gagne ©2013 Solution to Critical-Section Problem 1. Mutual Exclusion - If process Pi is executing in its critical section, then no other processes can be executing in their critical sections Operating System Concepts Essentials – 2nd Edition 5.14 Silberschatz, Galvin and Gagne ©2013 Solution to Critical-Section Problem 2. Progress - If no process is executing in its critical section and there exist some processes that wish to enter their critical section, then selection of processes that will enter the critical section next cannot be postponed indefinitely Operating System Concepts Essentials – 2nd Edition 5.15 Silberschatz, Galvin and Gagne ©2013 Solution to Critical-Section Problem 3. 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 Assume each process executes at nonzero speed No assumption of relative speed of n processes Operating System Concepts Essentials – 2nd Edition 5.16 Silberschatz, Galvin and Gagne ©2013 Critical-Section Handling in OS Two approaches: Preemptive – allows preemption of process when running in kernel mode Non-preemptive – runs until exits kernel mode, blocks, or voluntarily yields CPU Free of race conditions in kernel mode Operating System Concepts Essentials – 2nd Edition 5.17 Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.18 Silberschatz, Galvin and Gagne ©2013 Peterson's Solution Algorithmic description solving the problem Two process solution (Pi and Pj) Assumes that load and store machine-language instructions are atomic Cannot be interrupted Operating System Concepts Essentials – 2nd Edition 5.19 Silberschatz, Galvin and Gagne ©2013 Peterson's Solution Two processes (Pi , Pj) share two variables: int turn; boolean flag[2]; turn indicates who can enter critical section flag array used to indicate if process is ready to enter critical section e.g., flag[i] = true means Pi is ready Operating System Concepts Essentials – 2nd Edition 5.20 Silberschatz, Galvin and Gagne ©2013 Algorithm for Process Pi do { flag[i] = true; turn = j; while (flag[j] && turn == j); //critical section flag[i] = false; //remainder section } while (true); Operating System Concepts Essentials – 2nd Edition 5.21 Silberschatz, Galvin and Gagne ©2013 Algorithm for Process Pj do { flag[j] = true; turn = i; while (flag[i] && turn == i); //critical section flag[j] = false; //remainder section } while (true); Operating System Concepts Essentials – 2nd Edition 5.22 Silberschatz, Galvin and Gagne ©2013 Algorithm for Process Pi and Pj do { Pi flag[i] = true; turn = j; while (flag[j] && turn == j); //critical section flag[i] = false; //remainder section } while (true); do { Pj flag[j] = true; turn = i; while (flag[i] && turn == i); //critical section flag[j] = false; //remainder section } while (true); Operating System Concepts Essentials – 2nd Edition 5.23 Silberschatz, Galvin and Gagne ©2013 Peterson's Solution (Cont.) do { 1. Mutual exclusion: Pi enters critical section if either: – flag[j] == false OR – flag[i] = true; turn = j; while (flag[j] && turn == j); //critical section flag[i] = false; //remainder section } while (true); turn == i do { flag[j] = true; turn = i; while (flag[i] && turn == i); //critical section flag[j] = false; //remainder section } while (true); Operating System Concepts Essentials – 2nd Edition 5.24 Silberschatz, Galvin and Gagne ©2013 Peterson's Solution (Cont.) do { 1. Mutual exclusion: Pj enters critical section if either: – flag[i] == false OR – flag[i] = true; turn = j; while (flag[j] && turn == j); //critical section flag[i] = false; //remainder section } while (true); turn == j do { flag[j] = true; turn = i; while (flag[i] && turn == i); //critical section flag[j] = false; //remainder section } while (true); Operating System Concepts Essentials – 2nd Edition 5.25 Silberschatz, Galvin and Gagne ©2013 Peterson's Solution (Cont.) do { 1. Mutual exclusion: turn cannot equal i AND j at same time ==> mutual exclusion preserved flag[i] = true; turn = j; while (flag[j] && turn == j); //critical section flag[i] = false; //remainder section } while (true); do { flag[j] = true; turn = i; while (flag[i] && turn == i); //critical section flag[j] = false; //remainder section } while (true); Operating System Concepts Essentials – 2nd Edition 5.26 Silberschatz, Galvin and Gagne ©2013 Peterson's Solution (Cont.) do { 2. Progress: Pi exits critical section (CS) flag[i] Pj set to false can enter CS flag[i] = true; turn = j; while (flag[j] && turn == j); //critical section flag[i] = false; //remainder section } while (true); do { flag[j] = true; turn = i; while (flag[i] && turn == i); //critical section flag[j] = false; //remainder section } while (true); Operating System Concepts Essentials – 2nd Edition 5.27 Silberschatz, Galvin and Gagne ©2013 Peterson's Solution (Cont.) do { 2. Progress: Pj exits critical section (CS) flag[j] Pi set to false can enter CS flag[i] = true; turn = j; while (flag[j] && turn == j); //critical section flag[i] = false; //remainder section } while (true); do { flag[j] = true; turn = i; while (flag[i] && turn == i); //critical section flag[j] = false; //remainder section } while (true); Operating System Concepts Essentials – 2nd Edition 5.28 Silberschatz, Galvin and Gagne ©2013 Peterson's Solution (Cont.) 2. Progress ... selection of processes that will enter the critical section next cannot be postponed indefinitely do { flag[i] = true; turn = j; while (flag[j] && turn == j); //critical section flag[i] = false; //remainder section } while (true); do { Progress preserved! Operating System Concepts Essentials – 2nd Edition flag[j] = true; turn = i; while (flag[i] && turn == i); //critical section flag[j] = false; //remainder section } while (true); 5.29 Silberschatz, Galvin and Gagne ©2013 Peterson's Solution (Cont.) 3. Bounded waiting Processes will wait no more than 1 turn When Pi exits CS, allows Pj to run When Pj exists CS, allows Pi to run Operating System Concepts Essentials – 2nd Edition do { flag[i] = true; turn = j; while (flag[j] && turn == j); //critical section flag[i] = false; //remainder section } while (true); do { flag[j] = true; turn = i; while (flag[i] && turn == i); //critical section flag[j] = false; //remainder section } while (true); 5.30 Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.31 Silberschatz, Galvin and Gagne ©2013 Synchronization Hardware Many systems provide hardware support for implementing critical section code. All solutions based on idea of locking Protect critical regions via locks Uniprocessors –disable interrupts Running code would execute without preemption Generally too inefficient on multiprocessor systems Not scalable Operating System Concepts Essentials – 2nd Edition 5.32 Silberschatz, Galvin and Gagne ©2013 Synchronization Hardware Modern machines provide special atomic hardware instructions Either test memory word and set value Or swap contents of two memory words Operating System Concepts Essentials – 2nd Edition 5.33 Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.34 Silberschatz, Galvin and Gagne ©2013 Mutex Locks Hardware solutions are complicated Generally inaccessible to application programmers OS designers built software tools to solve critical section problem Simplest is mutex lock Operating System Concepts Essentials – 2nd Edition 5.35 Silberschatz, Galvin and Gagne ©2013 Mutex Locks Protect critical section by acquiring then releasing lock Boolean variable indicating lock availability Calls to acquire() and release() must be atomic Usually implemented via hardware atomic instructions This solution requires busy waiting This lock called a spinlock Operating System Concepts Essentials – 2nd Edition 5.36 Silberschatz, Galvin and Gagne ©2013 acquire() and release() acquire() { while (!available); /* busy wait */ available = false; } release() { available = true; } Operating System Concepts Essentials – 2nd Edition 5.37 Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.38 Silberschatz, Galvin and Gagne ©2013 Semaphore More sophisticated ways (than Mutex locks) for processes to synchronize Semaphore S – integer variable Can only be accessed via two atomic operations wait() and signal() Originally called P() and V() Operating System Concepts Essentials – 2nd Edition 5.39 Silberschatz, Galvin and Gagne ©2013 Semaphore wait(S) { while (S <= 0); // busy wait S--; } signal(S) { S++; } Operating System Concepts Essentials – 2nd Edition 5.40 Silberschatz, Galvin and Gagne ©2013 Semaphore Usage Counting semaphore – integer value can range over unrestricted domain Binary semaphore – integer value can range only between 0 and 1 Same as mutex lock Can solve various synchronization problems Operating System Concepts Essentials – 2nd Edition 5.41 Silberschatz, Galvin and Gagne ©2013 Semaphore Usage Consider P1 and P2 that require S1 to happen before S2 Create semaphore “synch” initialized to 0 P1: S1; signal(synch); P2: wait(synch); S2; Operating System Concepts Essentials – 2nd Edition 5.42 Silberschatz, Galvin and Gagne ©2013 Semaphore Implementation Must guarantee that no two processes can execute wait() and signal()on same semaphore at same time Implementation becomes critical section problem and signal code are placed in critical section wait Could have busy waiting in critical section Implementation Little – code is short busy waiting if critical section rarely occupied not a good solution Operating System Concepts Essentials – 2nd Edition 5.43 Silberschatz, Galvin and Gagne ©2013 Semaphore Implementation with no Busy waiting Each semaphore has an integer value and an associated waiting queue typedef struct { int value; struct process *list; } semaphore; struct process *list is linked list holding waiting processes (Processes waiting on that semaphore) Operating System Concepts Essentials – 2nd Edition 5.44 Silberschatz, Galvin and Gagne ©2013 Semaphore Implementation with no Busy waiting Two operations: block – place process invoking operation on appropriate waiting queue wakeup – remove one process from waiting queue and place on ready queue Operating System Concepts Essentials – 2nd Edition 5.45 Silberschatz, Galvin and Gagne ©2013 Implementation with no Busy waiting (Cont.) wait(semaphore *S) { S->value--; if (S->value < 0) { //add this process to S->list; block(); } } signal(semaphore *S) { S->value++; if (S->value <= 0) { //remove a process P from S->list; wakeup(P); } } Operating System Concepts Essentials – 2nd Edition 5.46 Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.47 Silberschatz, Galvin and Gagne ©2013 Deadlock and Starvation Deadlock – two or more processes waiting indefinitely for event that can be caused by only one of waiting processes Let S and Q be two semaphores initialized to 1 P0 P1 wait(S); wait(Q); wait(Q); wait(S); ... ... signal(S); signal(Q); signal(Q); signal(S); Operating System Concepts Essentials – 2nd Edition 5.48 Silberschatz, Galvin and Gagne ©2013 Deadlock and Starvation Starvation – indefinite blocking Waiting process never removed from semaphore queue Priority Inversion – Lower-priority process holds lock needed by higherpriority process Operating System Concepts Essentials – 2nd Edition 5.49 Silberschatz, Galvin and Gagne ©2013 Deadlock Characterization Deadlock can arise if four conditions hold: 1. Mutual exclusion: only one process can use a resource at a time 2. Hold and wait: a process holding at least one resource is waiting to acquire additional resources held by other processes Operating System Concepts Essentials – 2nd Edition 5.50 Silberschatz, Galvin and Gagne ©2013 Deadlock Characterization Deadlock can arise if four conditions hold: 3. No preemption: a resource can be released only voluntarily by holding process, after that process has completed its task 4. Circular wait: there exists a set {P0, P1, …, Pn} of waiting processes such that P0 is waiting for a resource held by P1, P1 is waiting for a resource held by P2, …, Pn–1 is waiting for a resource held by Pn, and Pn is waiting for a resource that is held by P0. Operating System Concepts Essentials – 2nd Edition 5.51 Silberschatz, Galvin and Gagne ©2013 Resource-Allocation Graph Graph = set of vertices V and edges E V partitioned into two types: P = {P1, P2, …, Pn}, the set of all processes R = {R1, R2, …, Rm}, the set of all resources request edge – directed edge Pi Rj assignment edge – directed edge Rj Pi Operating System Concepts Essentials – 2nd Edition 5.52 Silberschatz, Galvin and Gagne ©2013 Resource-Allocation Graph (Cont.) Process Resource Type with 4 instances Pi requests instance of Rj Pi Pi is holding an instance of Rj Rj Pi Rj Operating System Concepts Essentials – 2nd Edition 5.53 Silberschatz, Galvin and Gagne ©2013 Example of a Resource Allocation Graph P1 holds instance of R2 P1 requests R1 P2 holds instance of R1 P2 holds instance of R2 P2 requests R3 P3 holds instance of R3 Operating System Concepts Essentials – 2nd Edition 5.54 Silberschatz, Galvin and Gagne ©2013 Resource Allocation Graph With A Deadlock P1 holds instance of R2 P1 requests R1 P2 holds instance of R1 P2 holds instance of R2 P2 requests R3 P3 holds instance of R3 P3 requests R2 cycle!!! deadlock!!! Operating System Concepts Essentials – 2nd Edition 5.55 Silberschatz, Galvin and Gagne ©2013 Graph With A Cycle But No Deadlock P1 holds instance of R2 P1 requests R1 P2 holds instance of R1 P3 holds instance of R1 P3 requests R2 P4 holds instance of R2 When P4 releases instance of R2, P3 will acquire R2 and break the cycle ==> no deadlock! Operating System Concepts Essentials – 2nd Edition 5.56 Silberschatz, Galvin and Gagne ©2013 Basic Facts If graph contains no cycles no deadlock If graph contains a cycle if one instance per resource, then deadlock if several instances per resource, possibility of deadlock Operating System Concepts Essentials – 2nd Edition 5.57 Silberschatz, Galvin and Gagne ©2013 Methods for Handling Deadlocks Ensure that system will never enter deadlock state: Deadlock prevention Deadlock avoidance Allow system to enter deadlock state then recover Ignore problem; pretend deadlocks never occur Used by most operating systems, including UNIX!! Operating System Concepts Essentials – 2nd Edition 5.58 Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.59 Silberschatz, Galvin and Gagne ©2013 Classical Problems of Synchronization Classical problems to test synchronization schemes Bounded-Buffer Problem Readers and Writers Problem Dining-Philosophers Problem Operating System Concepts Essentials – 2nd Edition 5.60 Silberschatz, Galvin and Gagne ©2013 Bounded-Buffer Problem n buffers, each can hold one item Semaphore mutex initialized to value 1 Semaphore full initialized to value 0 Semaphore empty initialized to value n Operating System Concepts Essentials – 2nd Edition 5.61 Silberschatz, Galvin and Gagne ©2013 Bounded Buffer Problem (Cont.) Producer do { ... /* produce an item in next_produced */ ... wait(empty); wait(mutex); ... /* add next produced to the buffer */ ... signal(mutex); signal(full); } while (true); Operating System Concepts Essentials – 2nd Edition 5.62 Silberschatz, Galvin and Gagne ©2013 Bounded Buffer Problem (Cont.) Consumer Do { wait(full); wait(mutex); ... /* remove an item from buffer to next_consumed */ ... signal(mutex); signal(empty); ... /* consume the item in next consumed */ ... } while (true); Operating System Concepts Essentials – 2nd Edition 5.63 Silberschatz, Galvin and Gagne ©2013 Readers-Writers Problem A data set is shared among concurrent processes Readers – only read data; do not perform any updates Writers – can both read and write Problem – allow multiple readers to read at same time Only single writer can access shared data at same time Operating System Concepts Essentials – 2nd Edition 5.64 Silberschatz, Galvin and Gagne ©2013 Readers-Writers Problem Several variations of how readers and writers are considered – all involve some form of priorities Shared Data Data set Semaphore rw_mutex initialized to 1 Semaphore mutex initialized to 1 Integer read_count initialized to 0 Operating System Concepts Essentials – 2nd Edition 5.65 Silberschatz, Galvin and Gagne ©2013 Readers-Writers Problem (Cont.) Writer do { wait(rw_mutex); ... /* writing is performed */ ... signal(rw_mutex); } while (true); Operating System Concepts Essentials – 2nd Edition 5.66 Silberschatz, Galvin and Gagne ©2013 Readers-Writers Problem (Cont.) Reader do { wait(mutex); read_count++; if (read_count == 1) wait(rw_mutex); signal(mutex); ... /* reading is performed */ ... wait(mutex); read count--; if (read_count == 0) signal(rw_mutex); signal(mutex); } while (true); Operating System Concepts Essentials – 2nd Edition 5.67 Silberschatz, Galvin and Gagne ©2013 Readers-Writers Problem Variations First variation – no reader kept waiting unless writer has permission to use shared object Second variation – once writer is ready, it performs the write ASAP Both may have starvation Problem is solved on some systems by kernel providing reader-writer locks Operating System Concepts Essentials – 2nd Edition 5.68 Silberschatz, Galvin and Gagne ©2013 Dining-Philosophers Problem Philosophers spend their lives thinking and eating Occasionally try to pick up 2 chopsticks (one at a time) to eat from bowl Need both to eat Release both when done In the case of 5 philosophers Shared data Bowl of rice (data set) Chopsticks Operating System Concepts Essentials – 2nd Edition 5.69 Silberschatz, Galvin and Gagne ©2013 Dining-Philosophers Problem Algorithm (Cont.) Deadlock handling Allow at most 4 philosophers to be sitting at table. Allow philosopher to pick up forks only if both are available Asymmetric solution Odd-numbered philosophers pick up left, then right Even-numbered Operating System Concepts Essentials – 2nd Edition philosophers pick up right, then left 5.70 Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.71 Silberschatz, Galvin and Gagne ©2013 Linux Synchronization Linux: Prior to kernel Version 2.6, interrupts were disabled for short critical sections Version 2.6 and later, fully preemptive Linux provides: Semaphores Atomic integers spinlocks reader-writer versions of both Operating System Concepts Essentials – 2nd Edition 5.72 Silberschatz, Galvin and Gagne ©2013 Pthreads Synchronization Pthreads API is OS-independent Provides: mutex locks condition variable Non-portable extensions include: read-write locks spinlocks Operating System Concepts Essentials – 2nd Edition 5.73 Silberschatz, Galvin and Gagne ©2013 Chapter 5: Process Synchronization Background The Critical-Section Problem Peterson's Solution Synchronization Hardware Mutex Locks Semaphores Deadlock Classic Problems of Synchronization Synchronization Examples Alternatives Operating System Concepts Essentials – 2nd Edition 5.74 Silberschatz, Galvin and Gagne ©2013 Alternative Approaches Transactional Memory OpenMP Functional Programming Languages Operating System Concepts Essentials – 2nd Edition 5.75 Silberschatz, Galvin and Gagne ©2013 Transactional Memory Sequence of read-write operations to memory performed atomically Comes from databases void update() { /* read/write memory */ } Operating System Concepts Essentials – 2nd Edition 5.76 Silberschatz, Galvin and Gagne ©2013 OpenMP OpenMP = compiler directives and API that support parallel programming. void update(int value) { #pragma omp critical { count += value } } Operating System Concepts Essentials – 2nd Edition 5.77 Silberschatz, Galvin and Gagne ©2013 Functional Programming Languages Functional programming languages do not maintain state Variables treated as immutable Once assigned a value, cannot change E.g., Erlang and Scala Operating System Concepts Essentials – 2nd Edition 5.78 Silberschatz, Galvin and Gagne ©2013