Implementing Synchronization. Synchronization 101 Synchronization constrains the set of possible interleavings: Threads “agree” to stay out of each other’s.

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

Global Environment Model. MUTUAL EXCLUSION PROBLEM The operations used by processes to access to common resources (critical sections) must be mutually.
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.
Process Synchronization. Module 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores.
Mutual Exclusion.
Synchronization: Going Deeper. SharedLock: Reader/Writer Lock A reader/write lock or SharedLock is a new kind of “lock” that is similar to our old definition:
Critical Sections and Race Conditions. Administrivia Install and build Nachos if you haven’t already.
1 Mutual Exclusion: Primitives and Implementation Considerations.
Sleep/Wakeup and Condition Variables. Example: Await/Awake Consider a very simple use of sleep/wakeup to implement two new primitives: currentThread->Await()
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.
Operating Systems ECE344 Ding Yuan Synchronization (I) -- Critical region and lock Lecture 5: Synchronization (I) -- Critical region and lock.
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.
Synchronization Principles. Race Conditions Race Conditions: An Example spooler directory out in 4 7 somefile.txt list.c scores.txt Process.
1 CS 333 Introduction to Operating Systems Class 4 – Synchronization Primitives Semaphores Jonathan Walpole Computer Science Portland State University.
Jonathan Walpole Computer Science Portland State University
Jonathan Walpole Computer Science Portland State University
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.
Synchronization CSCI 444/544 Operating Systems Fall 2008.
CS510 Concurrent Systems Introduction to Concurrency.
The Synchronization Toolbox. Mutual Exclusion Race conditions can be avoiding by ensuring mutual exclusion in critical sections. Critical sections are.
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.
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.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
1 Synchronization Threads communicate to ensure consistency If not: race condition (non-deterministic result) Accomplished by synchronization operations.
CPS110: Threads review and wrap up Landon Cox February 11, 2009.
U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Computer Systems Principles Synchronization Emery Berger and Mark Corner University.
IT 344: Operating Systems Module 6 Synchronization Chia-Chi Teng CTB 265.
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.
Lecture 6 Page 1 CS 111 Summer 2013 Concurrency Solutions and Deadlock CS 111 Operating Systems Peter Reiher.
Implementing Lock. From the Previous Lecture  The “too much milk” example shows that writing concurrent programs directly with load and store instructions.
CSC 660: Advanced Operating SystemsSlide #1 CSC 660: Advanced OS Synchronization.
CS510 Concurrent Systems Jonathan Walpole. Introduction to Concurrency.
Implementing Mutual Exclusion Andy Wang Operating Systems COP 4610 / CGS 5765.
13/03/07Week 21 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections.
December 1, 2006©2006 Craig Zilles1 Threads & Atomic Operations in Hardware  Previously, we introduced multi-core parallelism & cache coherence —Today.
CSE 120 Principles of Operating
CS703 – Advanced Operating Systems
Background on the need for Synchronization
Atomic Operations in Hardware
Atomic Operations in Hardware
Semaphores and Condition Variables
More Threads and Synchronization
Lecture 12: Peterson’s Solution and Hardware Support
Jonathan Walpole Computer Science Portland State University
Jonathan Walpole Computer Science Portland State University
UNIVERSITY of WISCONSIN-MADISON Computer Sciences Department
Coordination Lecture 5.
Implementing Mutual Exclusion
Implementing Mutual Exclusion
Kernel Synchronization II
Lecture 12: Peterson’s Solution and Hardware Support
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
CS333 Intro to Operating Systems
CSE 451: Operating Systems Autumn 2009 Module 7 Synchronization
Presentation transcript:

Implementing Synchronization

Synchronization 101 Synchronization constrains the set of possible interleavings: Threads “agree” to stay out of each other’s way and/or to coordinate their activities. Example: mutual exclusion primitives (locks) voluntary blocking or spin-waiting on entrance to critical sections notify blocked or spinning peers on exit from the critical section There are several ways to implement locks. spinning (spinlock) or blocking (mutex) or hybrid Correct synchronization primitives are “magic”. requires hardware support and/or assistance from the scheduler

Locks Locks can be used to ensure mutual exclusion in conflicting critical sections. A lock is an object, a data item in memory. Methods: Lock::Acquire and Lock::Release. Threads pair calls to Acquire and Release. Acquire before entering a critical section. Release after leaving a critical section. Between Acquire/Release, the lock is held. Acquire does not return until any previous holder releases. Waiting locks can spin (a spinlock) or block (a mutex). A A R R

Portrait of a Lock in Motion A A R R

/* shared by all threads */ int counters[N]; int total; /* * Increment a counter by a specified value, and keep a running sum. * This is called repeatedly by each of N threads. * tid is a thread identifier unique across all threads. * value is just some arbitrary number. */ void TouchCount(int tid, int value) { counters[tid] += value; total += value; } Example: Per-Thread Counts and Total

Reading Between the Lines of C /* counters[tid] += value; total += value; */ loadcounters, R1; load counters base load8(SP), R2; load tid index shlR2, #2, R2; index = index * sizeof(int) addR1, R2, R1; compute index to array load4(SP), R3; load value load(R1), R2; load counters[tid] addR2, R3, R2; counters[tid] += value storeR2, (R1); store back to counters[tid] loadtotal, R2; load total addR2, R3, R2; total += value storeR2, total; store total vulnerable between load and store of counters[tid]...but it’s non-shared. vulnerable between load and store of total, which is shared. load add store load add store

Using a Lock for the Counter/Sum Example int counters[N]; int total; Lock *lock; /* * Increment a counter by a specified value, and keep a running sum. */ void TouchCount(int tid, int value) { lock->Acquire(); counters[tid] += value;/* critical section code is atomic...*/ total += value;/* …as long as the lock is held */ lock->Release(); }

Implementing Spinlocks: First Cut class Lock { int held; } void Lock::Acquire() { while (held);“busy-wait” for lock holder to release held = 1; } void Lock::Release() { held = 0; }

Spinlocks: What Went Wrong void Lock::Acquire() { while (held);/* test */ held = 1; /* set */ } void Lock::Release() { held = 0; } Race to acquire: two threads could observe held == 0 concurrently, and think they both can acquire the lock.

What Are We Afraid Of? Potential problems with the “rough” spinlock implementation: (1) races that violate mutual exclusion involuntary context switch between test and set on a multiprocessor, race between test and set on two CPUs (2) wasteful spinning lock holder calls sleep or yield interrupt handler acquires a busy lock involuntary context switch for lock holder Which are implementation issues, and which are problems with spinlocks themselves?

The Need for an Atomic “Toehold” To implement safe mutual exclusion, we need support for some sort of “magic toehold” for synchronization. The lock primitives themselves have critical sections to test and/or set the lock flags. These primitives must somehow be made atomic. uninterruptible a sequence of instructions that executes “all or nothing” Two solutions: (1) hardware support: atomic instructions (test-and-set) (2) scheduler control: disable timeslicing (disable interrupts)

Atomic Instructions: Test-and-Set Spinlock::Acquire () { while(held); held = 1; } Wrong load4(SP), R2; load “this” busywait: load 4(R2), R3; load “held” flag bnzR3, busywait; spin if held wasn’t zero store#1, 4(R2); held = 1 Right load4(SP), R2; load “this” busywait: tsl4(R2), R3; test-and-set this->held bnzR3,busywait; spin if held wasn’t zero load test store load test store Solution: TSL atomically sets the flag and leaves the old value in a register. Problem: interleaved load/test/store.

On Disabling Interrupts Nachos has a primitive to disable interrupts, which we will use as a toehold for synchronization. Temporarily block notification of external events that could trigger a context switch. e.g., clock interrupts (ticks) or device interrupts In a “real” system, this is available only to the kernel. why? Disabling interrupts is insufficient on a multiprocessor. It is thus a dumb way to implement spinlocks. We will use it ONLY as a toehold to implement “proper” synchronization. a blunt instrument to use as a last resort

Implementing Locks: Another Try class Lock { } void Lock::Acquire() { disable interrupts; } void Lock::Release() { enable interrupts; } Problems?

Implementing Mutexes: Rough Sketch class Lock { int held; Thread* waiting; } void Lock::Acquire() { if (held) { waiting = currentThread; currentThread->Sleep(); } held = 1; } void Lock::Release() { held = 0; if (waiting)/* somebody’s waiting: wake up */ scheduler->ReadyToRun(waiting); }

Nachos Thread States and Transitions running readyblocked Scheduler::Run Scheduler::ReadyToRun (Wakeup) Thread::Sleep (voluntary) Thread::Yield (voluntary or involuntary) currentThread->Yield(); currentThread->Sleep();

Implementing Mutexes: A First Cut class Lock { int held; List sleepers; } void Lock::Acquire() { while (held) {Why the while loop? sleepers.Append((void*)currentThread); currentThread->Sleep(); } held = 1; Is this safe? } void Lock::Release() { held = 0; if (!sleepers->IsEmpty())/* somebody’s waiting: wake up */ scheduler->ReadyToRun((Thread*)sleepers->Remove()); }

Mutexes: What Went Wrong void Lock::Acquire() { while (held) { sleepers.Append((void*)currentThread); currentThread->Sleep(); } held = 1; } void Lock::Release() { held = 0; if (!sleepers->IsEmpty())/* somebody’s waiting: wake up */ scheduler->ReadyToRun((Thread*)sleepers->Remove()); } Potential missed wakeup: holder could Release before thread is on sleepers list. Potential missed wakeup: holder could call to wake up before we are “fully asleep”. Race to acquire: two threads could observe held == 0 concurrently, and think they both can acquire the lock. Potential corruption of sleepers list in a race between two Acquires or an Acquire and a Release.

Thread* waiter = 0; void await() { waiter = currentThread;/* “I’m sleeping” */ currentThread->Sleep();/* sleep */ } void awake() { if (waiter) scheduler->ReadyToRun(waiter); /* wakeup */ waiter = (Thread*)0; } The Trouble with Sleep/Wakeup switch here for missed wakeup any others? A simple example of the use of sleep/wakeup in Nachos.

Using Sleep/Wakeup Safely Thread* waiter = 0; void await() { disable interrupts waiter = currentThread;/* “I’m sleeping” */ currentThread->Sleep();/* sleep */ enable interrupts } void awake() { disable interrupts if (waiter)/* wakeup */ scheduler->ReadyToRun(waiter); waiter = (Thread*)0;/* “you’re awake” */ enable interrupts } Disabling interrupts prevents a context switch between “I’m sleeping” and “sleep”. Disabling interrupts prevents a context switch between “wakeup” and “you’re awake”. Will this work on a multiprocessor? Nachos Thread::Sleep requires disabling interrupts.

What to Know about Sleep/Wakeup 1. Sleep/wakeup primitives are the fundamental basis for all blocking synchronization. 2. All use of sleep/wakeup requires some additional low-level mechanism to avoid missed and double wakeups. disabling interrupts, and/or constraints on preemption, and/or (Unix kernels use this instead of disabling interrupts) spin-waiting(on a multiprocessor) 3. These low-level mechanisms are tricky and error-prone. 4. High-level synchronization primitives take care of the details of using sleep/wakeup, hiding them from the caller. semaphores, mutexes, condition variables