CS 3204 Operating Systems Godmar Back Lecture 7. 12/12/2015CS 3204 Fall 20082 Announcements Project 1 due on Sep 29, 11:59pm Reading: –Read carefully.

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

1 Interprocess Communication 1. Ways of passing information 2. Guarded critical activities (e.g. updating shared data) 3. Proper sequencing in case of.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
Synchronization NOTE to instructors: it is helpful to walk through an example such as readers/writers locks for illustrating the use of condition variables.
More on Semaphores, and Classic Synchronization Problems CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han.
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
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.
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)
1 Mutual Exclusion: Primitives and Implementation Considerations.
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.
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
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts Amherst Operating Systems CMPSCI 377 Lecture.
CS444/CS544 Operating Systems Synchronization 2/16/2007 Prof. Searleman
Avishai Wool lecture Introduction to Systems Programming Lecture 4 Inter-Process / Inter-Thread Communication.
5.6 Semaphores Semaphores –Software construct that can be used to enforce mutual exclusion –Contains a protected variable Can be accessed only via wait.
Semaphores. Announcements No CS 415 Section this Friday Tom Roeder will hold office hours Homework 2 is due today.
5.6.2 Thread Synchronization with Semaphores Semaphores can be used to notify other threads that events have occurred –Producer-consumer relationship Producer.
Synchronization Principles. Race Conditions Race Conditions: An Example spooler directory out in 4 7 somefile.txt list.c scores.txt Process.
Chapter 2.3 : Interprocess Communication
Semaphores CSCI 444/544 Operating Systems Fall 2008.
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.
9/8/2015cse synchronization-p1 © Perkins DW Johnson and University of Washington1 Synchronization Part 1 CSE 410, Spring 2008 Computer Systems.
CS510 Concurrent Systems Introduction to Concurrency.
Implementing Synchronization. Synchronization 101 Synchronization constrains the set of possible interleavings: Threads “agree” to stay out of each other’s.
Operating Systems ECE344 Ashvin Goel ECE University of Toronto Mutual Exclusion.
Kernel Locking Techniques by Robert Love presented by Scott Price.
Chapter 7 -1 CHAPTER 7 PROCESS SYNCHRONIZATION CGS Operating System Concepts UCF, Spring 2004.
Chapter 6 – Process Synchronisation (Pgs 225 – 267)
Operating Systems CMPSC 473 Mutual Exclusion Lecture 11: October 5, 2010 Instructor: Bhuvan Urgaonkar.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
Operating Systems CSE 411 CPU Management Dec Lecture Instructor: Bhuvan Urgaonkar.
CS 3204 Operating Systems Godmar Back Lecture 9. 1/12/2016CS 3204 Fall Announcements Project 1 due on Sep 29, 11:59pm –Additional GTA office hours.
1 Previous Lecture Overview  semaphores provide the first high-level synchronization abstraction that is possible to implement efficiently in OS. This.
CSE 153 Design of Operating Systems Winter 2015 Lecture 5: Synchronization.
Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han.
Implementing Lock. From the Previous Lecture  The “too much milk” example shows that writing concurrent programs directly with load and store instructions.
CS 153 Design of Operating Systems Winter 2016 Lecture 7: Synchronization.
CSCI1600: Embedded and Real Time Software Lecture 17: Concurrent Programming Steven Reiss, Fall 2015.
CSC 660: Advanced Operating SystemsSlide #1 CSC 660: Advanced OS Synchronization.
1 Critical Section Problem CIS 450 Winter 2003 Professor Jinhua Guo.
Implementing Mutual Exclusion Andy Wang Operating Systems COP 4610 / CGS 5765.
Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections.
CS162 Section 2. True/False A thread needs to own a semaphore, meaning the thread has called semaphore.P(), before it can call semaphore.V() False: Any.
Interprocess Communication Race Conditions
CSE 120 Principles of Operating
CS703 – Advanced Operating Systems
Background on the need for Synchronization
Semaphores and Condition Variables
Critical section problem
Implementing Mutual Exclusion
Concurrency: Mutual Exclusion and Process Synchronization
CSCI1600: Embedded and Real Time Software
Implementing Mutual Exclusion
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
CSCI1600: Embedded and Real Time Software
Process/Thread Synchronization (Part 2)
CSE 542: Operating Systems
CSE 542: Operating Systems
Presentation transcript:

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 1.5, , Dr. Back has no office hours this week

12/12/2015CS 3204 Fall Project 1 Suggested Timeline By now, you have: –Have read relevant project documentation, set up CVS, built and run your first kernel, designed your data structures for alarm clock And should be finishing: –Alarm clock by Sep 16 Pass all basic priority tests by Sep 18 Priority Inheritance & Advanced Scheduler will take the most time to implement & debug, start them in parallel –Should have design for priority inheritance figured out by Sep 23 –Develop & test fixed-point layer independently by Sep 23 Due date Sep 29

Concurrency & Synchronization

12/12/2015CS 3204 Fall Overview Will talk about locks, semaphores, and monitors/condition variables For each, will talk about: –What abstraction they represent –How to implement them –How and when to use them Two major issues: –Mutual exclusion –Scheduling constraints Project note: Pintos implements its locks on top of semaphores

12/12/2015CS 3204 Fall Critical Section Problem A solution for the CS Problem must 1)Provide mutual exclusion: at most one thread can be inside CS 2)Guarantee Progress: (no deadlock) if more than one threads attempt to enter, one will succeed ability to enter should not depend on activity of other threads not currently in CS 3)Bounded Waiting: (no starvation) A thread attempting to enter critical section eventually will (assuming no thread spends unbounded amount of time inside CS) A solution for CS problem should be –Fair (make sure waiting times are balanced) –Efficient (not waste resources) –Simple

12/12/2015CS 3204 Fall Locks Thread that enters CS locks it –Others can’t get in and have to wait Thread unlocks CS when leaving it –Lets in next thread –which one? FIFO guarantees bounded waiting Highest priority in Proj1 Can view Lock as an abstract data type –Provides (at least) init, acquire, release lock unlock

12/12/2015CS 3204 Fall Implementing Locks Locks can be implemented directly, or – among other options - on top of semaphores –If implemented on top of semaphores, then semaphores must be implemented directly –Will explain this layered approach first to help in understanding project code –Issues in direct implementation of locks apply to direct implementation of semaphores as well

12/12/2015CS 3204 Fall Semaphores Invented by Edsger Dijkstra in 1960s Counter S, initialized to some value, with two operations: –P(S) or “down” or “wait” – if counter greater than zero, decrement. Else wait until greater than zero, then decrement –V(S) or “up” or “signal” – increment counter, wake up any threads stuck in P. Semaphores don’t go negative: –#V + InitialValue - #P >= 0 Note: direct access to counter value after initialization is not allowed Counting vs Binary Semaphores –Binary: counter can only be 0 or 1 Simple to implement, yet powerful –Can be used for many synchronization problems Source: inter.scoutnet.org

12/12/2015CS 3204 Fall Semaphores as Locks Semaphores can be used to build locks –Pintos does just that Must initialize semaphore with 1 to allow one thread to enter critical section Easily generalized to allow at most N simultaneous threads: multiplex pattern (i.e., a resource can be accessed by at most N threads) semaphore S(1); // allows initial down lock_acquire() { // try to decrement, wait if 0 sema_down(S); } lock_release() { // increment (wake up waiters if any) sema_up(S); } semaphore S(1); // allows initial down lock_acquire() { // try to decrement, wait if 0 sema_down(S); } lock_release() { // increment (wake up waiters if any) sema_up(S); }

12/12/2015CS 3204 Fall Implementing Locks Directly NB: Same technique applies to implementing semaphores directly (as in done in Pintos) –Will see two applications of the same technique Different solutions exist to implement locks for uniprocessor and multiprocessors Will talk about how to implement locks for uniprocessors first – next slides all assume uniprocessor

12/12/2015CS 3204 Fall Implementing Locks, Take 1 Does this work? lock_acquire(struct lock *l) { while (l->state == LOCKED) continue; l->state = LOCKED; } lock_acquire(struct lock *l) { while (l->state == LOCKED) continue; l->state = LOCKED; } lock_release(struct lock *l) { l->state = UNLOCKED; } lock_release(struct lock *l) { l->state = UNLOCKED; } No – does not guarantee mutual exclusion property – more than one thread may see “state” in UNLOCKED state and break out of while loop. This implementation has itself a race condition.

12/12/2015CS 3204 Fall Implementing Locks, Take 2 Does this work? lock_acquire(struct lock *l) { disable_preemption(); while (l->state == LOCKED) continue; l->state = LOCKED; enable_preemption(); } lock_acquire(struct lock *l) { disable_preemption(); while (l->state == LOCKED) continue; l->state = LOCKED; enable_preemption(); } lock_release(struct lock *l) { l->state = UNLOCKED; } lock_release(struct lock *l) { l->state = UNLOCKED; } No – does not guarantee progress property. If one thread enters the while loop, no other thread will ever be scheduled since preemption is disabled – in particular, no thread that would call lock_release will ever be scheduled.

12/12/2015CS 3204 Fall Implementing Locks, Take 3 Does this work? lock_acquire(struct lock *l) { while (true) { disable_preemption(); if (l->state == UNLOCKED) { l->state = LOCKED; enable_preemption(); return; } enable_preemption(); } lock_acquire(struct lock *l) { while (true) { disable_preemption(); if (l->state == UNLOCKED) { l->state = LOCKED; enable_preemption(); return; } enable_preemption(); } lock_release(struct lock *l) { l->state = UNLOCKED; } lock_release(struct lock *l) { l->state = UNLOCKED; } Yes, this works – but is grossly inefficient. A thread that encounters the lock in the LOCKED state will busy wait until it is unlocked, needlessly using up CPU time.

12/12/2015CS 3204 Fall Implementing Locks, Take 4 lock_acquire(struct lock *l) { disable_preemption(); while (l->state == LOCKED) { list_push_back(l->waiters, &current->elem); thread_block(current); } l->state = LOCKED; enable_preemption(); } lock_acquire(struct lock *l) { disable_preemption(); while (l->state == LOCKED) { list_push_back(l->waiters, &current->elem); thread_block(current); } l->state = LOCKED; enable_preemption(); } lock_release(struct lock *l) { disable_preemption(); l->state = UNLOCKED; if (list_size(l->waiters) > 0) thread_unblock( list_entry(list_pop_front(l->waiters), struct thread, elem)); enable_preemption(); } lock_release(struct lock *l) { disable_preemption(); l->state = UNLOCKED; if (list_size(l->waiters) > 0) thread_unblock( list_entry(list_pop_front(l->waiters), struct thread, elem)); enable_preemption(); } Correct & uses proper blocking. Note that thread doing the unlock performs the work of unblocking the first waiting thread.

12/12/2015CS 3204 Fall Multiprocessor Locks Can’t stop threads running on other processors –too expensive (interprocessor irq) –also would create conflict with protection (locking = unprivileged op, stopping = privileged op), involving the kernel in *every* acquire/release Instead: use atomic instructions provided by hardware –E.g.: test-and-set, atomic-swap, compare-and- exchange, fetch-and-add –All variations of “read-and-modify” theme Locks are built on top of these

12/12/2015CS 3204 Fall Atomic Swap // In C, an atomic swap instruction would look like this void atomic_swap(int *memory1, int *memory2) { [ disable interrupts in CPU; lock cache line(s) for other processors ] int tmp = *memory1; *memory1 = *memory2; *memory2 = tmp; [ unlock cache line(s); reenable interrupts ] } // In C, an atomic swap instruction would look like this void atomic_swap(int *memory1, int *memory2) { [ disable interrupts in CPU; lock cache line(s) for other processors ] int tmp = *memory1; *memory1 = *memory2; *memory2 = tmp; [ unlock cache line(s); reenable interrupts ] } CPU1 CPU2 Memory memory bus Cache cache coherence protocol

12/12/2015CS 3204 Fall Spinlocks lock_acquire(struct lock *l) { int lockstate = LOCKED; while (lockstate == LOCKED) { atomic_swap(&lockstate, &l->state); } } lock_acquire(struct lock *l) { int lockstate = LOCKED; while (lockstate == LOCKED) { atomic_swap(&lockstate, &l->state); } } lock_release(struct lock *l) { l->state = UNLOCKED; } lock_release(struct lock *l) { l->state = UNLOCKED; } Thread spins until it acquires lock –Q1: when should it block instead? –Q2: what if spin lock holder is preempted?

12/12/2015CS 3204 Fall Spinning vs Blocking Some lock implementations combine spinning and blocking locks Blocking has a cost –Shouldn’t block if lock becomes available in less time than it takes to block Strategy: spin for time it would take to block –Even in worst case, total cost for lock_acquire is less than 2*block time

12/12/2015CS 3204 Fall Spinlocks vs Disabling Preemption What if spinlocks were used on single CPU? Consider: –thread 1 takes spinlock –thread 1 is preempted –thread 2 with higher priority runs –thread 2 tries to take spinlock, finds it taken –thread 2 spins forever  deadlock! Thus in practice, usually combine spinlocks with disabling preemption –E.g., spin_lock_irqsave() in Linux UP kernel: reduces to disable_preemption() SMP kernel: disable_preemption() + spinlock Spinlocks are used when holding resources for small periods of time (same rule as for when it’s ok to disable irqs)

12/12/2015CS 3204 Fall Critical Section Efficiency As processors get faster, CSE decreases because atomic instructions become relatively more expensive Source: McKenney, 2005

12/12/2015CS 3204 Fall Spinlocks (Faster) lock_acquire(struct lock *l) { int lockstate = LOCKED; while (lockstate == LOCKED) { while (l->state == LOCKED) continue; atomic_swap(&lockstate, &l->state); } } lock_acquire(struct lock *l) { int lockstate = LOCKED; while (lockstate == LOCKED) { while (l->state == LOCKED) continue; atomic_swap(&lockstate, &l->state); } } lock_release(struct lock *l) { l->state = UNLOCKED; } lock_release(struct lock *l) { l->state = UNLOCKED; } Only try “expensive” atomic_swap instruction if you’ve seen lock in unlocked state

12/12/2015CS 3204 Fall Locks: Ownership & Recursion Locks typically (not always) have notion of ownership –Only lock holder is allowed to unlock –See Pintos lock_held_by_current_thread() What if lock holder tries to acquire locks it already holds? –Nonrecursive locks: deadlock! –Recursive locks: inc counter dec counter on lock_release release when zero