CS 3214 Computer Systems Lecture 21 Godmar Back.

Slides:



Advertisements
Similar presentations
CS492B Analysis of Concurrent Programs Lock Basics Jaehyuk Huh Computer Science, KAIST.
Advertisements

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.
/ PSWLAB Atomizer: A Dynamic Atomicity Checker For Multithreaded Programs By Cormac Flanagan, Stephen N. Freund 24 th April, 2008 Hong,Shin.
– 1 – , F’02 Traditional View of a Process Process = process context + code, data, and stack shared libraries run-time heap 0 read/write data Program.
1 Sharing Objects – Ch. 3 Visibility What is the source of the issue? Volatile Dekker’s algorithm Publication and Escape Thread Confinement Immutability.
CS510 Concurrent Systems Class 5 Threads Cannot Be Implemented As a Library.
Threads© Dr. Ayman Abdel-Hamid, CS4254 Spring CS4254 Computer Network Architecture and Programming Dr. Ayman A. Abdel-Hamid Computer Science Department.
Discussion Week 3 TA: Kyle Dewey. Overview Concurrency overview Synchronization primitives Semaphores Locks Conditions Project #1.
Carnegie Mellon /18-243: Introduction to Computer Systems Instructors: Bill Nace and Gregory Kesden (c) All Rights Reserved. All work.
Object Oriented Analysis & Design SDL Threads. Contents 2  Processes  Thread Concepts  Creating threads  Critical sections  Synchronizing threads.
Optimistic Design 1. Guarded Methods Do something based on the fact that one or more objects have particular states  Make a set of purchases assuming.
Operating Systems ECE344 Ashvin Goel ECE University of Toronto Mutual Exclusion.
CSC321 Concurrent Programming: §5 Monitors 1 Section 5 Monitors.
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.
Discussion Week 2 TA: Kyle Dewey. Overview Concurrency Process level Thread level MIPS - switch.s Project #1.
Operating Systems CSE 411 CPU Management Sept Lecture 10 Instructor: Bhuvan Urgaonkar.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
© Janice Regan, CMPT 300, May CMPT 300 Introduction to Operating Systems Operating Systems Processes and Threads.
CS533 – Spring Jeanie M. Schwenk Experiences and Processes and Monitors with Mesa What is Mesa? “Mesa is a strongly typed, block structured programming.
CMSC 330: Organization of Programming Languages Threads.
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.
Implementing Lock. From the Previous Lecture  The “too much milk” example shows that writing concurrent programs directly with load and store instructions.
CSCI1600: Embedded and Real Time Software Lecture 17: Concurrent Programming Steven Reiss, Fall 2015.
Implementing Mutual Exclusion Andy Wang Operating Systems COP 4610 / CGS 5765.
December 1, 2006©2006 Craig Zilles1 Threads & Atomic Operations in Hardware  Previously, we introduced multi-core parallelism & cache coherence —Today.
Kernel Synchronization David Ferry, Chris Gill CSE 522S - Advanced Operating Systems Washington University in St. Louis St. Louis, MO
CS 3214 Computer Systems.
A brief intro to: Parallelism, Threads, and Concurrency
CS703 – Advanced Operating Systems
Background on the need for Synchronization
Memory Consistency Models
Threads Cannot Be Implemented As a Library
Threads Threads.
Atomic Operations in Hardware
Atomic Operations in Hardware
Memory Consistency Models
Multiple Writers and Races
Semaphores and Condition Variables
CS510 Operating System Foundations
Threads and Memory Models Hal Perkins Autumn 2011
Designing Parallel Algorithms (Synchronization)
Kernel Synchronization II
Atomicity in Multithreaded Software
Synchronization and Semaphores
Jonathan Walpole Computer Science Portland State University
Threads and Memory Models Hal Perkins Autumn 2009
Thread Implementation Issues
CS703 - Advanced Operating Systems
Background and Motivation
Java Concurrency 17-Jan-19.
Implementing Mutual Exclusion
Software Transactional Memory Should Not be Obstruction-Free
CSCI1600: Embedded and Real Time Software
Implementing Mutual Exclusion
CS5123 Software Validation and Quality Assurance
Kernel Synchronization II
CSE 451: Operating Systems Autumn 2003 Lecture 7 Synchronization
CSE 451: Operating Systems Autumn 2005 Lecture 7 Synchronization
CSE 451: Operating Systems Winter 2003 Lecture 7 Synchronization
Java Concurrency.
CSE 153 Design of Operating Systems Winter 19
CSE 153 Design of Operating Systems Winter 2019
CS333 Intro to Operating Systems
Java Concurrency.
Relaxed Consistency Finale
Foundations and Definitions
CSCI1600: Embedded and Real Time Software
Java Concurrency 29-May-19.
EECE.4810/EECE.5730 Operating Systems
Don Porter Portions courtesy Emmett Witchel
Presentation transcript:

CS 3214 Computer Systems Lecture 21 Godmar Back

Announcements Project 4 due Apr 13 Exercise 10 due Apr 19 tomorrow CS 3214 Spring 2010 8/1/2018

MULTI-THREADING CS 3214 Spring 2010 8/1/2018

Locks Thread that enters CS locks it Thread unlocks CS when leaving 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 priority-based systems Can view Lock as an abstract data type Provides (at least) init, acquire, release lock unlock CS 3214 Spring 2010 8/1/2018

Managing Locks Programmer should consider locks resources In Java/C# Must ensure that they are released on all paths In Java/C# Either use built-in “synchronized” or use try/finally In C: requires careful reasoning about all code paths Idiomatic structure of functions helps: minimize number of returns can use goto’s to create a structure that resembles a try/finally clause if a function acquires multiple locks (not usually done for a single lock, though) In C++: use RAII pattern CS 3214 Spring 2010 8/1/2018

Locks In Java vs. C void f() { lock(l1); try { .... if (some error) return; …. lock(l2); try { if (some other err) } finally { unlock(l2); } unlock(l1); void f() { synchronized (l1) { .... if (some error) return; …. synchronized (l2) { if (some other err) } void f(…) { lock(&l1); …. if (some error) goto l1out; lock(&l2); if (some other error) goto l2out; l2out: unlock(l2); l1out: unlock(l1); return; } CS 3214 Spring 2010 8/1/2018

synchronized in Java Built-in ‘locking’ in Java Any Java object can be used as a lock 2 forms: block & method attribute If block form: synchronized (o) { … } uses L = o If instance method: uses L = ‘this’ If static method of class C: uses L = C.class Equivalent to (and best thought of as) L.lock(); try {… } finally { L.unlock(); } Recursive Synchronized methods can call each other without deadlocking CS 3214 Spring 2010 8/1/2018

Locks: Ownership & Recursion Locks semantically have notion of ownership Only lock holder is allowed to unlock Some systems allow querying lock_held_by_current_thread() But: POSIX does not enforce this and in fact Linux’s implementation allows non-holders to unlock a lock What if lock holder tries to acquire locks it already holds? Nonrecursive locks: deadlock! default semantics of POSIX locks Recursive locks: inc counter dec counter on lock_release release when zero default semantics of Java synchronized CS 3214 Spring 2010 8/1/2018

Thread-Safety Property of a function to yield correct result when called from multiple threads Attribute that must be documented as part of the API documentation of a library Functions are not thread-safe if they Fail to protect shared variables Rely on persistent state across invocations Return a pointer to a static variable Call other functions that aren’t thread safe. CS 3214 Spring 2010 8/1/2018

Class 2: Relying on persistent state across multiple function invocations. Random number generator relies on static state Fix: Rewrite function so that caller passes in all necessary state (see rand_r()) /* rand - return pseudo-random integer on 0..32767 */ int rand(void) { static unsigned int next = 1; next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768; } /* srand - set seed for rand() */ void srand(unsigned int seed) next = seed; CS 3214 Spring 2010 8/1/2018

Class 3: Returning a ptr to a static variable Fixes: 1. Rewrite code so caller passes pointer to struct. Issue: Requires changes in caller and callee. 2. Lock-and-copy Issue: Requires only simple changes in caller (and none in callee) However, caller must free memory. struct hostent *gethostbyname(char name) { static struct hostent h; <contact DNS and fill in h> return &h; } hostp = malloc(...)); gethostbyname_r(name, hostp); struct hostent *gethostbyname_ts(char *p) { struct hostent *q = Malloc(...); lock(&mutex); /* lock */ p = gethostbyname(name); *q = *p; /* copy */ unlock(&mutex); return q; } CS 3214 Spring 2010 8/1/2018

Performance Cost of Locking Direct cost: at a minimum, 1 atomic instruction per lock acquire (uncontended) Indirect cost if lock is contended (i.e., held by other thread when thread attempts to acquire it) Context switch cost: Thread needs to move into blocked state, context switch to other thread (if any is ready), - later – thread must be made ready again, another context switch back to resume thread Opportunity cost due to introduced serialization/loss of parallelism: blocked threads cannot use CPU/cores, may lead to underutilization and/or idling of cores Remember: nobody cares about the optimization of incorrect code. Safety is always paramount CS 3214 Spring 2010 8/1/2018

Critical Section Efficiency As processors get faster, CSE decreases because atomic instructions become relatively more expensive (even in uncontended case!) Source: McKenney, 2005 CS 3214 Spring 2010 8/1/2018

Atomicity Violations Locking all accesses to shared variables does not guarantee that a program is free of concurrency bugs Atomicity violations are another, more insidious type of concurrency violations Bug pattern is - lock - get information I - unlock (other threads may invalidate information I) - lock - act on now possibly out-of-date information I - unlock char *p = ….; /* shared variable */ lock lp; /* protects ‘p’ */ …. int getplen() { lock(&lp); int len = strlen(p); unlock(&lp); return len; } … int nchars = getplen(); char *copy = malloc(nchars + 1); strcpy(copy, p); CS 3214 Spring 2010 8/1/2018

Atomicity Violation (Example 2) public synchronized StringBuffer append(StringBuffer sb) { int len = sb.length(); // note: StringBuffer.length() is synchronized int newcount = count + len; if (newcount > value.length) expandCapacity(newcount); sb.getChars(0, len, value, count); // StringBuffer.getChars() is synchronized count = newcount; return this; } Not holding lock on ‘sb’ – other Thread may change its length Incorrect even though individual accesses to “sb” are synchronized (protected by a lock) But “len” may no longer be equal to “sb.length” in call to getChars() This means simply slapping lock()/unlock() around every access to a shared variable does not thread-safe code make Found by Flanagan/Freund CS 3214 Spring 2010 8/1/2018

Atomicity Constraints Atomicity violations disregard atomicity constraints Information read in critical section A must not be used in a critical section B if B relies on it not having been changed lock(); var x = read_var(); unlock(); …. use(x); atomic atomicity required to maintain consistency atomic CS 3214 Spring 2010 8/1/2018

How many locks should I use? Could use one lock for all shared variables Disadvantage: if a thread holding the lock blocks, no other thread can access any shared variable, even unrelated ones Sometimes used when retrofitting non-threaded code into threaded framework Examples: “BKL” Big Kernel Lock in Linux Interpreter Lock in Python GUI Lock in gtk Ideally, want fine-grained locking One lock only protects one (or a small set of) variables – how to pick that set? CS 3214 Spring 2010 8/1/2018

Mapping Locks To Variables Choosing which lock should protect which shared variable(s) is not easy – must weigh: Whether all variables are always accessed together (use one lock if so) Whether there is an atomicity requirement if multiple variables are accessed in related sequence (must hold single lock if so) Cost of multiple calls to lock/unlock (advantage of increased parallelism may be offset by those costs) Whether code inside critical section may block (if not, no throughput gain from fine-grained locking on uniprocessor) CS 3214 Spring 2010 8/1/2018

Rules for Easy Locking Every shared variable must be protected by a lock Establish this relationship with code comments /* protected by … <lock>*/ Acquire lock before touching (reading or writing) variable Release when done, on all paths One lock may protect more than one variable, but not too many If in doubt, use fewer locks (may lead to worse efficiency, but less likely to lead to race conditions or deadlock) If manipulating multiple variables, acquire locks assigned to protecting each Acquire locks always in same order (doesn’t matter which order, but must be same) Release in opposite order Don’t release any locks before all have been acquired (two-phase locking) CS 3214 Spring 2010 8/1/2018