D u k e S y s t e m s CPS 310 Threads and Concurrency: Topics Jeff Chase Duke University

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

Operating Systems: Monitors 1 Monitors (C.A.R. Hoare) higher level construct than semaphores a package of grouped procedures, variables and data i.e. object.
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 ©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 Semaphores and Monitors CIS450 Winter 2003 Professor Jinhua Guo.
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.
1 Semaphores and Monitors: High-level Synchronization Constructs.
COSC 3407: Operating Systems Lecture 8: Semaphores, Monitors and Condition Variables.
Concurrency, Race Conditions, Mutual Exclusion, Semaphores, Monitors, Deadlocks Chapters 2 and 6 Tanenbaum’s Modern OS.
Chapter 2: Processes Topics –Processes –Threads –Process Scheduling –Inter Process Communication (IPC) Reference: Operating Systems Design and Implementation.
1 CS318 Project #3 Preemptive Kernel. 2 Continuing from Project 2 Project 2 involved: Context Switch Stack Manipulation Saving State Moving between threads,
Monitors CSCI 444/544 Operating Systems Fall 2008.
Semaphores CSCI 444/544 Operating Systems Fall 2008.
Jonathan Walpole Computer Science Portland State University
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.
A. Frank - P. Weisberg Operating Systems Introduction to Cooperating Processes.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts, Amherst Operating Systems CMPSCI 377 Lecture.
Concurrency Recitation – 2/24 Nisarg Raval Slides by Prof. Landon Cox.
CS510 Concurrent Systems Introduction to Concurrency.
1 Concurrent Languages – Part 1 COMP 640 Programming Languages.
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.
4061 Session 21 (4/3). Today Thread Synchronization –Condition Variables –Monitors –Read-Write Locks.
Mode, space, and context: the basics
CPS110: Implementing threads Landon Cox. Recap and looking ahead Hardware OS Applications Where we’ve been Where we’re going.
Mode, space, and context: the basics Jeff Chase Duke University.
Threads Doing Several Things at Once. Threads n What are Threads? n Two Ways to Obtain a New Thread n The Lifecycle of a Thread n Four Kinds of Thread.
D u k e S y s t e m s More Synchronization featuring Producer/Consumer with Semaphores Jeff Chase Duke University.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
1 Condition Variables CS 241 Prof. Brighten Godfrey March 16, 2012 University of Illinois.
13/03/07Week 21 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University Ankara, TURKEY URL:
Problems with Semaphores Used for 2 independent purposes –Mutual exclusion –Condition synchronization Hard to get right –Small mistake easily leads to.
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.
1 Previous Lecture Overview  semaphores provide the first high-level synchronization abstraction that is possible to implement efficiently in OS. This.
Operating Systems CMPSC 473 Signals, Introduction to mutual exclusion September 28, Lecture 9 Instructor: Bhuvan Urgaonkar.
CS533 Concepts of Operating Systems Jonathan Walpole.
Dining Philosophers & Monitors Questions answered in this lecture: How to synchronize dining philosophers? What are monitors and condition variables? What.
CS510 Concurrent Systems Jonathan Walpole. Introduction to Concurrency.
SMP Basics KeyStone Training Multicore Applications Literature Number: SPRPxxx 1.
1 5-High-Performance Embedded Systems using Concurrent Process (cont.)
© 2004, D. J. Foreman 1 Monitors and Inter-Process Communication.
Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections.
CPS110: Implementing threads on a uni-processor Landon Cox January 29, 2008.
pThread synchronization
CS703 - Advanced Operating Systems
CPS110: Reader-writer locks
CS703 – Advanced Operating Systems
Background on the need for Synchronization
Threads Threads.
Multithreading Tutorial
Review: threads and synchronization
Monitors, Condition Variables, and Readers-Writers
CS510 Operating System Foundations
Threads and Synchronization
CSCI 511 Operating Systems Chapter 5 (Part C) Monitor
Lecture 14: Pthreads Mutex and Condition Variables
Multithreading Tutorial
Chapter 30 Condition Variables
Threads Chapter 5 2/17/2019 B.Ramamurthy.
Multithreading Tutorial
Threads Chapter 5 2/23/2019 B.Ramamurthy.
Multithreading Tutorial
Lecture 14: Pthreads Mutex and Condition Variables
Kernel Synchronization II
CS333 Intro to Operating Systems
Don Porter Portions courtesy Emmett Witchel
Review The Critical Section problem Peterson’s Algorithm
Presentation transcript:

D u k e S y s t e m s CPS 310 Threads and Concurrency: Topics Jeff Chase Duke University

Terminology and syntax The abstractions for concurrency control in this class are now sort-of universal at the OS/API level. Monitors (mutex+CV) with Mesa semantics appear in: – Java (e.g., on Android) and JVM languages (e.g., Scala) – POSIX threads or Pthreads (used on Linux and MacOS/iOS) – Windows, C#/.NET, and other Microsoft systems Terminology and APIs vary a bit. – mutex == lock == Java “synchronized” – monitor == mutex + condition variable (CV) – signal() == notify(), broadcast() == notifyAll() The slides use interchangeable terms interchangeably.

Example: the soda/HFCS machine Vending machine (buffer) Soda drinker (consumer) Delivery person (producer)

Producer-consumer code producer () { add one soda to machine } consumer () { take a soda from machine }

Solving producer-consumer 1.What are the variables/shared state?  Soda machine buffer  Number of sodas in machine (≤ MaxSodas) 2.Locks?  1 to protect all shared state (sodaLock) 3.Mutual exclusion?  Only one thread can manipulate machine at a time 4.Ordering constraints?  Consumer must wait if machine is empty (CV hasSoda)  Producer must wait if machine is full (CV hasRoom)

Producer-consumer code producer () { lock add one soda to machine unlock } consumer () { lock take a soda from machine unlock }

Producer-consumer code producer () { lock wait if full add one soda to machine notify (not empty) unlock } consumer () { lock wait if empty take a soda from machine notify (not full) unlock }

Producer-consumer code producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock, hasRoom) } add one soda to machine signal (hasSoda) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasSoda) } take a soda from machine signal (hasRoom) unlock (sodaLock) } MxCV1MxCV2 CV1 CV2

Producer-consumer code synchronized producer () { while(numSodas==maxSodas) { wait () } put a soda from machine notify(); } synchronized consumer () { while (numSodas == 0) { o.wait () } take a soda from machine notify(); }

Producer-consumer code consumer () { synchronized(o) { while (numSodas == 0) { o.wait () } take a soda o.notify(); } }

Producer-consumer code producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock, hasRoom) } fill machine with soda broadcast(hasSoda) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasSoda) } take a soda from machine signal(hasRoom) unlock (sodaLock) } The signal should be a broadcast if the producer can produce more than one resource, and there are multiple consumers. lpcox slide edited by chase

Variations: looping producer  Producer  Infinite loop ok?  Why/why not?  Release lock in wait call producer () { lock (sodaLock) while (1) { while(numSodas==MaxSodas){ wait (sodaLock, hasRoom) } add soda to machine signal (hasSoda) } unlock (sodaLock) }

Variations: resting producer  Producer  Sleep ok?  Why/why not?  Shouldn’t hold locks during a slow operation producer () { lock (sodaLock) while (1) { sleep (1 hour) while(numSodas==MaxSodas){ wait (sodaLock, hasRoom) } add soda to machine signal (hasSoda) } unlock (sodaLock) }

Variations: one CV? producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock,hasRorS) } add one soda to machine signal(hasRorS) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasRorS) } take a soda from machine signal (hasRorS) unlock (sodaLock) } Two producers, two consumers: who consumes a signal? ProducerA and ConsumerB wait while ConsumerC signals? MxCVMxCV

Variations: one CV? producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock,hasRorS) } add one soda to machine signal (hasRorS) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasRorS) } take a soda from machine signal (hasRorS) unlock (sodaLock) } Is it possible to have a producer and consumer both waiting? max=1, cA and cB wait, pC adds/signals, pD waits, cA wakes

Variations: one CV? producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock,hasRorS) } add one soda to machine signal (hasRorS) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasRorS) } take a soda from machine signal (hasRorS) unlock (sodaLock) } How can we make the one CV solution work?

Variations: one CV? producer () { lock (sodaLock) while(numSodas==MaxSodas){ wait (sodaLock,hasRorS) } add one soda to machine broadcast (hasRorS) unlock (sodaLock) } consumer () { lock (sodaLock) while (numSodas == 0) { wait (sodaLock,hasRorS) } take a soda from machine broadcast (hasRorS) unlock (sodaLock) } Use broadcast instead of signal: safe but slow.

Broadcast vs signal  Can I always use broadcast instead of signal?  Yes, assuming threads recheck condition  And they should: “loop before you leap”!  Mesa semantics requires it anyway: another thread could get to the lock before wait returns.  Why might I use signal instead?  Efficiency (spurious wakeups)  May wakeup threads for no good reason  “Signal is just a performance hint”. lpcox slide edited by chase

Locking a critical section mx->Acquire(); x = x + 1; mx->Release(); mx->Acquire(); x = x + 1; mx->Release(); load add store load add store Holding a shared mutex prevents competing threads from entering a critical section protected by the shared mutex (monitor). At most one thread runs in the critical section at a time. A A R R  The threads may run the critical section in either order, but the schedule can never enter the grey region where both threads execute the section at the same time. x=x+1

Locking a critical section mx->Acquire(); x = x + 1; mx->Release(); mx->Acquire(); x = x + 1; mx->Release(); load add store load add store load add store load add store load add store load add store Holding a shared mutex prevents competing threads from entering a critical section. If the critical section code acquires the mutex, then its execution is serialized: only one thread runs it at a time.   synchronized serialized atomic

How about this? x = x + 1; mx->Acquire(); x = x + 1; mx->Release(); load add store load add store A B

How about this? x = x + 1; mx->Acquire(); x = x + 1; mx->Release(); load add store load add store The locking discipline is not followed: purple fails to acquire the lock mx. Or rather: purple accesses the variable x through another program section A that is mutually critical with B, but does not acquire the mutex. A locking scheme is a convention that the entire program must follow. A B

How about this? mx->Acquire(); x = x + 1; mx->Release(); load add store load add store B lock->Acquire(); x = x + 1; lock->Release(); A

How about this? mx->Acquire(); x = x + 1; mx->Release(); load add store load add store This guy is not acquiring the right lock. Or whatever. They’re not using the same lock, and that’s what matters. A locking scheme is a convention that the entire program must follow. B lock->Acquire(); x = x + 1; lock->Release(); A

Ucontext library routines The system can use ucontext routines to: – “Freeze” at a point in time of the execution – Restart execution from a frozen moment in time – Execution continues where it left off…if the memory state is right. The system can implement multiple independent threads of execution within the same address space. – Create a context for a new thread with makecontext: when switched in it will call a specified procedure with specified arg. – Modify saved contexts at will. – Context switch with swapcontext: transfer a core from one thread to another

Messing with the context #include int count = 0; ucontext_t context; int main() { int i = 0; getcontext(&context); count += 1; i += 1; sleep(2); printf(”…", count, i); setcontext(&context); } ucontext Standard C library routines to: Save current register context to a block of memory (getcontext from core) Load/restore current register context from a block of memory (setcontext) Also: makecontext, swapcontext Details of the saved context (ucontext_t structure) are machine-dependent.

Messing with the context (2) #include int count = 0; ucontext_t context; int main() { int i = 0; getcontext(&context); count += 1; i += 1; sleep(1); printf(”…", count, i); setcontext(&context); } Loading the saved context transfers control to this block of code. (Why?) What about the stack? Save CPU core context to memory Load core context from memory

Messing with the context (3) #include int count = 0; ucontext_t context; int main() { int i = 0; getcontext(&context); count += 1; i += 1; sleep(1); printf(”…", count, i); setcontext(&context); } chase$ cc -o context0 context0.c < warnings: ucontext deprecated on MacOS > chase$./context …

Reading behind the C Disassembled code: movl0x a(%rip),%ecx addl$0x ,%ecx movl%ecx,0x e(%rip) movl0xfc(%rbp),%ecx addl$0x ,%ecx movl%ecx,0xfc(%rbp) %rip and %rbp are set “right”, then these references “work”. count += 1; i += 1; On MacOS: chase$ man otool chase$ otool –vt context0 … On this machine, with this cc: Static global _count is addressed relative to the location of the code itself, as given by the PC register [%rip is instruction pointer register] Local variable i is addressed as an offset from stack frame. [%rbp is stack frame base pointer]

Messing with the context (4) #include int count = 0; ucontext_t context; int main() { int i = 0; getcontext(&context); count += 1; i += 1; sleep(1); printf(”…", count, i); setcontext(&context); } chase$ cc –O2 -o context0 context0.c < warnings: ucontext deprecated on MacOS > chase$./context … What happened?

Messing with the context (5) #include int count = 0; ucontext_t context; int main() { int i = 0; getcontext(&context); count += 1; i += 1; sleep(1); printf(”…", count, i); setcontext(&context); } What does this do?