Reminder from last time

Similar documents
Event Counts: Producer-Consumer. Sequencers. Concurrent Systems 8L for Part IB Handout 2. Event Counts & Sequencers. Dr.

Summary Semaphores. Passing the Baton any await statement. Synchronisation code not linked to the data

CSE 153 Design of Operating Systems

Operating Systems ECE344

Opera&ng Systems ECE344

CSE 120 Principles of Operating Systems Spring 2016

Real Time Operating Systems and Middleware

Reminder from last time

Reminder from last <me

The Deadlock Lecture

Semaphores. Blocking in semaphores. Two types of semaphores. Example: Bounded buffer problem. Binary semaphore usage

CS533 Concepts of Operating Systems. Jonathan Walpole

Lecture 6 (cont.): Semaphores and Monitors

Condition Variables CS 241. Prof. Brighten Godfrey. March 16, University of Illinois

CSE 451: Operating Systems Spring Module 10 Semaphores, Condition Variables, and Monitors

CS 318 Principles of Operating Systems

Concurrency. On multiprocessors, several threads can execute simultaneously, one on each processor.

CSE 120 Principles of Operating Systems Spring 2016

Operating systems and concurrency (B08)

Semaphores. To avoid busy waiting: when a process has to wait, it will be put in a blocked queue of processes waiting for the same event

Semaphores. Semaphores. Semaphore s operations. Semaphores: observations

Introduction to OS Synchronization MOS 2.3

CS 318 Principles of Operating Systems

Semaphore. Originally called P() and V() wait (S) { while S <= 0 ; // no-op S--; } signal (S) { S++; }

CS 31: Intro to Systems Misc. Threading. Kevin Webb Swarthmore College December 6, 2018

Real-Time and Concurrent Programming Lecture 4 (F4): Monitors: synchronized, wait and notify

CS510 Operating System Foundations. Jonathan Walpole

Semaphores. Jinkyu Jeong Computer Systems Laboratory Sungkyunkwan University

Lecture 8: September 30

G52CON: Concepts of Concurrency

CS 318 Principles of Operating Systems

Concurrency and Synchronisation

CHAPTER 6: PROCESS SYNCHRONIZATION

CIS Operating Systems Application of Semaphores. Professor Qiang Zeng Spring 2018

Operating Systems CMPSCI 377 Spring Mark Corner University of Massachusetts Amherst

Synchronization 1. Synchronization

Concurrency and Synchronisation

Learning Outcomes. Concurrency and Synchronisation. Textbook. Concurrency Example. Inter- Thread and Process Communication. Sections & 2.

Administrivia. Assignments 0 & 1 Class contact for the next two weeks Next week. Following week

Concurrency. On multiprocessors, several threads can execute simultaneously, one on each processor.

Semaphores and Monitors: High-level Synchronization Constructs

Synchronization. CSCI 5103 Operating Systems. Semaphore Usage. Bounded-Buffer Problem With Semaphores. Monitors Other Approaches

Classical concurrency control: topic overview 1 In these lectures we consider shared writeable data in main memory

Lecture 7: CVs & Scheduling

Overview. Lab advice. Lab advice. Readers-writers problem. Readers-writers solution. Real-time Systems D0003E 3/10/2009

Concurrency. Chapter 5

Locks and semaphores. Johan Montelius KTH

Synchronization Primitives

Process Management And Synchronization

Concurrency and Synchronisation. Leonid Ryzhyk

Module 6: Process Synchronization. Operating System Concepts with Java 8 th Edition

Operating Systems. Thread Synchronization Primitives. Thomas Ropars.

Threads and Synchronization. Kevin Webb Swarthmore College February 15, 2018

Concurrent Programming Lecture 10

Operating Systems. Lecture 8

Synchronization 1. Synchronization

Operating Systems (2INC0) 2017/18

Multitasking / Multithreading system Supports multiple tasks

Models of concurrency & synchronization algorithms

There are 8 total numbered pages, 6 Questions. You have 60 minutes. Budget your time carefully!

Dealing with Issues for Interprocess Communication

Concurrency: a crash course

Concurrency. On multiprocessors, several threads can execute simultaneously, one on each processor.

CSE 451: Operating Systems Winter Synchronization. Gary Kimura

Solving the Producer Consumer Problem with PThreads

Concurrency. On multiprocessors, several threads can execute simultaneously, one on each processor.

Atomic Instructions! Hakim Weatherspoon CS 3410, Spring 2011 Computer Science Cornell University. P&H Chapter 2.11

Introduction to parallel computing

But first... Re: generic parking. A cyclic POSIX thread (2) Real-time Systems SMD138. Lecture 14: Real-time languages (Burns & Wellings ch.

Operating Systems. Designed and Presented by Dr. Ayman Elshenawy Elsefy

Chapter 6: Process Synchronization

Lesson 6: Process Synchronization

CS 326 Operating Systems Synchronization. Greg Benson Department of Computer Science University of San Francisco

Overview. CMSC 330: Organization of Programming Languages. Concurrency. Multiprocessors. Processes vs. Threads. Computation Abstractions

recap, what s the problem Locks and semaphores Total Store Order Peterson s algorithm Johan Montelius 0 0 a = 1 b = 1 read b read a

Deadlock and Monitors. CS439: Principles of Computer Systems September 24, 2018

Locks and semaphores. Johan Montelius KTH

Operating Systems. Lecture 4 - Concurrency and Synchronization. Master of Computer Science PUF - Hồ Chí Minh 2016/2017

What's wrong with Semaphores?

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

CMSC421: Principles of Operating Systems

Deadlock and Monitors. CS439: Principles of Computer Systems February 7, 2018

Resource Access Control (2) Real-Time and Embedded Systems (M) Lecture 14

W4118 Operating Systems. Instructor: Junfeng Yang

IV. Process Synchronisation

Java Monitors. Parallel and Distributed Computing. Department of Computer Science and Engineering (DEI) Instituto Superior Técnico.

Synchronization. CS 416: Operating Systems Design, Spring 2011 Department of Computer Science Rutgers University

Virtual Machine Design

CSC501 Operating Systems Principles. Process Synchronization

In class we examined the need for concurrent execution paths like a consumer and a producer to synchronize their access to a shared ring buffer.

Chapter 5: Process Synchronization. Operating System Concepts 9 th Edition

Enforcing Mutual Exclusion Using Monitors

Monitors; Software Transactional Memory

Chapter 6: Process Synchronization. Operating System Concepts 9 th Edit9on

CS 333 Introduction to Operating Systems. Class 6 Monitors and Message Passing. Jonathan Walpole Computer Science Portland State University

Classic Problems of Synchronization

Operating Systems CMPSC 473. Synchronization February 26, Lecture 12 Instructor: Trent Jaeger

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

G Programming Languages Spring 2010 Lecture 13. Robert Grimm, New York University

CS370 Operating Systems

Transcription:

Concurrent systems Lecture 3: CCR, monitors, and concurrency in practice DrRobert N. M. Watson 1 Reminder from last time Implementing mutual exclusion: hardware support for atomicity and inter-processor interrupts Semaphores for mutual exclusion, condition synchronisation, and resource allocation Two-party and generalised producerconsumer relationships 2 1

From last time: Semaphores summary Powerful abstraction for implementing concurrency control: mutual exclusion & condition synchronization Better than read-and-set() but correct use requires considerable care e.g. forget to wait(), can corrupt data e.g. forget to signal(), can lead to infinite delay generally get more complex as add more semaphores Used internally in some OSes and libraries, but generally deprecated for other mechanisms Semaphores are a low-level implementation primitive they say what to do, rather than describe programming goals3 This time Multi-Reader Single-Writer (MRSW) locks Starvation and fairness Alternatives to semaphores/locks: Conditional critical regions (CCRs) Monitors Condition variables Signal-and-wait vs. signal-and-continue semantics Concurrency primitives in practice Concurrency primitives wrap-up 4 2

Multiple-Readers Single-Writer (MRSW) Another common synchronisation paradigm is MRSW Shared resource accessed by a set of threads e.g. cached set of DNS results Safe for many threads to read simultaneously, but a writer (updating) must have exclusive access MRSW locks have read lock and write lock operations Mutual exclusion vs. data stability Simple implementation uses a single semaphore as a mutual exclusion lock for write access Any writer must wait to acquire this First reader also acquires this; last reader releases it Protect reader counts using another semaphore 5 Simplest MRSW solution int nr = 0; // number of readers rsem = new Semaphore(1); // protects access to nr wsem = new Semaphore(1); // protects writes to data // a writer thread wait(wsem);.. perform update to data signal(wsem); Code for writer is simple.. but reader case more complex: must track number of readers, and acquire or release overall lock as appropriate // a reader thread wait(rsem); nr = nr + 1; if (nr == 1) // first in wait(wsem); signal(rsem);.. read data wait(rsem); nr = nr - 1; if (nr == 0) // last out signal(wsem); signal(rsem); 6 3

Simplest MRSW solution Solution on previous slide is correct Only one writer will be able to access data structure, but providing there is no writer any number of readers can access it However writers can starve If readers continue to arrive, a writer might wait forever (since readers will not release wsem) Would be fairer if a writer only had to wait for all current readers to exit Can implement this with an additional semaphore 7 A fairer MRSW solution int nr = 0; // number of readers rsem = new Semaphore(1); // protects access to nr wsem = new Semaphore(1); // protects writes to data turn = new Semaphore(1); // write is awaiting a turn Once a writer tries to enter, it will acquire turn which prevents any further readers from entering // a writer thread wait(turn); wait(wsem);.. perform update to data signal(turn); signal(wsem); // a reader thread wait(turn); signal(turn); wait(rsem); nr = nr + 1; if (nr == 1) // first in wait(wsem); signal(rsem);.. read data wait(rsem); nr = nr - 1; if (nr == 0) // last out signal(wsem); signal(rsem); 8 4

Conditional Critical Regions Implementing synchronisation with locks is difficult Only the developer knows what data is protected by which locks One early (1970s) effort to address this problem was CCRs Variables can be explicitly declared as shared Code can be tagged as using those variables, e.g. shared int A, B, C; region A, B { await( /* arbitrary condition */); // critical code using A and B Compiler automatically declares and manages underlying primitives for mutual exclusion or synchronization e.g. wait/signal, read/await/advance, Easier for programmer (c/f previous implementations) 9 CCR example: Producer-Consumer shared int buffer[n]; shared int in = 0; shared int out = 0; // producer thread while(true) { item = produce(); region in, out, buffer { await((in out) < N); buffer[in % N] = item; in = in + 1; // consumer thread while(true) { region in, out, buffer { await((in-out) > 0); item = buffer[out%n]; out = out + 1; consume(item); Explicit (scoped) declaration of critical sections automatically acquire mutual exclusion lock on region entry Powerful await(): any evaluable predicate 10 5

CCR pros and cons On the surface seems like a definite step up Programmer focuses on variables to be protected, compiler generates appropriate semaphores (etc) Compiler can also check that shared variables are never accessed outside a CCR (still rely on programmer annotating correctly) But await(<expr>) is problematic What to do if the (arbitrary) <expr> is not true? very difficult to work out when it becomes true? Solution was to leave region & try to re-enter: this is busy waiting, which is very inefficient 11 Monitors Monitors are similar to CCRs (implicit mutual exclusion), but modify them in two ways Waiting is limited to explicit condition variables All related routines are combined together, along with initialization code, in a single construct Idea is that only one thread can ever be executing within the monitor If a thread calls a monitor method, it will block (enqueue) if another thread is holding the monitor Hence all methods within the monitor can proceed on the basis that mutual exclusion has been ensured Java s synchronized primitive implements monitors 12 6

Example Monitor syntax monitor <foo> { All related data and methods kept together // declarations of shared variables // set of procedures (or methods) procedure P1(...) {... procedure P2(...) {...... procedure PN(...) {... { /* monitor initialization code */ Shared variables only accessible from within monitor methods Invoking any procedure causes an [implicit] mutual exclusion lock to be taken Shared variables can be initialized here 13 Condition Variables Mutual exclusion not always sufficient Condition synchronisation -- e.g., wait for a condition to occur Monitors allow condition variables Explicitly declared and managed by programmer NB: No integrated counter not a stateful semaphore! Support three operations: wait(cv) { suspend thread and add it to the queue for cv; release monitor lock signal(cv) { if any threads queued on cv, wake one; broadcast(cv) { wake all threads queued on cv; 14 7

Monitor Producer-Consumer solution? monitor ProducerConsumer { If buffer is full (in==out+n), int in, out, buf[n]; must wait for consumer condition notfull = TRUE, notempty = FALSE; procedure produce(item) { if ((in-out) == N) wait(notfull); buf[in % N] = item; if ((in-out) == 0) signal(notempty); in = in + 1; procedure int consume() { if ((in-out) == 0) wait(notempty); item = buf[out % N]; if ((in-out) == N) signal(notfull); out = out + 1; return(item); /* init */ { in = out = 0; If buffer was empty (in==out), signal the consumer If buffer is empty (in==out), must wait for producer If buffer was full before, signal the producer 15 Does this work? Depends on implementation of wait() & signal() Imagine two threads, T1 and T2 T1 enters the monitor and calls wait(c) this suspends T1, places it on the queue for C, and unlocks the monitor Next T2 enters the monitor, and invokes signal(c) Now T1 is unblocked (i.e. capable of running again) but can only have one thread active inside a monitor! If we let T2 continue (signal-and-continue), T1 must queue for re-entry to the monitor And no guarantee it will be next to enter Otherwise T2 must be suspended (signal-and-wait), allowing T1 to continue 16 8

Signal-and-Wait ( Hoare Monitors ) Consider a queue E to enter monitor If monitor is occupied, threads are added to E May not be FIFO, but should be fair If thread T1 waits on C, added to queue C If T2 enters monitor & signals, waking T1 T2 is added to a new queue S in front of E T1 continues and eventually exits (or re-waits) Some thread on S chosen to resume Only admit a thread from E when S is empty 17 Signal-and-Wait pros and cons We call signal() exactly when condition is true, then directly transfer control to waking thread Hence condition will still be true! But more difficult to implement And can be complex to reason about (a call to signal may or may not result in a context switch) Hence we must ensure that any invariants are maintained at time we invoke signal() With these semantics, our example is broken: we signal() before incrementing in/out 18 9

Same code as slide 11 Monitor Producer-Consumer solution? monitor ProducerConsumer { If buffer is full (in==out+n), int in, out, buf[n]; must wait for consumer condition notfull = TRUE, notempty = FALSE; procedure produce(item) { if ((in-out) == N) wait(notfull); buf[in % N] = item; if ((in-out) == 0) signal(notempty); in = in + 1; procedure int consume() { if ((in-out) == 0) wait(notempty); item = buf[out % N]; if ((in-out) == N) signal(notfull); out = out + 1; return(item); /* init */ { in = out = 0; If buffer was empty (in==out), signal the consumer If buffer is empty (in==out), must wait for producer If buffer was full before, signal the producer 19 Signal-and-Continue Alternative semantics introduced by Mesa programming language (Xerox PARC) An invocation of signal() moves a thread from the condition queue C to the entry queue E Invoking threads continues until exits (or waits) Simpler to build but now not guaranteed that condition is true when resume! Other threads may have executed after the signal, but before you continue 20 10

Signal-and-Continue example (1) P 1 enters P 1 waits as!notfull P 1 tries to enter, enqueued on E P 1 wakes up despite!notfull P 1 P 2 Buffer P 2 tries to enter, enqueued on E full P 2 enters!full P 2 inserts item, sets!notfull full C 1 C 1 enters C 1 removes item, signals notfull With signal-and-continue semantics, must use while instead of if in case the condition becomes false while waiting Thread in monitor Thread waits for monitor Buffer has space (notfull) Thread waits for condition Buffer is full (!notfull) 21 Signal-and-Continue example (2) Consider multiple producer-consumer threads 1. P1 enters. Buffer is full so blocks on queue for C 2. C1 enters. 3. P2 tries to enter; occupied, so queues on E 4. C1 continues, consumes, and signals C ( notfull ) 5. P1 unblocks; monitor occupied, so queues on E 6. C1 exits, allowing P2 to enter 7. P2 fills buffer, and exits monitor 8. P1 resumes and tries to add item BUG! Hence must re-test condition: i.e. while( (in-out) == N) wait(notfull); 22 11

Monitor Producer-Consumer solution? While buffer is full monitor ProducerConsumer { (in==out+n), must wait for int in, out, buf[n]; consumer condition notfull = TRUE, notempty = FALSE; procedure produce(item) { while ((in-out) == N) wait(notfull); buf[in % N] = item; if ((in-out) == 0) signal(notempty); in = in + 1; procedure int consume() { while ((in-out) == 0) wait(notempty); item = buf[out % N]; if ((in-out) == N) signal(notfull); out = out + 1; return(item); /* init */ { in = out = 0; if() replaced with while() for conditions If buffer was full (in==out), signal the consumer While buffer is empty (in==out), must wait for producer If buffer was full before, signal the producer 23 Monitors: summary Structured concurrency control groups together shared data and methods (today we d call this object-oriented) Considerably simpler than semaphores, but still perilous in places May be overly conservative sometimes: e.g. for MRSW cannot have >1 reader in monitor Typically must work around with entry and exit methods (BeginRead(), EndRead(), BeginWrite(), etc) Exercise: sketch a MRSW monitor implementation 24 12

Concurrency in practice Seen a number of abstractions for concurrency control Mutual exclusion and condition synchronization Next let s look at some concrete examples: FreeBSD kernels POSIX pthreads (C/C++ API) Java C# 25 Example: pthreads Standard (POSIX) threading API for C, C++, etc mutexes, condition variables, and barriers Mutexes are essentially binary semaphores: int pthread_mutex_init(pthread_mutex_t *mutex,...); int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t *mutex); A thread calling lock() blocks if the mutex is held trylock() is a non-blocking variant: returns immediately; returns 0 if lock acquired, or non-zero if not. 26 13

Example: pthreads Condition variables are Mesa-style: int pthread_cond_init(pthread_cond_t *cond,...); int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_signal(pthread_cond_t *cond); int pthread_cond_broadcast(pthread_cond_t *cond); No proper monitors: must manually code e.g. pthread_mutex_lock(&m); while (!condition) // Notice while() not if()! pthread_cond_wait(&c,&m); // do stuff if (condition) pthread_cond_broadcast(&c); pthread_mutex_unlock(&m); 27 Example: pthreads Barriers: explicit synchronization mechanism Wait until all threads reach some point E.g., in discrete event simulation, all parallel threads must complete one epoch before any begin on the next int pthread_barrier_init(pthread_barrier_t *b,..., N); int pthread_barrier_wait(pthread_barrier_t *b); pthread_barrier_init(&b,..., NTHREADS); for(i=0; i<nthreads; i++) pthread_create(..., worker,...); worker() { while(!done) { // do work for this round pthread_barrier_wait(&b); 28 14

Example: FreeBSD kernel Kernel provides spin locks, mutexes, conditional variables, reader-writer + read-mostly locks Semantics (roughly) modeled on POSIX threads A variety of deferred work primitives Fully preemptive and highly threaded (e.g., interrupt processing in threads) Interesting debugging tools such as DTrace, lock contention measurement, lock-order checking Concurrency case study for our last lecture 29 Example: Java [original] Synchronization inspired by monitors Objects already encapsulate data & methods! Can synchronise on other objects e.g., designated locks Mesa-style, but no explicit condition variables public class MyClass { // public synchronized void mymethod() throws...{ while(!condition) wait(); // do stuff if(condition) notifyall(); Java 5 provides many additional options 30 15

Example: C# Very similar to Java, but with explicit arguments public class MyClass { // public void mymethod() { lock(this) { while(!condition) Monitor.Wait(this); // do stuff if(condition) Monitor.PulseAll(this); Also provides spinlocks, reader-writer locks, semaphores, barriers, event synchronization, 31 Concurrency Primitives: Summary Concurrent systems require means to ensure: Safety (mutual exclusion in critical sections), and Progress (condition synchronization) Spinlocks (busy wait); semaphores; MRSWs, CCRs, and monitors Hardware primitives for synchronisation Signal-and-Wait vs. Signal-and-Continue Many of these are still used in practice subtle minor differences can be dangerous require care to avoid bugs E.g., lost wakeups More detail on implementation in our case study 32 16

Summary + next time Multi-Reader Single-Writer (MRSW) locks Alternatives to semaphores/locks: Conditional critical regions (CCRs) Monitors Condition variables Signal-and-wait vs. signal-and-continue semantics Concurrency primitives in practice Concurrency primitives wrap-up Next time: Problems with concurrency: deadlock, livelock, priorities Resource allocation graphs; deadlock {prevention, detection, recovery Priority and scheduling; priority inversion; priority inheritance 33 17