Data Races and Locks Unit 2.a 6/22/2010

Slides:



Advertisements
Similar presentations
Operating Systems Semaphores II
Advertisements

Synchronization and Deadlocks
Concurrency: Deadlock and Starvation Chapter 6. Deadlock Permanent blocking of a set of processes that either compete for system resources or communicate.
CS492B Analysis of Concurrent Programs Lock Basics Jaehyuk Huh Computer Science, KAIST.
Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Multithreaded Programs in Java. Tasks and Threads A task is an abstraction of a series of steps – Might be done in a separate thread – Java libraries.
Concurrency 101 Shared state. Part 1: General Concepts 2.
© 2009 Matthew J. Sottile, Timothy G. Mattson, and Craig E Rasmussen 1 Concurrency in Programming Languages Matthew J. Sottile Timothy G. Mattson Craig.
CS444/CS544 Operating Systems Synchronization 2/16/2006 Prof. Searleman
Threading Part 2 CS221 – 4/22/09. Where We Left Off Simple Threads Program: – Start a worker thread from the Main thread – Worker thread prints messages.
Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.
1 Sharing Objects – Ch. 3 Visibility What is the source of the issue? Volatile Dekker’s algorithm Publication and Escape Thread Confinement Immutability.
1 Concurrency: Deadlock and Starvation Chapter 6.
29-Jun-15 Java Concurrency. Definitions Parallel processes—two or more Threads are running simultaneously, on different cores (processors), in the same.
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.
1 CSCD 330 Network Programming Lecture 13 More Client-Server Programming Sometime in 2014 Reading: References at end of Lecture.
1 Thread II Slides courtesy of Dr. Nilanjan Banerjee.
Object Oriented Analysis & Design SDL Threads. Contents 2  Processes  Thread Concepts  Creating threads  Critical sections  Synchronizing threads.
CSE 501N Fall ‘09 23: Advanced Multithreading: Synchronization and Thread-Safety December 1, 2009 Nick Leidenfrost.
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.
4061 Session 21 (4/3). Today Thread Synchronization –Condition Variables –Monitors –Read-Write Locks.
CSC321 Concurrent Programming: §5 Monitors 1 Section 5 Monitors.
Kernel Locking Techniques by Robert Love presented by Scott Price.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
COSC 3407: Operating Systems Lecture 9: Readers-Writers and Language Support for Synchronization.
Lecture 5 Page 1 CS 111 Summer 2013 Bounded Buffers A higher level abstraction than shared domains or simple messages But not quite as high level as RPC.
NETW 3005 Monitors and Deadlocks. Reading For this lecture, you should have read Chapter 7. NETW3005 (Operating Systems) Lecture 06 - Deadlocks2.
CSCD 330 Network Programming
Multithreading / Concurrency
CSE 120 Principles of Operating
Background on the need for Synchronization
The Singleton Pattern SE-2811 Dr. Mark L. Hornick.
Atomic Operations in Hardware
Atomic Operations in Hardware
Critical sections, locking, monitors, etc.
ITEC 202 Operating Systems
Multiple Writers and Races
Lecture 25 More Synchronized Data and Producer/Consumer Relationship
Threads and Concurrency in Java: Part 2
143a discussion session week 3
Common Correctness and Performance Issues
Lecture 14: Pthreads Mutex and Condition Variables
Threading And Parallel Programming Constructs
Java Concurrency 17-Jan-19.
Implementing Mutual Exclusion
Concurrency: Mutual Exclusion and Process Synchronization
Conditions for Deadlock
Implementing Mutual Exclusion
Lecture 14: Pthreads Mutex and Condition Variables
Kernel Synchronization II
Imperative Data Parallelism (Correctness)
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 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.
Threads and Multithreading
CSE 451: Operating Systems Winter 2007 Module 6 Synchronization
Patterns for Programming Shared Memory
CSE 451 Section 1/27/2000.
Java Concurrency 29-May-19.
EECE.4810/EECE.5730 Operating Systems
CSE 332: Concurrency and Locks
CSE 542: Operating Systems
Presentation transcript:

Data Races and Locks Unit 2.a 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Acknowledgments Authored by Sebastian Burckhardt, MSR Redmond 2/16/2019 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Concepts Atomicity Violations Data Races Data-Race-Free Discipline Immutability Isolation Deadlocks Lock(myobj) Correctness Concept Code Concept 6/16/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

atomicity Violations Part 1 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Atomic, Informally A statement sequence S is atomic if S’s effects appear to other threads as if S executed without interruption Atomicity Violation: An error caused by unexpected lack of atomicity. 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Atomicity Violation Example 1: Naïvely Parallelized AntiSocialRobots Robots are moved in parallel Check if destination cell free, then move This sequence is not atomic! Cell may fill between check and move Schedule of events: r1.check, r2.check, r1.move, r2.movCRASH r1 r2 r1 Toub: It shouldn’t be inferred from this slide (maybe it’s a talking point) that these kinds of issues are avoided through message passing.  The same kinds of races still exist.  After all, you can build a distributed shared memory system on top of message passing, and you can build a message passing system on top of shared memory. r2 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Atomicity Violation Example 2: Bank Account int balance = 0; public void Deposit(int amount) { int b = balance; // read current balance b = b + amount; // add amount balance = b; // write balance back } public void TestParallelDeposit() Parallel.Invoke( () => Deposit(2), () => Deposit(5) ); Assert.AreEqual<int>(7, balance); } Problematic schedule: task 1 reads balance 0 task 2 reads balance 0 task 1 writes balance 2 task 2 writes balance 5 Final balance: 5, not 7! 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Sometimes, it just “looks” atomic… (1) int balance = 0; public void DepositOne() { balance++; } public void TestParallelDepositOne() Parallel.Invoke( () => DepositOne(), () => DepositOne() ); Assert.AreEqual<int>(2, balance); } This is not an atomic operation, because it is internally still executed in three steps: b = balance; b = b + 1; balance = b; 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Sometimes, it just “looks” atomic… (2) struct RoomPoint { public int X; public int Y; ... } RoomPoint p = new RoomPoint(2,3); r.Location = p; This is not an atomic assignment, because the struct is internally copied in several steps: r.Location.X = p.X; r.Location.Y = p.Y; 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Finding Atomicity Problems Atomicity Problems are often a result of unexpected concurrency Programmer may not have been aware of issue Data races are excellent indicators of potential atomicity problems All of the atomicity problems shown on previous slides are also data races. First line of defense against atomicity problems: Prevent data races. 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Part 2 Data Races 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

What is a Data Race? Two concurrent accesses to a memory location at least one of which is a write. Example: Data race between a read and a write int x = 1; Parallel.Invoke( () => { x = 2; }, () => { System.Console.WriteLine(x); } ); Outcome nondeterministic or worse may print 1 or 2, or arbitrarily bad things on a relaxed memory model writes x reads x 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Data Races and Happens-Before Example of a data race with two writes: int x = 1; Parallel.Invoke( () => { x = 2; }, () => { x = 3; } ); System.Console.WriteLine(x); We visualize the ordering of memory accesses with a happens-before graph: There is no path between (write 2 to x) and (write 3 to x), thus they are concurrent, thus they create a data race (note: the read is not in a data race) write 1 to x write 2 to x write 3 to x read x 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Quiz: Where are the data races? Parallel.For(1,2, i => { x = a[i]; }); Parallel.For(1,2, i => { a[i] = x; }); Parallel.For(1,2, i => { a[i] = a[i+1]; }); 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Quiz: Where are the data races? Parallel.For(1,2, i => { x = a[i]; }); Parallel.For(1,2, i => { a[i] = x; }); Parallel.For(1,2, i => { a[i] = a[i+1]; }); reads a[0] reads a[1] reads x reads x reads a[2] reads a[3] race writes x writes x writes a[0] writes a[1] writes a[1] writes a[2] race Race between two writes. No Race between two reads. Race between a read and a write. 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Spotting Reads & Writes Sometimes a single statement performs multiple memory accesses When you execute x += y there are actually two reads and one write: reads x reads y writes x When you execute a[i] = x there are actually three reads and one write: reads x reads a reads i writes a[i] 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Data Races can be hard to spot. Parallel.For(0, 10000, i => {a[i] = new Foo();}) Code looks fine... at first. 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Data Races can be hard to spot. Parallel.For(0, 10000, i => {a[i] = new Foo();}) Problem: we have to follow calls... even if they look harmless at first (like a constructor). class Foo { private static int counter; private int unique_id; public Foo() { unique_id = counter++; } Data Race on static field ! 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

In this Course: We Strictly Follow DRF Discipline Data-Race-Free (DRF) Discipline means we avoid ALL data races (no such thing as a “benign” data race). Already “best practice” for many, but not all programmers.

DRF Discipline Advantages Avoid issues with memory model Make code more declarative Make Race Detection Tools More Useful Race Detectors are excellent at finding forgotten dependencies unexpected conflicts Atomicity problems 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Data Race prevention Part 3 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Avoiding Data Races The three most frequent ways to avoid data races on a variable Make it isolated variable is only ever accessed by one task Make it immutable variable is only ever read Make it synchronized Use a lock to arbitrate concurrent accesses Can use combination over time TODO: replace task-local with isolated, etc. 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Labeling memory accesses This loop is race-free because the accessed locations are either isolated or immutable! Parallel.For(1,1000, i => { a[i] = x; }); x: immutable i: isolated a: immutable a[i]: isolated 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Cool Trick: Avoid Data Races By Encapsulation No data race on x or y isolated during construction (no other tasks can access this object yet) immutable once constructor is finished (fields x,y are private, and methods only read from them) public class Coordinate { private double x, y; public Coordinate(double a, double b) x = a; y = b; } public void GetX() { return x; public void GetY() { return y; 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Part 4 Basic Locking 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Using locks We can often restrict accesses to a variable and make it isolated variable is only ever accessed by one task make it immutable variable is only ever read But if we want to decide on-the-fly who gets to access the variable, we make it synchronized Use a lock to arbitrate between concurrent accesses 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Use lock to arbitrate accesses Example: No data race on variable x, because lock guarantees mutual exclusion! int x = 1; Object mylock = new Object(); Parallel.Invoke( () => { lock(mylock) { x = 2; } }, System.Console.WriteLine(x); }); writes x reads x 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

called “critical section” Basic Locking Any object can serve as a “lock” At most one task can have the lock at a time Task acquires/releases the lock C# syntax: lock(myobj) { ...code to execute with lock goes here... } Lock acquired when task enters critical section May have to wait until lock becomes available Lock released when task exits critical section When exiting either normally or due to an uncaught exception called “critical section” Toub: Where you say “nop”, might want to mention the term “reentrant”.  In doing so, a speaking might be that .NET Monitors (e.g. the lock described here) are reentrant, but not all synchronization primitives and locking types are.  Also, there is reference counting on the lock happening here, so while the thread will be allowed to enter the lock it already holds, it must exit it an equal number of times. 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Lock Semantics Can not enter critical section unless lock is available Task blocks indefinitely if lock is currently held by a different task Several tasks may be blocked & wait for the same lock to become available Tasks may ‘race’ to acquire a lock.. This is not a data race, but a ‘controlled’ race. Winner is chosen nondeterministically. Reentrance is o.k. lock (x) { lock (x) { … } } is equivalent to lock(x) { …} nesting depth is tracked automatically 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Using Locks to Prevent Races This idiom is commonly used to prevent data races on a field x: Choose some lock to “protect” x Ensure lock held whenever x is accessed Object mylock = new Object(); // use this lock to protect x Parallel.Invoke( () => { lock(mylock) { x = 2; } }, () => { w = 2; }, () => { z = 2; }, () => { lock(mylock) { y = x; } }, ) 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Often: protect local fields public class SafeCounter { private int value; private Object mylock = new Object(); public SafeCounter() value = 0; } public void Increment() lock(mylock) value = value + 1; Create a private lock object to protect the fields Guarantees: no data race on field isolated during construction synchronized afterwards 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Simple Locking Policy For each field that may be accessed concurrently: Designate a lock object (in your mind, and with comments) Any object will do (can use this as well) The same lock object can be used for many fields Every time you access a synchronized object: Make sure the lock is held during the access Guarantees: no data races “in your mind”… at the very least it should be commented.  Ideally it would be expressed with contracts, attributes, etc., something we don’t yet have for this in .NET, unfortunately. “often”… but not something that’s publicly exposed, which is often the “object they are a part of”.  The lock represents internal state/implementation detail which is then leaked in this manner. “Guarantees: no data races”… the “data” here should be stressed… this is no way guarantees no races, but it does prevent the kind of races doesn’t this far. 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Common Problems with locks Part 5 Common Problems with locks 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Locks = Easy Fix for all problems ? Suppose you have locked everything, and your code is data-race-free. Is that the end of all trouble? No. Can still have correctness problems: Deadlocks Atomicity problems Can still have performance problems: Lock contention Locking overhead 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Pitfall 1: Deadlock Deadlocking schedule: Task 1 acquires A Object A = new Object(); Object B = new Object(); Parallel.Invoke( () => { lock(A) { lock (B) { ; } } }, () => { lock(B) { lock (A) { ; } } }, ) Deadlocking schedule: Task 1 acquires A Task 2 acquires B Task 1 tries to acquire B, waits for Task 2 to release B Task 2 tries to acquire A, waits for Task 1 to release A Deadlock! Nobody can make progress 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Deadlock = Cycle in Wait-For Graph Visualize deadlocked configuration Each vertex represents a waiting task Each edge x->y represents “x is waiting for y” If there is a cycle: potential deadlock If there is no cycle: safe Parallel.Invoke( () => { lock(A) { lock (B) { ; } } }, () => { lock(B) { lock (A) { ; } } }, ) Wait for B task2 task1 Wait for A 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Solution: Consistent Order If locks are acquired in consistent order, no cycle and thus no deadlock! Object A = new Object(); Object B = new Object(); Object C = new Object(); Parallel.Invoke( () => { lock(A) { lock (B) { ; } } }, () => { lock(B) { lock (C) { ; } } }, () => { lock(A) { lock (C) { ; } } }, ) 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Lock Leveling Simple policy to avoid deadlocks: Assign a “level” (some arbitrarily chosen number) to each lock (in your mind and in comments). Follow policy: whenever acquiring a lock, its level must be higher than all the levels of the locks already held Effect: no cycles possible 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Pitfall 2: Atomicity Violation Consider AntiSocial Robots Code: Problem: robots may move into same cell! Because lock is released & re-acquired in between checking & moving! Parallel.Invoke( () => { if (IsFree(r1.Destination)) MoveRobot(r1); }, () => { if (IsFree(r2.Destination)) MoveRobot(r2); } ) Bool IsFree(Cell c) { lock(c) { return c.Robot == null }; } Void MoveRobot(Robot r) { lock(r.Destination) { r.Destination.Robot = r; } 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Next Lecture Typical Performance Problems Detailed Case Study: Antisocial Robots 6/22/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

ParallelExtensionsExtras. http://code.msdn.microsoft.com/ParExtSamples ParallelExtensionsExtras. FastBitmap 6/16/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com

Parallel Programming with Microsoft .NET Appendix B (Debugging and Profiling Parallel Applications) 6/16/2010 Practical Parallel and Concurrent Programming DRAFT: comments to msrpcpcp@microsoft.com