1 Mutual Exclusion: Primitives and Implementation Considerations.

Slides:



Advertisements
Similar presentations
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
Advertisements

Synchronization NOTE to instructors: it is helpful to walk through an example such as readers/writers locks for illustrating the use of condition variables.
Operating Systems Part III: Process Management (Process Synchronization)
Synchronization. How to synchronize processes? – Need to protect access to shared data to avoid problems like race conditions – Typical example: Updating.
Process Synchronization A set of concurrent/parallel processes/tasks can be disjoint or cooperating (or competing) With cooperating and competing processes.
PROCESS SYNCHRONIZATION READINGS: CHAPTER 5. ISSUES IN COOPERING PROCESSES AND THREADS – DATA SHARING Shared Memory Two or more processes share a part.
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Chapter 6 Process Synchronization Bernard Chen Spring 2007.
Chapter 6: Process Synchronization
Background Concurrent access to shared data can lead to inconsistencies Maintaining data consistency among cooperating processes is critical What is wrong.
5.1 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts with Java – 8 th Edition Chapter 5: CPU Scheduling.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
EEE 435 Principles of Operating Systems Interprocess Communication Pt II (Modern Operating Systems 2.3)
Process Synchronization. Module 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores.
Interprocess Communication
1 Condition Synchronization. 2 Synchronization Now that you have seen locks, is that all there is? No, but what is the “right” way to build a parallel.
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.
CS 162 Discussion Section Week 3. Who am I? Mosharaf Chowdhury Office 651 Soda 4-5PM.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts Amherst Operating Systems CMPSCI 377 Lecture.
Avishai Wool lecture Introduction to Systems Programming Lecture 4 Inter-Process / Inter-Thread Communication.
Chapter 6: Synchronization. 6.2 Silberschatz, Galvin and Gagne ©2005 Operating System Principles Module 6: Synchronization 6.1 Background 6.2 The Critical-Section.
CPS110: Implementing threads/locks on a uni-processor Landon Cox.
Race Conditions CS550 Operating Systems. Review So far, we have discussed Processes and Threads and talked about multithreading and MPI processes by example.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts, Amherst Operating Systems CMPSCI 377 Lecture.
Instructor: Umar KalimNUST Institute of Information Technology Operating Systems Process Synchronization.
Computer Science 162 Discussion Section Week 3. Agenda Project 1 released! Locks, Semaphores, and condition variables Producer-consumer – Example (locks,
Synchronization CSCI 444/544 Operating Systems Fall 2008.
Operating Systems CSE 411 CPU Management Oct Lecture 13 Instructor: Bhuvan Urgaonkar.
Concurrency Recitation – 2/24 Nisarg Raval Slides by Prof. Landon Cox.
9/8/2015cse synchronization-p1 © Perkins DW Johnson and University of Washington1 Synchronization Part 1 CSE 410, Spring 2008 Computer Systems.
1 Thread Synchronization: Too Much Milk. 2 Implementing Critical Sections in Software Hard The following example will demonstrate the difficulty of providing.
Implementing Synchronization. Synchronization 101 Synchronization constrains the set of possible interleavings: Threads “agree” to stay out of each other’s.
Process Synchronization Continued 7.2 Critical-Section Problem 7.3 Synchronization Hardware 7.4 Semaphores.
COMP 111 Threads and concurrency Sept 28, Tufts University Computer Science2 Who is this guy? I am not Prof. Couch Obvious? Sam Guyer New assistant.
Operating Systems ECE344 Ashvin Goel ECE University of Toronto Mutual Exclusion.
COSC 3407: Operating Systems Lecture 7: Implementing Mutual Exclusion.
1 Concurrency: Mutual Exclusion and Synchronization Chapter 5.
11/18/20151 Operating Systems Design (CS 423) Elsa L Gunter 2112 SC, UIUC Based on slides by Roy Campbell, Sam.
Chapter 7 -1 CHAPTER 7 PROCESS SYNCHRONIZATION CGS Operating System Concepts UCF, Spring 2004.
Chapter 6 – Process Synchronisation (Pgs 225 – 267)
CS 3204 Operating Systems Godmar Back Lecture 7. 12/12/2015CS 3204 Fall Announcements Project 1 due on Sep 29, 11:59pm Reading: –Read carefully.
Background Concurrent access to shared data may result in data inconsistency Maintaining data consistency requires mechanisms to ensure the orderly execution.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
CSCI-375 Operating Systems Lecture Note: Many slides and/or pictures in the following are adapted from: slides ©2005 Silberschatz, Galvin, and Gagne Some.
COSC 3407: Operating Systems Lecture 9: Readers-Writers and Language Support for Synchronization.
U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Computer Systems Principles Synchronization Emery Berger and Mark Corner University.
CPS110: Thread cooperation Landon Cox. Constraining concurrency  Synchronization  Controlling thread interleavings  Some events are independent  No.
1 Synchronization via Transactions. 2 Concurrency Quiz If two threads execute this program concurrently, how many different final values of X are there?
1 Previous Lecture Overview  semaphores provide the first high-level synchronization abstraction that is possible to implement efficiently in OS. This.
Implementing Lock. From the Previous Lecture  The “too much milk” example shows that writing concurrent programs directly with load and store instructions.
CSCI1600: Embedded and Real Time Software Lecture 17: Concurrent Programming Steven Reiss, Fall 2015.
1 Critical Section Problem CIS 450 Winter 2003 Professor Jinhua Guo.
Concurrency: Locks and synchronization Slides by Prof. Cox.
Implementing Mutual Exclusion Andy Wang Operating Systems COP 4610 / CGS 5765.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
Multiprocessors – Locks
CS703 – Advanced Operating Systems
Atomic Operations in Hardware
Atomic Operations in Hardware
Implementing Mutual Exclusion
Implementing Mutual Exclusion
CSE 451: Operating Systems Autumn 2003 Lecture 7 Synchronization
CSE 451: Operating Systems Autumn 2005 Lecture 7 Synchronization
CSE 451: Operating Systems Winter 2003 Lecture 7 Synchronization
CSE 153 Design of Operating Systems Winter 19
CS333 Intro to Operating Systems
Chapter 6: Synchronization Tools
Process/Thread Synchronization (Part 2)
CPS110: Thread cooperation
Don Porter Portions courtesy Emmett Witchel
Presentation transcript:

1 Mutual Exclusion: Primitives and Implementation Considerations

2 Too Much Milk: Lessons Software solution (Peterson’s algorithm) works, but it is unsatisfactory  Solution is complicated; proving correctness is tricky even for the simple example  While thread is waiting, it is consuming CPU time  Asymmetric solution exists for 2 processes. How can we do better?  Use hardware features to eliminate busy waiting  Define higher-level programming abstractions to simplify concurrent programming

3 Concurrency Quiz If two threads execute this program concurrently, how many different final values of X are there? Initially, X == 0. void increment() { int temp = X; temp = temp + 1; X = temp; } void increment() { int temp = X; temp = temp + 1; X = temp; } Thread 1Thread 2 Answer: A.0 B.1 C.2 D.More than 2

4 Schedules/Interleavings Model of concurrent execution Interleave statements from each thread into a single thread If any interleaving yields incorrect results, some synchronization is needed tmp1 = X; tmp1 = tmp1 + 1; X = tmp1; tmp2 = X; tmp2 = tmp2 + 1; X = tmp2; Thread 1 Thread 2 tmp1 = X; tmp2 = X; tmp2 = tmp2 + 1; tmp1 = tmp1 + 1; X = tmp1; X = tmp2; If X==0 initially, X == 1 at the end. WRONG result!

5 Locks fix this with Mutual Exclusion Mutual exclusion ensures only safe interleavings  When is mutual exclusion too safe? void increment() { lock.acquire(); int temp = X; temp = temp + 1; X = temp; lock.release(); }

6 Introducing Locks Locks – implement mutual exclusion  Two methods  Lock::Acquire() – wait until lock is free, then grab it  Lock::Release() – release the lock, waking up a waiter, if any With locks, too much milk problem is very easy!  Check and update happen as one unit (exclusive access) Lock.Acquire(); if (noMilk) { buy milk; } Lock.Release(); Lock.Acquire(); if (noMilk) { buy milk; } Lock.Release(); How can we implement locks? Lock.Acquire(); x++; Lock.Release(); Lock.Acquire(); x++; Lock.Release();

7 How to think about synchronization code Every thread has the same pattern  Entry section: code to attempt entry to critical section  Critical section: code that requires isolation (e.g., with mutual exclusion)  Exit section: cleanup code after execution of critical region  Non-critical section: everything else There can be multiple critical regions in a program  Only critical regions that access the same resource (e.g., data structure) need to synchronize with each other while(1) { Entry section Critical section Exit section Non-critical section }

8 The correctness conditions Safety  Only one thread in the critical region Liveness  Some thread that enters the entry section eventually enters the critical region  Even if other thread takes forever in non-critical region Bounded waiting  A thread that enters the entry section enters the critical section within some bounded number of operations. Failure atomicity  It is OK for a thread to die in the critical region  Many techniques do not provide failure atomicity while(1) { Entry section Critical section Exit section Non-critical section }

9 Read-Modify-Write (RMW) Implement locks using read-modify-write instructions  As an atomic and isolated action 1. read a memory location into a register, AND 2. write a new value to the location  Implementing RMW is tricky in multi-processors  Requires cache coherence hardware. Caches snoop the memory bus. Examples:  Test&set instructions (most architectures)  Reads a value from memory  Write “1” back to memory location  Compare & swap (68000)  Test the value against some constant  If the test returns true, set value in memory to different value  Report the result of the test in a flag  if [addr] == r1 then [addr] = r2;  Exchange, locked increment, locked decrement (x86)  Load linked/store conditional (PowerPC,Alpha, MIPS)

10 Implementing Locks with Test&set If lock is free (lock_value == 0), then test&set reads 0 and sets value to 1  lock is set to busy and Acquire completes If lock is busy, the test&set reads 1 and sets value to 1  no change in lock’s status and Acquire loops If lock is free (lock_value == 0), then test&set reads 0 and sets value to 1  lock is set to busy and Acquire completes If lock is busy, the test&set reads 1 and sets value to 1  no change in lock’s status and Acquire loops int lock_value = 0; int* lock = &lock_value; int lock_value = 0; int* lock = &lock_value; Lock::Acquire() { while (test&set(lock) == 1) ; //spin } Lock::Acquire() { while (test&set(lock) == 1) ; //spin } Lock::Release() { *lock = 0; } Lock::Release() { *lock = 0; } Does this lock have bounded waiting?

11 Locks and Busy Waiting Busy-waiting:  Threads consume CPU cycles while waiting  Low latency to acquire Limitations  Occupies a CPU core  What happens if threads have different priorities?  Busy-waiting thread remains runnable  If the thread waiting for a lock has higher priority than the thread occupying the lock, then ?  Ugh, I just wanted to lock a data structure, but now I’m involved with the scheduler!  What if programmer forgets to unlock? Lock::Acquire() { while (test&set(lock) == 1) ; // spin } Lock::Acquire() { while (test&set(lock) == 1) ; // spin }

12 Remember to always release locks Java provides convenient mechanism. import java.util.concurrent.locks.ReentrantLock; public static final aLock = new ReentrantLock(); aLock.lock(); try { … } finally { aLock.unlock(); } return 0;

13 Remember to always release locks We will NOT use Java’s implicit locks synchronized void method(void) { XXX } is short for void method(void) { synchronized(this) { XXX }} is short for void method(void) { this.l.lock(); try { XXX } finally { this.l.unlock();}

14 Cheaper Locks with Cheaper busy waiting Using Test&Set Lock::Acquire() { while (test&set(lock) == 1); } Lock::Acquire() { while (test&set(lock) == 1); } Lock::Release() { *lock = 0; } Lock::Release() { *lock = 0; } With busy-waiting Lock::Acquire() { while(1) { if (test&set(lock) == 0) break; else sleep(1); } Lock::Acquire() { while(1) { if (test&set(lock) == 0) break; else sleep(1); } With voluntary yield of CPU Lock::Release() { *lock = 0; } Lock::Release() { *lock = 0; } What is the problem with this?  A. CPU usage B. Memory usage C. Lock::Acquire() latency  D. Memory bus usage E. Messes up interrupt handling

15 Test & Set with Memory Hierarchies 0xF0 lock: 1 0xF4 … lock: 1 … lock: 1 … CPU A while(test&set(lock)); // in critical region L1 L2 Main Memory … … L1 L2 CPU B while(test&set(lock)); What happens to lock variable’s cache line when different cpu’s contend for the same lock? Load can stall

16 Cheap Locks with Cheap busy waiting Using Test&Test&Set Lock::Acquire() { while (test&set(lock) == 1); } Lock::Acquire() { while (test&set(lock) == 1); } Lock::Release() { *lock = 0; } Lock::Release() { *lock = 0; } Busy-wait on in-memory copy Lock::Acquire() { while(1) { while (*lock == 1) ; // spin just reading if (test&set(lock) == 0) break; } Lock::Acquire() { while(1) { while (*lock == 1) ; // spin just reading if (test&set(lock) == 0) break; } Busy-wait on cached copy Lock::Release() { *lock = 0; } Lock::Release() { *lock = 0; } What is the problem with this?  A. CPU usage B. Memory usage C. Lock::Acquire() latency  D. Memory bus usage E. Does not work

17 Test & Set with Memory Hierarchies 0xF0 lock: 1 0xF4 … lock: 1 … lock: 1 … CPU A // in critical region L1 L2 Main Memory lock: 1 … … L1 L2 CPU B while(*lock); if(test&set(lock))brk; What happens to lock variable’s cache line when different cpu’s contend for the same lock?

18 Test & Set with Memory Hierarchies 0xF0 lock: 0 0xF4 … lock: 0 … lock: 0 … CPU A // in critical region *lock = 0 L1 L2 Main Memory L1 L2 CPU B while(*lock); if(test&set(lock))brk; What happens to lock variable’s cache line when different cpu’s contend for the same lock? 0xF0 lock: 1 0xF4 … lock: 1 … … lock: 0 … …

19 Implementing Locks: Summary Locks are higher-level programming abstraction  Mutual exclusion can be implemented using locks Lock implementation generally requires some level of hardware support  Details of hardware support affects efficiency of locking Locks can busy-wait, and busy-waiting cheaply is important  Soon come primitives that block rather than busy-wait

20 Implementing Locks without Busy Waiting (blocking) Using Test&Set Lock::Acquire() { while (test&set(lock) == 1) ; // spin } Lock::Acquire() { while (test&set(lock) == 1) ; // spin } Lock::Release() { *lock := 0; } Lock::Release() { *lock := 0; } With busy-waiting Lock::Acquire() { if (test&set(q_lock) == 1) { Put TCB on wait queue for lock; Lock::Switch(); // dispatch thread } Lock::Acquire() { if (test&set(q_lock) == 1) { Put TCB on wait queue for lock; Lock::Switch(); // dispatch thread } Without busy-waiting, use a queue Lock::Release() { if (wait queue is not empty) { Move a (or all?) waiting threads to ready queue; } *q_lock = 0; Lock::Release() { if (wait queue is not empty) { Move a (or all?) waiting threads to ready queue; } *q_lock = 0; Must only 1 thread be awakened? Lock::Switch() { q_lock = 0; pid = schedule(); if(waited_on_lock(pid)) while(test&set(q_lock)==1) ; dispatch pid } Lock::Switch() { q_lock = 0; pid = schedule(); if(waited_on_lock(pid)) while(test&set(q_lock)==1) ; dispatch pid }

21 Implementing Locks: Summary Locks are higher-level programming abstraction  Mutual exclusion can be implemented using locks Lock implementation generally requires some level of hardware support  Atomic read-modify-write instructions  Uni- and multi-processor architectures Locks are good for mutual exclusion but weak for coordination, e.g., producer/consumer patterns.

22 Fine-grain locks  Greater concurrency  Greater code complexity  Potential deadlocks  Not composable  Potential data races  Which lock to lock? Why Locks are Hard // WITH FINE-GRAIN LOCKS void move(T s, T d, Obj key){ LOCK(s); LOCK(d); tmp = s.remove(key); d.insert(key, tmp); UNLOCK(d); UNLOCK(s); } DEADLOCK! move(a, b, key1); move(b, a, key2); Thread 0 Thread 1 Coarse-grain locks  Simple to develop  Easy to avoid deadlock  Few data races  Limited concurrency