Mutual Exclusion Mutual Exclusion We will clarify our

  • Slides: 114
Download presentation
Mutual Exclusion

Mutual Exclusion

Mutual Exclusion • We will clarify our understanding of mutual exclusion • We will

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 Art of Multiprocessor Programming 2

Mutual Exclusion • • • Formal problem definitions Solutions for 2 threads Solutions for

Mutual Exclusion • • • Formal problem definitions Solutions for 2 threads Solutions for n threads Fair solutions Inherent costs Art of Multiprocessor Programming 3

Warning • You will never use these protocols – Get over it • You

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 Art of Multiprocessor Programming 4

Why is Concurrent Programming so Hard? • Try preparing a seven-course banquet – By

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 Art of Multiprocessor Programming 5

Time • “Absolute, true and mathematical time, of itself and from its own nature,

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 Art of Multiprocessor Programming 6

Events • An event a 0 of thread A is – Instantaneous – No

Events • An event a 0 of thread A is – Instantaneous – No simultaneous events (break ties) a 0 time Art of Multiprocessor Programming 7

Threads • A thread A is (formally) a sequence a 0, a 1, .

Threads • A thread A is (formally) a sequence a 0, a 1, . . . of events – “Trace” model – Notation: a 0 a 1 indicates order a 0 a 1 a 2 … time Art of Multiprocessor Programming 8

Example Thread Events • • • Assign to shared variable Assign to local variable

Example Thread Events • • • Assign to shared variable Assign to local variable Invoke method Return from method Lots of other things … Art of Multiprocessor Programming 9

Threads are State Machines Events are transitions a 3 a 2 Art of Multiprocessor

Threads are State Machines Events are transitions a 3 a 2 Art of Multiprocessor Programming a 0 a 1 10

States • Thread State – Program counter – Local variables • System state –

States • Thread State – Program counter – Local variables • System state – Object fields (shared variables) – Union of thread states Art of Multiprocessor Programming 11

Concurrency • Thread A time Art of Multiprocessor Programming 12

Concurrency • Thread A time Art of Multiprocessor Programming 12

Concurrency • Thread A time • Thread B time Art of Multiprocessor Programming 13

Concurrency • Thread A time • Thread B time Art of Multiprocessor Programming 13

Interleavings • Events of two or more threads – Interleaved – Not necessarily independent

Interleavings • Events of two or more threads – Interleaved – Not necessarily independent (why? ) time Art of Multiprocessor Programming 14

Intervals • An interval A 0 =(a 0, a 1) is – Time between

Intervals • An interval A 0 =(a 0, a 1) is – Time between events a 0 and a 1 a 0 A 0 a 1 time Art of Multiprocessor Programming 15

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

Intervals may Overlap b 0 a 0 A 0 B 0 b 1 a 1 time Art of Multiprocessor Programming 16

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

Intervals may be Disjoint b 0 a 0 A 0 B 0 b 1 a 1 time Art of Multiprocessor Programming 17

Precedence Interval A 0 precedes interval B 0 b 0 a 0 A 0

Precedence Interval A 0 precedes interval B 0 b 0 a 0 A 0 B 0 b 1 a 1 time Art of Multiprocessor Programming 18

Precedence • Notation: A 0 B 0 • Formally, – End event of A

Precedence • Notation: A 0 B 0 • Formally, – End event of A 0 before start event of B 0 – Also called “happens before” or “precedes” Art of Multiprocessor Programming 19

Precedence Ordering • Remark: A 0 B 0 is just like saying – 1066

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? Art of Multiprocessor Programming 20

Precedence Ordering • • Never true that A A If A B then not

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! Art of Multiprocessor Programming 21

Partial Orders (review) • Irreflexive: – Never true that A A • Antisymmetric: –

Partial Orders (review) • Irreflexive: – Never true that A A • Antisymmetric: – If A B then not true that B A • Transitive: – If A B & B C then A C Art of Multiprocessor Programming 22

Total Orders (review) • Also – Irreflexive – Antisymmetric – Transitive • Except that

Total Orders (review) • Also – Irreflexive – Antisymmetric – Transitive • Except that for every distinct A, B, – Either A B or B A Art of Multiprocessor Programming 23

Repeated Events while (mumble) { a 0; a 1; } a 0 k A

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

Implementing a Counter public class Counter { private long value; public long get. And.

Implementing a Counter public class Counter { private long value; public long get. And. Increment() { temp = value; value = temp + 1; return temp; Make these } } steps indivisible using locks Art of Multiprocessor 25 Programming

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

Locks (Mutual Exclusion) public interface Lock { public void lock(); public void unlock(); } Art of Multiprocessor Programming 26

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

Locks (Mutual Exclusion) public interface Lock { public void lock(); acquire lock public void unlock(); } Art of Multiprocessor Programming 27

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

Locks (Mutual Exclusion) public interface Lock { public void lock(); acquire lock public void unlock(); release lock } Art of Multiprocessor Programming 28

Using Locks public class Counter { private long value; private Lock lock; public long

Using Locks public class Counter { private long value; private Lock lock; public long get. And. Increment() { lock(); try { int temp = value; value = value + 1; } finally { lock. unlock(); } return temp; }} Art of Multiprocessor Programming 29

Using Locks public class Counter { private long value; private Lock lock; public long

Using Locks public class Counter { private long value; private Lock lock; public long get. And. Increment() { lock(); acquire try { int temp = value; value = value + 1; } finally { lock. unlock(); } return temp; }} Art of Multiprocessor Programming Lock 30

Using Locks public class Counter { private long value; private Lock lock; public long

Using Locks public class Counter { private long value; private Lock lock; public long get. And. Increment() { lock(); try { int temp = value; value = value + 1; } finally { Release lock. unlock(); } (no matter what) return temp; }} Art of Multiprocessor Programming 31

Using Locks public class Counter { private long value; private Lock lock; public long

Using Locks public class Counter { private long value; private Lock lock; public long get. And. Increment() { lock(); try { int temp = value; value = value + 1; } finally { lock. unlock(); } return temp; }} Art of Multiprocessor Programming Critical section 32

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution Art of

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution Art of Multiprocessor Programming 33

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution • And

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution • And CSjm be thread j’s m-th critical section execution Art of Multiprocessor Programming 34

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution • And

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution • And CSjm be j’s m-th execution • Then either – or Art of Multiprocessor Programming 35

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution • And

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution • And CSjm be j’s m-th execution • Then either – or CSik CSjm Art of Multiprocessor Programming 36

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution • And

Mutual Exclusion • Let CSik be thread i’s k-th critical section execution • And CSjm be j’s m-th execution • Then either – or CSik CSjm Art of Multiprocessor Programming CSjm CSik 37

Deadlock-Free • If some thread calls lock() – And never returns – Then other

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 Art of Multiprocessor Programming 38

Starvation-Free • If some thread calls lock() – It will eventually return • Individual

Starvation-Free • If some thread calls lock() – It will eventually return • Individual threads make progress Art of Multiprocessor Programming 39

Two-Thread vs n -Thread Solutions • 2 -thread solutions first – Illustrate most basic

Two-Thread vs n -Thread Solutions • 2 -thread solutions first – Illustrate most basic ideas – Fits on one slide • Then n-thread solutions Art of Multiprocessor Programming 40

Two-Thread Conventions class … implements Lock { … // thread-local index, 0 or 1

Two-Thread Conventions class … implements Lock { … // thread-local index, 0 or 1 public void lock() { int i = Thread. ID. get(); int j = 1 - i; … } } Art of Multiprocessor Programming 41

Two-Thread Conventions class … implements Lock { … // thread-local index, 0 or 1

Two-Thread Conventions class … implements Lock { … // thread-local index, 0 or 1 public void lock() { int i = Thread. ID. get(); int j = 1 - i; … } } Henceforth: i is current thread, j is other thread Art of Multiprocessor Programming 42

Lock. One class Lock. One implements Lock { private boolean[] flag = new boolean[2];

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

Lock. One class Lock. One implements Lock { private boolean[] flag = new boolean[2];

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

Lock. One class Lock. One implements Lock { private boolean[] flag = new boolean[2];

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

Lock. One class Lock. One implements Lock { private boolean[] flag = new boolean[2];

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

Lock. One Satisfies Mutual Exclusion • Assume CSAj overlaps CSBk • Consider each thread's

Lock. One Satisfies Mutual Exclusion • Assume CSAj overlaps CSBk • Consider each thread's last (j-th and k-th) read and write in the lock() method before entering • Derive a contradiction Art of Multiprocessor Programming 47

From the Code • write. A(flag[A]=true) read. A(flag[B]==false) CSA • write. B(flag[B]=true) read. B(flag[A]==false)

From the Code • write. A(flag[A]=true) read. A(flag[B]==false) CSA • write. B(flag[B]=true) read. B(flag[A]==false) CSB class Lock. One implements Lock { … public void lock() { flag[i] = true; while (flag[j]) {} } Art of Multiprocessor Programming 48

From the Assumption • read. A(flag[B]==false) write. B(flag[B]=true) • read. B(flag[A]==false) write. A(flag[A]=true) Art

From the Assumption • read. A(flag[B]==false) write. B(flag[B]=true) • read. B(flag[A]==false) write. A(flag[A]=true) Art of Multiprocessor Programming 49

Combining • Assumptions: – read. A(flag[B]==false) write. B(flag[B]=true) – read. B(flag[A]==false) write. A(flag[A]=true) •

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) Art of Multiprocessor Programming 50

Combining • Assumptions: – read. A(flag[B]==false) write. B(flag[B]=true) – read. B(flag[A]==false) write. A(flag[A]=true) •

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) Art of Multiprocessor Programming 51

Combining • Assumptions: – read. A(flag[B]==false) write. B(flag[B]=true) – read. B(flag[A]==false) write. A(flag[A]=true) •

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) Art of Multiprocessor Programming 52

Combining • Assumptions: – read. A(flag[B]==false) write. B(flag[B]=true) – read. B(flag[A]==false) write. A(flag[A]=true) •

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) Art of Multiprocessor Programming 53

Combining • Assumptions: – read. A(flag[B]==false) write. B(flag[B]=true) – read. B(flag[A]==false) write. A(flag[A]=true) •

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) Art of Multiprocessor Programming 54

Combining • Assumptions: – read. A(flag[B]==false) write. B(flag[B]=true) – read. B(flag[A]==false) write. A(flag[A]=true) •

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) Art of Multiprocessor Programming 55

Cycle! a in e l r b i de s s or o p

Cycle! a in e l r b i de s s or o p l m a I rti a p Art of Multiprocessor Programming 56

Deadlock Freedom • Lock. One Fails deadlock-freedom – Concurrent execution can deadlock flag[i] =

Deadlock Freedom • Lock. One Fails deadlock-freedom – Concurrent execution can deadlock flag[i] = true; while (flag[j]){} flag[j] = true; while (flag[i]){} – Sequential executions OK Art of Multiprocessor Programming 57

Lock. Two public class Lock. Two implements Lock { private int victim; public void

Lock. Two public class Lock. Two implements Lock { private int victim; public void lock() { victim = i; while (victim == i) {}; } public void unlock() {} } Art of Multiprocessor Programming 58

Lock. Two public class Lock. Two implements Lock { private int victim; Let other

Lock. Two public class Lock. Two implements Lock { private int victim; Let other public void lock() { first victim = i; while (victim == i) {}; } go public void unlock() {} } Art of Multiprocessor Programming 59

Lock. Two public class Lock. Two implements Lock { Wait for private int victim;

Lock. Two public class Lock. Two implements Lock { Wait for private int victim; public void lock() { permission victim = i; while (victim == i) {}; } public void unlock() {} } Art of Multiprocessor Programming 60

Lock. Two public class Lock 2 implements Lock { private int victim; public void

Lock. Two public class Lock 2 implements Lock { private int victim; public void lock() { Nothing victim = i; while (victim == i) {}; } to do public void unlock() {} } Art of Multiprocessor Programming 61

Lock. Two Claims • Satisfies mutual exclusion – If thread i in CS public

Lock. Two Claims • Satisfies mutual exclusion – If thread i in CS public void Lock. Two() { victim = i; – Then victim == j while (victim == i) {}; – Cannot be both 0 and 1 • Not deadlock free } – Sequential execution deadlocks – Concurrent execution does not Art of Multiprocessor Programming 62

Peterson’s Algorithm public void lock() { flag[i] = true; victim = i; while (flag[j]

Peterson’s Algorithm public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {}; } public void unlock() { flag[i] = false; } Art of Multiprocessor Programming 63

Peterson’s Algorithm Announce I’m interested public void lock() { flag[i] = true; victim =

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; } Art of Multiprocessor Programming 64

Peterson’s Algorithm Announce I’m interested public void lock() { flag[i] = true; Defer to

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

Peterson’s Algorithm Announce I’m interested public void lock() { flag[i] = true; Defer to

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

Peterson’s Algorithm Announce I’m interested public void lock() { flag[i] = true; Defer to

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

Mutual Exclusion (1) write. B(Flag[B]=true) write. B(victim=B) public void lock() { flag[i] = true;

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 Art of Multiprocessor Programming 68

Also from the Code (2) write. A(victim=A) read. A(flag[B]) read. A(victim) public void lock()

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) {}; } Art of Multiprocessor Programming 69

Assumption (3) write. B(victim=B) write. A(victim=A) W. L. O. G. assume A is the

Assumption (3) write. B(victim=B) write. A(victim=A) W. L. O. G. assume A is the last thread to write victim Art of Multiprocessor Programming 70

Combining Observations (1) write. B(flag[B]=true) write. B(victim=B) (3) write. B(victim=B) write. A(victim=A) (2) write.

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) Thus, A read flag[B] == true and victim == A, so it could not have entered the CS QED Art of Multiprocessor Programming 71

Deadlock Free public void lock() { … while (flag[j] && victim == i) {};

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 Art of Multiprocessor Programming 72

Starvation Free • Thread i blocked only if j repeatedly re-enters so that flag[j]

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; } Art of Multiprocessor Programming 73

Question 3: But does it work in Java? public void lock() { flag[i] =

Question 3: But does it work in Java? public void lock() { flag[i] = 1; turn = 1 -i; while (!((flag[1 -i] == 0) || (turn == i))) { } } public void unlock() { flag[i]=0; } java Peterson … (results in deadlock) java Peterson. . . (mutual exclusion fails (if a counter is protected with these locks, we observe a problem after enough iterations))

Fact • Most hardware architectures don’t support sequential consistency • Because they think it’s

Fact • Most hardware architectures don’t support sequential consistency • Because they think it’s too strong Art of Multiprocessor Programming 75

The Flag Example y. read(0) x. write(1) y. write(1) x. read(0) • Each thread’s

The Flag Example y. read(0) x. write(1) y. write(1) x. read(0) • Each thread’s view is sequentially consistent – It went first time Art of Multiprocessor Programming 76

The Flag Example y. read(0) x. write(1) y. write(1) x. read(0) • Entire history

The Flag Example y. read(0) x. write(1) y. write(1) x. read(0) • Entire history isn’t sequentially consistent – Can’t both go first time Art of Multiprocessor Programming 77

The Flag Example y. read(0) x. write(1) y. write(1) x. read(0) • Is this

The Flag Example y. read(0) x. write(1) y. write(1) x. read(0) • Is this behavior really so wrong? – We can argue either way … time Art of Multiprocessor Programming 78

Opinion 1: It’s Wrong • This pattern – Write mine, read yours • Is

Opinion 1: It’s Wrong • This pattern – Write mine, read yours • Is exactly the flag principle – Beloved of Alice and Bob – Heart of mutual exclusion • Peterson • Bakery, etc. • It’s non-negotiable! Art of Multiprocessor Programming 79

Opinion 2: But It Feels So Right … • Many hardware architects think that

Opinion 2: But It Feels So Right … • Many hardware architects think that sequential consistency is too strong • Too expensive to implement in modern hardware • OK if flag principle – violated by default – Honored by explicit request Art of Multiprocessor Programming 80

Who knew you wanted to synchronize? • Writing to memory = mailing a letter

Who knew you wanted to synchronize? • Writing to memory = mailing a letter • Vast majority of reads & writes – Not for synchronization – No need to idle waiting for post office • If you want to synchronize – Announce it explicitly – Pay for it only when you need it Art of Multiprocessor Programming 81

Explicit Synchronization • Memory barrier instruction – Flush unwritten caches – Bring caches up

Explicit Synchronization • Memory barrier instruction – Flush unwritten caches – Bring caches up to date • Expensive Art of Multiprocessor Programming 82

Volatile • In Java, can ask compiler to keep a variable up-to-date with volatile

Volatile • In Java, can ask compiler to keep a variable up-to-date with volatile keyword • Also inhibits reordering & other “optimizations” • Example: public static volatile int[] flag; public static volatile int z = 0; Art of Multiprocessor Programming 83

Question • Can this result in i=0 and j=0?

Question • Can this result in i=0 and j=0?

Answer: Yes! • How can i=0 and j=0?

Answer: Yes! • How can i=0 and j=0?

Working Memory v. s. Main Memory • Every thread has a working memory in

Working Memory v. s. Main Memory • Every thread has a working memory in which it keeps its own working copy of variables that it must use or assign. As the thread executes a program, it operates on these working copies. • The main memory contains the master copy of every variable.

Low level actions

Low level actions

How can this happen? • Compiler can reorder statement or keep values in registers

How can this happen? • Compiler can reorder statement or keep values in registers • Processor can reorder them • On multiprocessor, values not synchronized in global memory • Must use synchronization to enforce visibility and ordering as well as mutual exclusion

Synchronization Action //block until obtain lock synchronized (an. Object) { //get main memory value

Synchronization Action //block until obtain lock synchronized (an. Object) { //get main memory value of field 1 and field 2 int x = an. Object. field 1; int y = an. Object. field 2; an. Object. field 3 = x + y; //commit value of field 3 to main memory } // release lock more. Code();

When are actions visible to other thread?

When are actions visible to other thread?

What does volatile mean? • C/C++ spec --There is no implementation independent meaning of

What does volatile mean? • C/C++ spec --There is no implementation independent meaning of volatile • Situation a little better with Java Technology --volatile reads/writes guaranteed to go directly to main memory e. g. can’t be cached in registers or local memory

Using volatile • Volatile used to guarantee visibility of writes --stop() must be declared

Using volatile • Volatile used to guarantee visibility of writes --stop() must be declared volatile --Otherwise, compiler could keep in register class Animator implements Runnable { private volatile boolean stop = false; public void stop() { stop = true; } public void run() { while (!stop) one. Step(); } private void one. Step() {/*……*/} }

The Filter Algorithm for n Threads There are n-1 “waiting rooms” called levels ncs

The Filter Algorithm for n Threads There are n-1 “waiting rooms” called levels ncs • At each level – At least one enters level – At least one blocked if many try cs • Only one thread makes it through Art of Multiprocessor Programming 93

Filter class Filter implements Lock { int[] level; // level[i] for thread i int[]

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

Filter class Filter implements Lock { … public void lock(){ for (int L =

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; }} Art of Multiprocessor Programming 95

Filter class Filter implements Lock { … public void lock() { for (int L

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 Art of Multiprocessor Programming 96

Filter class Filter implements Lock { … public void lock() { for (int L

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 }} public void release(int i) { level[i] = 0; }} Art of Multiprocessor Programming Announce intention to enter level L 97

Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() {

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; }} Art of Multiprocessor Programming Give priority to anyone but me 98

Filter class Filter implements Lock { Wait as long as someone else is at

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

Filter class Filter implements Lock { int level[n]; int victim[n]; public void lock() {

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) { it completes Thread enters level L when level[i] = 0; the loop }} Art of Multiprocessor Programming 100

Claim • Start at level L=0 • At most n-L threads enter level L

Claim • Start at level L=0 • At most n-L threads enter level L • Mutual exclusion at level L=n-1 ncs cs L=0 L=1 L=n-2 L=n-1 Art of Multiprocessor Programming 101

Induction Hypothesis • No more than n-(L-1) at level L-1 • Induction step: by

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 assume L-1 has n-(L-1) L has n-L cs Art of Multiprocessor Programming prove 102

Proof Structure ncs A B Assumed to enter L-1 n-L+1 = 4 Last to

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

Just Like Peterson (1) write. B(level[B]=L) write. B(victim[L]=B) public void lock() { for (int

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 Art of Multiprocessor Programming 104

From the Code (2) write. A(victim[L]=A) read. A(level[B]) read. A(victim[L]) public void lock() {

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) {}; }} Art of Multiprocessor Programming 105

By Assumption (3) write. B(victim[L]=B) write. A(victim[L]=A) By assumption, A is the last thread

By Assumption (3) write. B(victim[L]=B) write. A(victim[L]=A) By assumption, A is the last thread to write victim[L] Art of Multiprocessor Programming 106

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.

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]) Art of Multiprocessor Programming 107

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.

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]) Art of Multiprocessor Programming 108

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.

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]) Thus, A read level[B] ≥ L, and victim[L] = A, so it could not have entered level L! Art of Multiprocessor Programming 109

No Starvation • Filter Lock satisfies properties: – Just like Peterson Alg at any

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 Art of Multiprocessor Programming 110

Shared Memory • Shared read/write memory locations called Registers (historical reasons) • Come in

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 Art of Multiprocessor Programming 111

Theorem At least N MRSW (multireader/single-writer) registers are needed to solve deadlock-free mutual exclusion.

Theorem At least N MRSW (multireader/single-writer) registers are needed to solve deadlock-free mutual exclusion. N registers like Flag[]… Art of Multiprocessor Programming 112

Summary of Lecture • In the 1960’s several incorrect solutions to starvation-free mutual exclusion

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 2 N RWRegisters Art of Multiprocessor Programming 113

Summary of Lecture • N RW-Registers inefficient – Because writes “cover” older writes •

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… Art of Multiprocessor Programming 114