CSE 153 Design of Operating Systems Winter 2015 Lecture 5: Synchronization.

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Chapter 6: Process Synchronization
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts – 9 th Edition Chapter 5: Process Synchronization.
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.
Process Synchronization. Module 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores.
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.
CSE 451: Operating Systems Winter 2012 Synchronization Mark Zbikowski Gary Kimura.
CSE 451: Operating Systems Spring 2012 Module 7 Synchronization Ed Lazowska Allen Center 570.
Synchronization. Shared Memory Thread Synchronization Threads cooperate in multithreaded environments – User threads and kernel threads – Share resources.
Operating Systems ECE344 Ding Yuan Synchronization (I) -- Critical region and lock Lecture 5: Synchronization (I) -- Critical region and lock.
CS444/CS544 Operating Systems Synchronization 2/21/2006 Prof. Searleman
CS444/CS544 Operating Systems Synchronization 2/16/2006 Prof. Searleman
CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman
5.6 Semaphores Semaphores –Software construct that can be used to enforce mutual exclusion –Contains a protected variable Can be accessed only via wait.
Chapter 6: Process Synchronization. Outline Background Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores Classic Problems.
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.
Synchronization CSCI 444/544 Operating Systems Fall 2008.
1 Race Conditions/Mutual Exclusion Segment of code of a process where a shared resource is accessed (changing global variables, writing files etc) is called.
Operating Systems CSE 411 CPU Management Oct Lecture 13 Instructor: Bhuvan Urgaonkar.
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.
Midterm 1 – Wednesday, June 4  Chapters 1-3: understand material as it relates to concepts covered  Chapter 4 - Processes: 4.1 Process Concept 4.2 Process.
Operating Systems ECE344 Ashvin Goel ECE University of Toronto Mutual Exclusion.
Silberschatz, Galvin and Gagne  Operating System Concepts Chapter 7: Process Synchronization Background The Critical-Section Problem Synchronization.
1 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts Essentials – 9 th Edition Chapter 5: Process Synchronization.
Chapter 6 – Process Synchronisation (Pgs 225 – 267)
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.
U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Computer Systems Principles Synchronization Emery Berger and Mark Corner University.
CSE 153 Design of Operating Systems Winter 2015 Midterm Review.
IT 344: Operating Systems Module 6 Synchronization Chia-Chi Teng CTB 265.
Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han.
CS 153 Design of Operating Systems Winter 2016 Lecture 7: Synchronization.
1 Critical Section Problem CIS 450 Winter 2003 Professor Jinhua Guo.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Chapter 6: Process Synchronization.
13/03/07Week 21 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Chapter 6 Synchronization Dr. Yingwu Zhu. The Problem with Concurrent Execution Concurrent processes (& threads) often access shared data and resources.
CSE 451: Operating Systems Spring 2010 Module 7 Synchronization John Zahorjan Allen Center 534.
CSE 120 Principles of Operating
CS703 – Advanced Operating Systems
Background on the need for Synchronization
Synchronization.
Synchronization.
Chapter 5: Process Synchronization
Topic 6 (Textbook - Chapter 5) Process Synchronization
Lecture 2 Part 2 Process Synchronization
CENG334 Introduction to Operating Systems
CSE 451: Operating Systems Winter 2007 Module 6 Synchronization
CSE 451: Operating Systems Autumn 2004 Module 6 Synchronization
CSE 451: Operating Systems Autumn 2003 Lecture 7 Synchronization
CSE 451: Operating Systems Autumn 2005 Lecture 7 Synchronization
CSE 451: Operating Systems Winter 2004 Module 6 Synchronization
CSE 451: Operating Systems Winter 2003 Lecture 7 Synchronization
CSE 153 Design of Operating Systems Winter 19
CSE 153 Design of Operating Systems Winter 2019
CS333 Intro to Operating Systems
Chapter 6: Synchronization Tools
CSE 451: Operating Systems Spring 2008 Module 7 Synchronization
CSE 451: Operating Systems Winter 2007 Module 6 Synchronization
CSE 451: Operating Systems Autumn 2009 Module 7 Synchronization
CSE 153 Design of Operating Systems Winter 2019
CSE 451: Operating Systems Spring 2007 Module 7 Synchronization
CSE 542: Operating Systems
CSE 542: Operating Systems
Presentation transcript:

CSE 153 Design of Operating Systems Winter 2015 Lecture 5: Synchronization

Administrivia l Homework 1 posted today u Due in class next Tuesday l Hopefully you have started on project 1 by now? u Be prepared with questions for this weeks Lab u Read up on scheduling and synchronization in textbook and start early! u Need to read and understand a lot of code before starting to code u Students typically find this to be the hardest of the three projects CSE 153 – Lecture 5 – Synchronization2

Cooperation between Threads l Threads cooperate in multithreaded programs u To share resources, access shared data structures »Threads accessing a memory cache in a Web server u To coordinate their execution »One thread executes relative to another CSE 153 – Lecture 5 – Synchronization3

4 Threads: Sharing Data int num_connections = 0; web_server() { while (1) { int sock = accept(); thread_fork(handle_request, sock); } handle_request(int sock) { ++num_connections; Process request close(sock); }

CSE 153 – Lecture 5 – Synchronization5 Threads: Cooperation l Threads voluntarily give up the CPU with thread_yield while (1) { printf(“ping\n”); thread_yield(); } while (1) { printf(“pong\n”); thread_yield(); } Ping ThreadPong Thread

January 21, 2014CSE 153 – Lecture 5 – Synchronization6 Synchronization l For correctness, we need to control this cooperation u Threads interleave executions arbitrarily and at different rates u Scheduling is not under program control l We control cooperation using synchronization u Synchronization enables us to restrict the possible inter- leavings of thread executions l Discuss in terms of threads, also applies to processes

January 21, 2014CSE 153 – Lecture 5 – Synchronization7 Shared Resources We initially focus on coordinating access to shared resources l Basic problem u If two concurrent threads are accessing a shared variable, and that variable is read/modified/written by those threads, then access to the variable must be controlled to avoid erroneous behavior l Over the next couple of lectures, we will look at u Mechanisms to control access to shared resources »Locks, mutexes, semaphores, monitors, condition variables, etc. u Patterns for coordinating accesses to shared resources »Bounded buffer, producer-consumer, etc.

CSE 153 – Lecture 5 – Synchronization8 Classic Example l Suppose we have to implement a function to handle withdrawals from a bank account: withdraw (account, amount) { balance = get_balance(account); balance = balance – amount; put_balance(account, balance); return balance; } l Now suppose that you and your father share a bank account with a balance of $1000 l Then you each go to separate ATM machines and simultaneously withdraw $100 from the account

CSE 153 – Lecture 5 – Synchronization9 Example Continued l We’ll represent the situation by creating a separate thread for each person to do the withdrawals l These threads run on the same bank machine: l What’s the problem with this implementation? u Think about potential schedules of these two threads withdraw (account, amount) { balance = get_balance(account); balance = balance – amount; put_balance(account, balance); return balance; } withdraw (account, amount) { balance = get_balance(account); balance = balance – amount; put_balance(account, balance); return balance; }

CSE 153 – Lecture 5 – Synchronization10 Interleaved Schedules l The problem is that the execution of the two threads can be interleaved: l What is the balance of the account now? balance = get_balance(account); balance = balance – amount; balance = get_balance(account); balance = balance – amount; put_balance(account, balance); Execution sequence seen by CPU Context switch

CSE 153 – Lecture 5 – Synchronization11 Shared Resources l Problem: two threads accessed a shared resource u Known as a race condition (memorize this buzzword) l Need mechanisms to control this access u So we can reason about how the program will operate l Our example was updating a shared bank account l Also necessary for synchronizing access to any shared data structure u Buffers, queues, lists, hash tables, etc.

CSE 153 – Lecture 5 – Synchronization12 When Are Resources Shared? l Local variables? u Not shared: refer to data on the stack u Each thread has its own stack u Never pass/share/store a pointer to a local variable on the stack for thread T1 to another thread T2 l Global variables and static objects? u Shared: in static data segment, accessible by all threads l Dynamic objects and other heap objects? u Shared: Allocated from heap with malloc/free or new/delete Stack (T1) Code Static Data Heap Stack (T2) Stack (T3) Thread 3 Thread 2 PC (T1) PC (T3) PC (T2) Thread 1

CSE 153 – Lecture 5 – Synchronization13 How Interleaved Can It Get? get_balance(account); put_balance(account, balance); balance = balance – amount; balance = get_balance(account); balance = How contorted can the interleavings be? l We'll assume that the only atomic operations are reads and writes of individual memory locations u Some architectures don't even give you that! l We'll assume that a context switch can occur at any time l We'll assume that you can delay a thread as long as you like as long as it's not delayed forever

CSE 153 – Lecture 5 – Synchronization14 Mutual Exclusion l Mutual exclusion to synchronize access to shared resources u This allows us to have larger atomic blocks u What does atomic mean? l Code that uses mutual called a critical section u Only one thread at a time can execute in the critical section u All other threads are forced to wait on entry u When a thread leaves a critical section, another can enter u Example: sharing an ATM with others l What requirements would you place on a critical section?

CSE 153 – Lecture 5 – Synchronization15 Critical Section Requirements Critical sections have the following requirements: 1) Mutual exclusion (mutex) u If one thread is in the critical section, then no other is 2) Progress u A thread in the critical section will eventually leave the critical section u If some thread T is not in the critical section, then T cannot prevent some other thread S from entering the critical section 3) Bounded waiting (no starvation) u If some thread T is waiting on the critical section, then T will eventually enter the critical section 4) Performance u The overhead of entering and exiting the critical section is small with respect to the work being done within it

CSE 153 – Lecture 5 – Synchronization16 About Requirements There are three kinds of requirements that we'll use l Safety property: nothing bad happens u Mutex l Liveness property: something good happens u Progress, Bounded Waiting l Performance requirement u Performance l Properties hold for each run, while performance depends on all the runs u Rule of thumb: When designing a concurrent algorithm, worry about safety first (but don't forget liveness!).

CSE 153 – Lecture 5 – Synchronization17 Mechanisms For Building Critical Sections l Atomic read/write u Can it be done? l Locks u Primitive, minimal semantics, used to build others l Semaphores u Basic, easy to get the hang of, but hard to program with l Monitors u High-level, requires language support, operations implicit

CSE 153 – Lecture 5 – Synchronization18 Mutual Exclusion with Atomic Read/Writes: First Try while (true) { while (turn != 1) ; critical section turn = 2; outside of critical section } while (true) { while (turn != 2) ; critical section turn = 1; outside of critical section } int turn = 1; This is called alternation It satisfies mutex: If blue is in the critical section, then turn == 1 and if yellow is in the critical section then turn == 2 (turn == 1) ≡ (turn != 2) Is there anything wrong with this solution?

CSE 153 – Lecture 5 – Synchronization19 Mutual Exclusion with Atomic Read/Writes: First Try while (true) { while (turn != 1) ; critical section turn = 2; outside of critical section } while (true) { while (turn != 2) ; critical section turn = 1; outside of critical section } int turn = 1; This is called alternation It satisfies mutex: If blue is in the critical section, then turn == 1 and if yellow is in the critical section then turn == 2 (turn == 1) ≡ (turn != 2) It violates progress: blue thread could go into an infinite loop outside of the critical section, which will prevent the yellow one from entering

CSE 153 – Lecture 5 – Synchronization20 Mutex with Atomic R/W: Peterson's Algorithm while (true) { try1 = true; turn = 2; while (try2 && turn != 1) ; critical section try1 = false; outside of critical section } while (true) { try2 = true; turn = 1; while (try1 && turn != 2) ; critical section try2 = false; outside of critical section } int turn = 1; bool try1 = false, try2 = false; This satisfies all the requirements Here's why...

CSE 153 – Lecture 5 – Synchronization21 Mutex with Atomic R/W: Peterson's Algorithm while (true) { {¬ try1 ∧ (turn == 1 ∨ turn == 2) } 1 try1 = true; { try1 ∧ (turn == 1 ∨ turn == 2) } 2 turn = 2; { try1 ∧ (turn == 1 ∨ turn == 2) } 3 while (try2 && turn != 1) ; { try1 ∧ (turn == 1 ∨ ¬ try2 ∨ (try2 ∧ (yellow at 6 or at 7)) } critical section 4 try1 = false; {¬ try1 ∧ (turn == 1 ∨ turn == 2) } outside of critical section } while (true) { {¬ try2 ∧ (turn == 1 ∨ turn == 2) } 5 try2 = true; { try2 ∧ (turn == 1 ∨ turn == 2) } 6 turn = 1; { try2 ∧ (turn == 1 ∨ turn == 2) } 7 while (try1 && turn != 2) ; { try2 ∧ (turn == 2 ∨ ¬ try1 ∨ (try1 ∧ (blue at 2 or at 3)) } critical section 8 try2 = false; {¬ try2 ∧ (turn == 1 ∨ turn == 2) } outside of critical section } int turn = 1; bool try1 = false, try2 = false; (blue at 4) ∧ try1 ∧ (turn == 1 ∨ ¬ try2 ∨ (try2 ∧ (yellow at 6 or at 7)) ∧ (yellow at 8) ∧ try2 ∧ (turn == 2 ∨ ¬ try1 ∨ (try1 ∧ (blue at 2 or at 3))... ⇒ (turn == 1 ∧ turn == 2)

CSE 153 – Lecture 5 – Synchronization22 Locks l A lock is an object in memory providing two operations u acquire(): before entering the critical section u release(): after leaving a critical section l Threads pair calls to acquire() and release() u Between acquire()/release(), the thread holds the lock u acquire() does not return until any previous holder releases u What can happen if the calls are not paired?

CSE 153 – Lecture 5 – Synchronization23 Using Locks u Why is the “return” outside the critical section? Is this ok? u What happens when a third thread calls acquire? withdraw (account, amount) { acquire(lock); balance = get_balance(account); balance = balance – amount; put_balance(account, balance); release(lock); return balance; } acquire(lock); balance = get_balance(account); balance = balance – amount; balance = get_balance(account); balance = balance – amount; put_balance(account, balance); release(lock); acquire(lock); put_balance(account, balance); release(lock); Critical Section

CSE 153 – Lecture 5 – Synchronization24 l How do we implement locks? Here is one attempt: l This is called a spinlock because a thread spins waiting for the lock to be released l Does this work? Implementing Locks (1) struct lock { int held = 0; } void acquire (lock) { while (lock->held); lock->held = 1; } void release (lock) { lock->held = 0; } busy-wait (spin-wait) for lock to be released

CSE 153 – Lecture 5 – Synchronization25 Implementing Locks (2) l No. Two independent threads may both notice that a lock has been released and thereby acquire it. struct lock { int held = 0; } void acquire (lock) { while (lock->held); lock->held = 1; } void release (lock) { lock->held = 0; } A context switch can occur here, causing a race condition

CSE 153 – Lecture 5 – Synchronization26 Implementing Locks (3) l The problem is that the implementation of locks has critical sections, too l How do we stop the recursion? l The implementation of acquire/release must be atomic u An atomic operation is one which executes as though it could not be interrupted u Code that executes “all or nothing” l How do we make them atomic? l Need help from hardware u Atomic instructions (e.g., test-and-set) u Disable/enable interrupts (prevents context switches)

CSE 153 – Lecture 5 – Synchronization27 Atomic Instructions: Test-And-Set l The semantics of test-and-set are: u Record the old value u Set the value to indicate available u Return the old value l Hardware executes it atomically! l When executing test-and-set on “flag” u What is value of flag afterwards if it was initially False? True? u What is the return result if flag was initially False? True? bool test_and_set (bool *flag) { bool old = *flag; *flag = True; return old; }

CSE 153 – Lecture 5 – Synchronization28 Using Test-And-Set l Here is our lock implementation with test-and-set: l When will the while return? What is the value of held? struct lock { int held = 0; } void acquire (lock) { while (test-and-set(&lock->held)); } void release (lock) { lock->held = 0; }

CSE 153 – Lecture 5 – Synchronization29 Problems with Spinlocks l The problem with spinlocks is that they are wasteful l If a thread is spinning on a lock, then the scheduler thinks that this thread needs CPU and puts it on the ready queue l If N threads are contending for the lock, the thread which holds the lock gets only 1/N’th of the CPU

CSE 153 – Lecture 5 – Synchronization30 Disabling Interrupts l Another implementation of acquire/release is to disable interrupts: l Note that there is no state associated with the lock l Can two threads disable interrupts simultaneously? struct lock { } void acquire (lock) { disable interrupts; } void release (lock) { enable interrupts; }

CSE 153 – Lecture 5 – Synchronization31 On Disabling Interrupts l Disabling interrupts blocks notification of external events that could trigger a context switch (e.g., timer) l In a “real” system, this is only available to the kernel u Why? l Disabling interrupts is insufficient on a multiprocessor u Back to atomic instructions l Like spinlocks, only want to disable interrupts to implement higher-level synchronization primitives u Don’t want interrupts disabled between acquire and release

CSE 153 – Lecture 5 – Synchronization32 Summarize Where We Are l Goal: Use mutual exclusion to protect critical sections of code that access shared resources l Method: Use locks (spinlocks or disable interrupts) l Problem: Critical sections can be long acquire(lock) … Critical section … release(lock) Disabling Interrupts: l Should not disable interrupts for long periods of time l Can miss or delay important events (e.g., timer, I/O) Spinlocks: l Threads waiting to acquire lock spin in test-and-set loop l Wastes CPU cycles l Longer the CS, the longer the spin l Greater the chance for lock holder to be interrupted

CSE 153 – Lecture 5 – Synchronization33 Higher-Level Synchronization l Spinlocks and disabling interrupts are useful only for very short and simple critical sections u Wasteful otherwise u These primitives are “primitive” – don’t do anything besides mutual exclusion l Need higher-level synchronization primitives that: u Block waiters u Leave interrupts enabled within the critical section l All synchronization requires atomicity l So we’ll use our “atomic” locks as primitives to implement them

l Block waiters, interrupts enabled in critical sections void release (lock) { Disable interrupts; if (Q) remove and unblock a waiting thread; else lock->held = 0; Enable interrupts; } CSE 153 – Lecture 5 – Synchronization34 Implementing Locks (4) struct lock { int held = 0; queue Q; } void acquire (lock) { Disable interrupts; if (lock->held) { put current thread on lock Q; block current thread; } lock->held = 1; Enable interrupts; } acquire(lock) … Critical section … release(lock) Interrupts Enabled Interrupts Disabled

CSE 153 – Lecture 5 – Synchronization35 Next time… l Semaphores and monitors u Read Chapter 5.4 – 5.7 l Homework 1 due next Tuesday

CSE 153 – Lecture 5 – Synchronization36 Semaphores l Semaphores are data structures that also provide mutual exclusion to critical sections u Block waiters, interrupts enabled within CS u Described by Dijkstra in THE system in 1968 l Semaphores count the number of threads using a critical section (more later) l Semaphores support two operations: u wait(semaphore): decrement, block until semaphore is open »Also P() after the Dutch word for test u signal(semaphore): increment, allow another thread to enter »Also V() after the Dutch word for increment

CSE 153 – Lecture 5 – Synchronization37 Blocking in Semaphores l Associated with each semaphore is a queue of waiting processes l When wait() is called by a thread: u If semaphore is open, thread continues u If semaphore is closed, thread blocks on queue l signal() opens the semaphore: u If a thread is waiting on the queue, the thread is unblocked u If no threads are waiting on the queue, the signal is remembered for the next thread »In other words, signal() has “history” »This history uses a counter

CSE 153 – Lecture 5 – Synchronization38 Using Semaphores l Use is similar to locks, but semantics are different struct account { double balance; semaphore S; } withdraw (account, amount) { wait(account->S); tmp = account->balance; tmp = tmp - amount; account->balance = tmp; signal(account->S); return tmp; } wait(account->S); tmp = account->balance; tmp = tmp – amount; wait(account->S); account->balance = tmp; signal(account->S); wait(account->S); … signal(account->S); … signal(account->S); Threads block It is undefined which thread runs after a signal