Programming Paradigms for Concurrency Lecture 2 - Mutual Exclusion

Similar documents
Mutual Exclusion. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Peterson s Algorithm

Mutual Exclusion. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Lecture 7: Mutual Exclusion 2/16/12. slides adapted from The Art of Multiprocessor Programming, Herlihy and Shavit

What We'll Cover Today

Solution: a lock (a/k/a mutex) public: virtual void unlock() =0;

Mutual Exclusion. 1 Formal problem definitions. Time notion CSE /17/2015. Outline of this lecture:

DD2451 Parallel and Distributed Computing --- FDD3008 Distributed Algorithms

Mutual Exclusion: Classical Algorithms for Locks

Programming Paradigms for Concurrency Lecture 3 Concurrent Objects

Synchronization API of Pthread Mutex: lock, unlock, try_lock CondVar: wait, signal, signal_broadcast. Synchronization

Introduction to Concurrency and Multicore Programming. Slides adapted from Art of Multicore Programming by Herlihy and Shavit

Advanced Multiprocessor Programming

10/28/11. DD2451 Overview. DD2451 Overview. FDD 3008 Overview. Course Material

Unit 6: Indeterminate Computation

Atomicity and Virtualization. Atomicity. Critical section. Edsger s perspective. Virtualizing a resource requires managing concurrent accesses

Concurrent Computing

Sequen&al Consistency and Linearizability

Chapter 6: Process [& Thread] Synchronization. CSCI [4 6] 730 Operating Systems. Why does cooperation require synchronization?

Introduction. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit. Art of Multiprocessor Programming

Shared-Memory Computability

! Why is synchronization needed? ! Synchronization Language/Definitions: ! How are locks implemented? Maria Hybinette, UGA

Models of concurrency & synchronization algorithms

Concurrent Objects. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

CS370 Operating Systems

Linked Lists: Locking, Lock-Free, and Beyond. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Concurrent Skip Lists. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Introduction. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Universality of Consensus. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Spin Locks and Contention. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

CSCI [4 6] 730 Operating Systems. Example Execution. Process [& Thread] Synchronization. Why does cooperation require synchronization?

SPIN, PETERSON AND BAKERY LOCKS

Spin Locks and Contention. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Spin Locks and Contention

Lecture. DM510 - Operating Systems, Weekly Notes, Week 11/12, 2018

Concurrency: Mutual Exclusion and Synchronization

Chapter 6: Process Synchronization

Chapter 6: Synchronization. Chapter 6: Synchronization. 6.1 Background. Part Three - Process Coordination. Consumer. Producer. 6.

Thread Synchronization: Foundations. Properties. Safety properties. Edsger s perspective. Nothing bad happens

Chapter 5: Process Synchronization. Operating System Concepts Essentials 2 nd Edition

Concurrent Objects and Linearizability

Process Synchronization

Concurrency: Mutual Exclusion and

6.852: Distributed Algorithms Fall, Class 21

Introduction. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Programming Paradigms for Concurrency Introduction

Process Synchronization

Chapter 7: Process Synchronization. Background. Illustration

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

Linked Lists: Locking, Lock- Free, and Beyond. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Chapter 6: Process Synchronization. Module 6: Process Synchronization

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

Lecture Topics. Announcements. Today: Concurrency: Mutual Exclusion (Stallings, chapter , 5.7)

Process Synchronization. Mehdi Kargahi School of ECE University of Tehran Spring 2008

Chapter 6: Synchronization. Operating System Concepts 8 th Edition,

CS370 Operating Systems

DD2451 Parallel and Distributed Computing --- FDD3008 Distributed Algorithms

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

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

Introduction to Concurrent Programming

Process Synchronization

Shared Objects. Shared Objects

Pre- and post- CS protocols. CS 361 Concurrent programming Drexel University Fall 2004 Lecture 7. Other requirements for a mutual exclusion algorithm

Chapter 7: Process Synchronization. Background

Module 6: Process Synchronization

Chapter 6: Process Synchronization

Coarse-grained and fine-grained locking Niklas Fors

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

CS 361 Concurrent programming Drexel University Fall 2004 Lecture 8. Proof by contradiction. Proof of correctness. Proof of mutual exclusion property

Process Synchronization

Topology and Topological Spaces

CoSc 450: Programming Paradigms. The Critical Section Problem

Chapter 6: Process Synchronization. Operating System Concepts 8 th Edition,

The Relative Power of Synchronization Methods

MULTITHREADING AND SYNCHRONIZATION. CS124 Operating Systems Fall , Lecture 10

Synchronization. CS 475, Spring 2018 Concurrent & Distributed Systems

Synchronization Principles

Review of last lecture. Peer Quiz. DPHPC Overview. Goals of this lecture. Lock-based queue

Process Management And Synchronization

Thread Synchronization: Too Much Milk

Dept. of CSE, York Univ. 1

Example Threads. compile: gcc mythread.cc -o mythread -lpthread What is the output of this program? #include <pthread.h> #include <stdio.

Synchronization problems with semaphores

Concurrent Queues, Monitors, and the ABA problem. Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Operating Systems. Thread Synchronization Primitives. Thomas Ropars.

Semaphores. May 10, Mutual exclusion with shared variables is difficult (e.g. Dekker s solution).

Process Synchronisation (contd.) Deadlock. Operating Systems. Spring CS5212

EXTENDING THE PRIORITY CEILING PROTOCOL USING READ/WRITE AFFECTED SETS MICHAEL A. SQUADRITO A THESIS SUBMITTED IN PARTIAL FULFILLMENT OF THE

Algorithm 23 works. Instead of a spanning tree, one can use routing.

1 The comparison of QC, SC and LIN

Introduction to Operating Systems

[module 2.2] MODELING CONCURRENT PROGRAM EXECUTION

Algorithmic Verification. Algorithmic Verification. Model checking. Algorithmic verification. The software crisis (and hardware as well)

CS4411 Intro. to Operating Systems Exam 1 Fall points 9 pages

Important Lessons. A Distributed Algorithm (2) Today's Lecture - Replication

EECE.4810/EECE.5730: Operating Systems Spring 2017 Homework 2 Solution

CSE332: Data Abstractions Lecture 23: Programming with Locks and Critical Sections. Tyler Robison Summer 2010

Part III Synchronization Software and Hardware Solutions

Lesson 6: Process Synchronization

Proving Dekker with SPIN and PROMELA

Transcription:

Programming Paradigms for Concurrency Lecture 2 - Mutual Exclusion Based on companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit Modified by Thomas Wies New York University

Mutual Exclusion We will clarify our understanding of mutual exclusion We will also show you how to reason about various properties in an asynchronous concurrent setting 2

Mutual Exclusion In his 1965 paper E. W. Dijkstra wrote: "Given in this paper is a solution to a problem which, to the knowledge of the author, has been an open question since at least 1962, irrespective of the solvability. [...] Although the setting of the problem might seem somewhat academic at first, the author trusts that anyone familiar with the logical problems that arise in computer coupling will appreciate the significance of the fact that this problem indeed can be solved." 3

Mutual Exclusion Formal problem definitions Solutions for 2 threads Solutions for n threads Fair solutions Inherent costs 4

Warning You will never use these protocols Get over it You are advised to understand them The same issues show up everywhere Except hidden and more complex 5

Why is Concurrent Programming so Hard? Try preparing a seven-course banquet By yourself With one friend With twenty-seven friends Before we can talk about programs Need a language Describing time and concurrency 6

Time Absolute, true and mathematical time, of itself and from its own nature, flows equably without relation to anything external. (I. Newton, 1689) Time is, like, Nature s way of making sure that everything doesn t happen all at once. (Anonymous, circa 1968) time 7

Events An event a 0 of thread A is Instantaneous No simultaneous events (break ties) a 0 time 8

A thread A is (formally) a sequence a 0, a 1,... of events Trace model Threads Notation: a 0 a 1 indicates order a 0 a 1 a 2 time 9

Example Thread Events Assign to shared variable Assign to local variable Invoke method Return from method Lots of other things 10

Threads are State Machines a 0 Events are transitions a 3 a 2 a 1 11

States Thread State Program counter Local variables System state Object fields (shared variables) Union of thread states 12

Concurrency Thread A time 13

Concurrency Thread A time Thread B time 14

Interleavings Events of two or more threads Interleaved Not necessarily independent (why?) time 15

Intervals An interval A 0 =(a 0,a 1 ) is Time between events a 0 and a 1 a 0 a 1 A 0 time 16

Intervals may Overlap b 0 B 0 b 1 a 0 A 0 a 1 time 17

Intervals may be Disjoint b 0 B 0 b 1 a 0 A 0 a 1 time 18

Precedence Interval A 0 precedes interval B 0 b 0 B 0 b 1 a 0 A 0 a 1 time 19

Precedence Notation: A 0 B 0 Formally, End event of A 0 before start event of B 0 Also called happens before or precedes 20

Precedence Ordering Remark: A 0 B 0 is just like saying 1066 AD 1492 AD, Middle Ages Renaissance, Oh wait, what about this week vs this month? 21

Precedence Ordering Never true that A A If A B then not true that B A If A B & B C then A C Funny thing: A B & B A might both be false! 22

Irreflexive: Strict Partial Orders (review) Never true that A A Antisymmetric: If A B then not true that B A Transitive: If A B & B C then A C 23

Strict Total Orders (review) Also Irreflexive Antisymmetric Transitive Except that for every distinct A, B, Either A B or B A 24

Repeated Events while (mumble) { a 0 ; a 1 ; } k-th occurrence of event a 0 a 0 k A 0 k k-th occurrence of interval A 0 =(a 0,a 1 ) 25

Implementing a Counter public class Counter { private long value; } public long getandincrement() { temp = value; value = temp + 1; return temp; } Make these steps indivisible using locks 26

Locks (Mutual Exclusion) public interface Lock { public void lock(); public void unlock(); } 27

Locks (Mutual Exclusion) public interface Lock { public void lock(); acquire lock public void unlock(); } 28

Locks (Mutual Exclusion) public interface Lock { public void lock(); public void unlock(); } acquire lock release lock 29

Using Locks public class Counter { private long value; private Lock lock; public long getandincrement() { lock.lock(); try { int temp = value; value = value + 1; } finally { lock.unlock(); } return temp; }} 30

Using Locks public class Counter { private long value; private Lock lock; public long getandincrement() { lock.lock(); try { int temp = value; value = value + 1; } finally { lock.unlock(); } return temp; }} acquire Lock 31

Using Locks public class Counter { private long value; private Lock lock; public long getandincrement() { lock.lock(); try { int temp = value; value = value + 1; } finally { lock.unlock(); } return temp; }} Release lock (no matter what) 32

Using Locks public class Counter { private long value; private Lock lock; public long getandincrement() { lock.lock(); try { int temp = value; value = value + 1; } finally { lock.unlock(); } return temp; }} critical section 33

Mutual Exclusion Let CS k i be thread i s k-th critical section execution 34

Mutual Exclusion Let CS k i be thread i s k-th critical section execution And CS m j be thread j s m-th critical section execution 35

Mutual Exclusion Let CS k i be thread i s k-th critical section execution And CS m j be j s m-th execution Then either or 36

Mutual Exclusion Let CS k i be thread i s k-th critical section execution And CS m j be j s m-th execution Then either or CS i k CS j m 37

Mutual Exclusion Let CS k i be thread i s k-th critical section execution And CS m j be j s m-th execution Then either or CS i k CS j m CS j m CS i k 38

Deadlock-Free If some thread calls lock() And never returns Then other threads must complete lock() and unlock() calls infinitely often System as a whole makes progress Even if individuals starve 39

Starvation-Free If some thread calls lock() It will eventually return Individual threads make progress 40

Two-Thread vs n-thread Solutions 2-thread solutions first Illustrate most basic ideas Fits on one slide Then n-thread solutions 41

Two-Thread Conventions class implements Lock { // thread-local index, 0 or 1 public void lock() { int i = ThreadID.get(); int j = 1 - i; } } 42

Two-Thread Conventions class implements Lock { // thread-local index, 0 or 1 public void lock() { int i = ThreadID.get(); int j = 1 - i; } } Henceforth: i is current thread, j is other thread 43

LockOne class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock() { flag[i] = true; while (flag[j]) {} }

LockOne class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock() { flag[i] = true; while (flag[j]) {} } Each thread has flag

LockOne class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock() { flag[i] = true; while (flag[j]) {} Set my flag }

LockOne class LockOne implements Lock { private boolean[] flag = new boolean[2]; public void lock() { flag[i] = true; while (flag[j]) {} } Wait for other flag to become false

LockOne Satisfies Mutual Exclusion Assume CS j overlaps A CS k B Consider each thread's last (j-th and k-th) read and write in the lock() method before entering Derive a contradiction 48

From the Code write A (flag[a]=true) read A (flag[b]==false) CS A write B (flag[b]=true) read B (flag[a]==false) CS B class LockOne implements Lock { public void lock() { flag[i] = true; while (flag[j]) {} } 49

From the Assumption read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) write A (flag[a]=true) 50

Combining Assumptions: read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) write A (flag[a]=true) From the code write A (flag[a]=true) read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) 51

Combining Assumptions: read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) write A (flag[a]=true) From the code write A (flag[a]=true) read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) 52

Combining Assumptions: read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) write A (flag[a]=true) From the code write A (flag[a]=true) read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) 53

Combining Assumptions: read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) write A (flag[a]=true) From the code write A (flag[a]=true) read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) 54

Combining Assumptions: read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) write A (flag[a]=true) From the code write A (flag[a]=true) read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) 55

Combining Assumptions: read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) write A (flag[a]=true) From the code write A (flag[a]=true) read A (flag[b]==false) write B (flag[b]=true) read B (flag[a]==false) 56

Cycle! 57

Deadlock Freedom LockOne Fails deadlock-freedom Concurrent execution can deadlock flag[i] = true; flag[j] = true; while (flag[j]){} while (flag[i]){} Sequential executions OK 58

LockTwo public class LockTwo implements Lock { private int victim; public void lock() { victim = i; while (victim == i) {}; } public void unlock() {} } 59

LockTwo public class LockTwo implements Lock { private int victim; public void lock() { victim = i; while (victim == i) {}; } public void unlock() {} } Let other go first 60

LockTwo public class LockTwo implements Lock { private int victim; public void lock() { victim = i; while (victim == i) {}; } public void unlock() {} } Wait for permission 61

LockTwo public class Lock2 implements Lock { private int victim; public void lock() { victim = i; while (victim == i) {}; } public void unlock() {} } Nothing to do 62

LockTwo Claims Satisfies mutual exclusion If thread i in CS Then victim == j Cannot be both 0 and 1 Not deadlock free Sequential execution deadlocks Concurrent execution does not public void LockTwo() { victim = i; while (victim == i) {}; } 63

Peterson s Algorithm public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } 64

Peterson s Algorithm Announce I m interested public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } 65

Peterson s Algorithm Announce I m interested public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } Defer to other 66

Peterson s Algorithm public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } Announce I m interested Defer to other Wait while other interested & I m the victim 67

Peterson s Algorithm public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } No longer interested Announce I m interested Defer to other Wait while other interested & I m the victim 68

Mutual Exclusion (1) write B (Flag[B]=true) write B (victim=b) public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } From the Code 69

Also from the Code (2) write A (victim=a) read A (flag[b]) read A (victim) public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } 70

Assumption (3) write B (victim=b) write A (victim=a) W.L.O.G. assume A is the last thread to write victim 71

Combining Observations (1) write B (flag[b]=true) write B (victim=b) (3) write B (victim=b) write A (victim=a) (2) write A (victim=a) read A (flag[b]) read A (victim) 72

Combining Observations (1) write B (flag[b]=true) write B (victim=b) (3) write B (victim=b) write A (victim=a) (2) write A (victim=a) read A (flag[b]) read A (victim) 73

Combining Observations (1) write B (flag[b]=true) write B (victim=b) (3) write B (victim=b) write A (victim=a) (2) write A (victim=a) read A (flag[b]) read A (victim) A read flag[b] == true and victim == A, so it could not have entered the CS (QED) 74

Deadlock Free public void lock() { while (flag[j] && victim == i) {}; Thread blocked only at while loop only if other s flag is true only if it is the victim Solo: other s flag is false Both: one or the other not the victim 75

Starvation Free Thread i blocked only if j repeatedly re-enters so that flag[j] == true and victim == i When j re-enters it sets victim to j. So i gets in public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } 76

The Filter Algorithm for n Threads There are n waiting rooms called levels At each level At least one enters level At least one blocked if many try Only one thread makes it through ncs cs 77

Filter class Filter implements Lock { int[] level; // level[i] for thread i int[] victim; // victim[l] for level L } public Filter(int n) { level = new int[n]; victim = new int[n]; for (int i = 1; i < n; i++) { }} level[i] = 0; level Thread 2 at level 4 0 2 0 0 4 0 0 0 0 0 2 1 4 victim n-1 78 n-1

Filter class Filter implements Lock { public void lock(){ for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (($ k!= i level[k] >= L) && victim[l] == i ) {}; }} public void unlock() { level[i] = 0; }} 79

Filter class Filter implements Lock { public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (($ k!= i) level[k] >= L) && victim[l] == i) {}; }} public void release(int i) { level[i] = 0; }} One level at a time 80

Filter class Filter implements Lock { public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (($ k!= i) level[k] >= L) && victim[l] == i) {}; // busy wait }} Announce public void release(int i) { level[i] = 0; level L }} intention to enter 81

Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (($ k!= i) level[k] >= L) && victim[l] == i) {}; }} public void release(int i) { level[i] = 0; }} Give priority to anyone but me 82

Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; Wait as long as someone else is at same or higher level, and I m designated victim while (($ k!= i) level[k] >= L) && victim[l] == i) {}; }} public void release(int i) { level[i] = 0; }} 83

Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (($ k!= i) level[k] >= L) && victim[l] == i) {}; }} public void release(int i) { level[i] = 0; }} the loop Thread enters level L when it completes 84

Claim Start at level L=0 At most n-l threads enter level L Mutual exclusion at level L=n-1 ncs L=0 L=1 L=n-2 cs L=n-1 85

Induction Hypothesis No more than n-(l-1) at level L-1 Induction step: by contradiction Assume all at level L-1 enter level L A last to write victim[l] B is any other thread at level L ncs cs assume L-1 has n-(l-1) L has n-l prove 86

Proof Structure Last to write victim[l] A ncs cs B Assumed to enter L-1 n-l+1 = 4 n-l+1 = 4 By way of contradiction all enter L Show that A must have seen L in level[b] and since victim[l] == A could not have entered 87

Just Like Peterson (1) write B (level[b]=l) write B (victim[l]=b) public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (($ k!= i) level[k] >= L) && victim[l] == i) {}; }} From the Code 88

From the Code (2) write A (victim[l]=a) read A (level[b]) read A (victim[l]) public void lock() { for (int L = 1; L < n; L++) { level[i] = L; victim[l] = i; while (($ k!= i) level[k] >= L) && victim[l] == i) {}; }} 89

By Assumption (3) write B (victim[l]=b) write A (victim[l]=a) By assumption, A is the last thread to write victim[l] 90

Combining Observations (1) write B (level[b]=l) write B (victim[l]=b) (3) write B (victim[l]=b) write A (victim[l]=a) (2) write A (victim[l]=a) read A (level[b]) read A (victim[l]) 91

Combining Observations (1) write B (level[b]=l) write B (victim[l]=b) (3) write B (victim[l]=b) write A (victim[l]=a) (2) write A (victim[l]=a) read A (level[b]) read A (victim[l]) 92

Combining Observations (1) write B (level[b]=l) write B (victim[l]=b) (3) write B (victim[l]=b) write A (victim[l]=a) (2) write A (victim[l]=a) read A (level[b]) read A (victim[l]) A read level[b] L, and victim[l] = A, so it could not have entered level L! 93

No Starvation Filter Lock satisfies properties: Just like Peterson Alg at any level So no one starves But what about fairness? Threads can be overtaken by others 94

Bounded Waiting Want stronger fairness guarantees Thread not overtaken too much If A starts before B, then A enters before B? But what does start mean? Need to adjust definitions. 95

Bounded Waiting Divide lock() method into 2 parts: Doorway interval: Written D A always finishes in finite steps Waiting interval: Written W A may take unbounded steps 96

First-Come-First-Served For threads A and B: If D A k D B j A s k-th doorway precedes B s j-th doorway Then CS A k CS B j A s k-th critical section precedes B s j-th critical section B cannot overtake A 97

Fairness Again Filter Lock satisfies properties: No one starves But very weak fairness Can be overtaken arbitrary # of times That s pretty lame 98

Bakery Algorithm Provides First-Come-First-Served How? Take a number Wait until lower numbers have been served Lexicographic order (a,i) > (b,j) If a > b, or a = b and i > j 99

Bakery Algorithm class Bakery implements Lock { boolean[] flag; } Label[] label; public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { } flag[i] = false; label[i] = 0; 100

Bakery Algorithm class Bakery implements Lock { boolean[] flag; } Label[] label; public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; 0 0 4 0 0 5 0 0 for (int i = 0; i < n; i++) { } flag[i] = false; label[i] = 0; 0 2 f f t f f t f f CS 6 n-1 101

Bakery Algorithm class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ($k flag[k] && (label[i],i) > (label[k],k)); } 102

Bakery Algorithm class Bakery implements Lock { Doorway public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ($k flag[k] && (label[i],i) > (label[k],k)); } 103

Bakery Algorithm class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; I m interested while ($k flag[k] && (label[i],i) > (label[k],k)); } 104

Bakery Algorithm Take increasing label (read labels in some arbitrary order) class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ($k flag[k] && (label[i],i) > (label[k],k)); } 105

Bakery Algorithm Someone is interested class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ($k flag[k] && (label[i],i) > (label[k],k)); } 106

Bakery Algorithm class Bakery implements Lock { boolean flag[n]; int label[n]; Someone is interested public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ($k flag[k] && (label[i],i) > (label[k],k)); } whose (label[k],k) in lexicographic order is lower 107

Bakery Algorithm class Bakery implements Lock { public void unlock() { flag[i] = false; } } 108

Bakery Algorithm class Bakery implements Lock { No longer interested public void unlock() { flag[i] = false; } } labels are always increasing 109

No Deadlock There is always one thread with earliest label Ties are impossible (why?) 110

First-Come-First-Served If D A D B then A s label is smaller And: write A (label[a]) read B (label[a]) write B (label[b]) read B (flag[a]) So B sees smaller label for A locked out while flag[a] is true class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ($k flag[k] && (label[i],i) > (label[k],k)); } 111

Mutual Exclusion Suppose A and B in CS together Suppose A has earlier label When B entered, it must have seen flag[a] is false, or label[a] > label[b] class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ($k flag[k] && (label[i],i) > (label[k],k)); } 112

Mutual Exclusion Labels are strictly increasing so B must have seen flag[a] == false 113

Mutual Exclusion Labels are strictly increasing so B must have seen flag[a] == false Labeling B read B (flag[a]) write A (flag[a]) Labeling A 114

Mutual Exclusion Labels are strictly increasing so B must have seen flag[a] == false Labeling B read B (flag[a]) write A (flag[a]) Labeling A Which contradicts the assumption that A has an earlier label 115

Bakery Y2 32 K Bug class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ($k flag[k] && (label[i],i) > (label[k],k)); } 116

Bakery Y2 32 K Bug Mutex breaks if label[i] overflows class Bakery implements Lock { public void lock() { flag[i] = true; label[i] = max(label[0],,label[n-1])+1; while ($k flag[k] && (label[i],i) > (label[k],k)); } 117

Does Overflow Actually Matter? Yes Y2K 18 January 2038 (Unix time_t rollover) 16-bit counters No 64-bit counters Maybe 32-bit counters 118

Timestamps Label variable is really a timestamp Need ability to Read others timestamps Compare them Generate a later timestamp Can we do this without overflow? 119

The Good News One can construct a Wait-free (no mutual exclusion) Concurrent Timestamping system That never overflows 120

The Good News One can construct a Wait-free (no mutual exclusion) Concurrent Timestamping system That never overflows This part is hard 121

Instead We construct a Sequential timestamping system Same basic idea But simpler As if we use mutex to read & write atomically No good for building locks But useful anyway 122

Precedence Graphs 0 1 2 3 Timestamps form directed graph Edge x to y Means x is later timestamp We say x dominates y 123

Unbounded Counter Precedence Graph 0 1 2 3 Timestamping = move tokens on graph Atomically read others tokens move mine Ignore tie-breaking for now 124

Unbounded Counter Precedence Graph 0 1 2 3 125

Unbounded Counter Precedence Graph 0 1 2 3 takes 0 takes 1 takes 2 126

Two-Thread Bounded Precedence Graph 0 2 1 127

Two-Thread Bounded Precedence Graph 0 2 1 128

Two-Thread Bounded Precedence Graph 0 2 1 129

Two-Thread Bounded Precedence Graph 0 2 1 130

Two-Thread Bounded Precedence Graph T 2 0 and so on 2 1 131

Three-Thread Bounded Precedence Graph? 3 0 2 1 132

Three-Thread Bounded Precedence Graph? 3 0 2 1 What to do if one thread gets stuck? 133

Graph Composition 0 0 2 1 T 3 =T 2 *T 2 2 Replace each vertex with a copy of the graph 1 134

Three-Thread Bounded Precedence Graph T 3 0 2 0 1 0 0 2 1 2 1 2 1 135

Three-Thread Bounded Precedence Graph T 3 0 0 20 < 02 < 12 2 1 0 0 2 1 2 1 2 1 136

Three-Thread Bounded Precedence Graph T 3 0 2 0 1 0 0 2 1 2 1 2 1 and so on 137

In General T k = T 2 * T k-1 K threads need 3 k nodes label size = Log 2 (3 k ) = 2k 138

Deep Philosophical Question The Bakery Algorithm is Succinct, Elegant, and Fair. Q: So why isn t it practical? A: Well, you have to read N distinct variables 139

Shared Memory Shared read/write memory locations called Registers (historical reasons) Come in different flavors Multi-Reader-Single-Writer (Flag[]) Multi-Reader-Multi-Writer (Victim[]) Not that interesting: SRMW and SRSW 140

Theorem At least N MRSW (multi-reader/singlewriter) registers are needed to solve deadlock-free mutual exclusion. N registers like Flag[] 141

Proving Algorithmic Impossibility To show no algorithm exists: assume by way of contradiction one does, show a bad execution that violates properties: in our case assume an alg for deadlock free mutual exclusion using < N registers C write CS 142

Proof: Need N-MRSW Registers Each thread must write to some register A B C write write CS CS CS can t tell whether A is in critical section 143

Upper Bound Bakery algorithm Uses 2N MRSW registers So the bound is (pretty) tight But what if we use MRMW registers? Like victim[]? 144

Bad News Theorem At least N MRMW multireader/multi-writer registers are needed to solve deadlock-free mutual exclusion. (So multiple writers don t help) 145

Theorem (For 2 Threads) Theorem: Deadlock-free mutual exclusion for 2 threads requires at least 2 multi-reader multi-writer registers Proof: assume one register suffices and derive a contradiction 146

Two Thread Execution A B Write(R) R CS CS Threads run, reading and writing R Deadlock free so at least one gets in 147

Covering State for One Register Always Exists B Write(R) In any protocol B has to write to the register before entering CS, so stop it just before 148

Proof: Assume Cover of 1 A B Write(R) CS A runs, possibly writes to the register, enters CS 149

Proof: Assume Cover of 1 A B CS Write(R) CS B Runs, first obliterating any trace of A, then also enters the critical section 150

Theorem Deadlock-free mutual exclusion for 3 threads requires at least 3 multi-reader multi-writer registers 151

Proof: Assume Cover of 2 A B C Write(R B ) Write(R C ) Only 2 registers 152

Run A Solo A B C Write(R B ) Write(R C ) CS Writes to one or both registers, enters CS 153

Obliterate Traces of A A B C Write(R B ) Write(R C ) CS Other threads obliterate evidence that A entered CS 154

Mutual Exclusion Fails A B C Write(R B ) Write(R C ) CS CS CS looks empty, so another thread gets in 155

Proof Strategy Proved: a contradiction starting from a covering state for 2 registers Claim: a covering state for 2 registers is reachable from any state where CS is empty 156

Covering State for Two A B Write(R A ) Write(R B ) If we run B through CS 3 times, B must return twice to cover some register, say R B 157

Covering State for Two A B Write(R A ) Write(R B ) Start with B covering register R B for the 1 st time Run A until it is about to write to uncovered R A Are we done? 158

Covering State for Two A B Write(R A ) Write(R B ) NO! A could have written to R B So CS no longer looks empty to thread C 159

Covering State for Two A B Write(R A ) Write(R B ) Run B obliterating traces of A in R B Run B again until it is about to write to R B Now we are done 160

Inductively We Can Show A B C Write(R A ) Write(R B ) Write(R C ) There is a covering state Where k threads not in CS cover k distinct registers Proof follows when k = N-1 161

Summary of Lecture In the 1960 s several incorrect solutions to starvation-free mutual exclusion using RW-registers were published Today we know how to solve FIFO N thread mutual exclusion using 2N RW- Registers 162

Summary of Lecture N RW-Registers inefficient Because writes cover older writes Need stronger hardware operations that do not have the covering problem In next lectures - understand what these operations are 163

This work is licensed under a Creative Commons Attribution- ShareAlike 2.5 License. You are free: to Share to copy, distribute and transmit the work to Remix to adapt the work Under the following conditions: Attribution. You must attribute the work to The Art of Multiprocessor Programming (but not in any way that suggests that the authors endorse you or your use of the work). Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license. For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to http://creativecommons.org/licenses/by-sa/3.0/. Any of the above conditions can be waived if you get permission from the copyright holder. Nothing in this license impairs or restricts the author's moral rights. 164