Mutual Exclusion

37
cs4414 Spring 2014 University of Virginia David Evans Class 20: Mutual Exclusion Reminder: Project Ideas are due by 11:59pm tonight!

description

University of Virginia cs4414: Operating Systems http://rust-class.org For embedded notes, see: http://rust-class.org/class-20-mutual-exclusion.html

Transcript of Mutual Exclusion

Page 1: Mutual Exclusion

cs4414 Spring 2014University of VirginiaDavid Evans

Class 20:Mutual Exclusion

Reminder: Project Ideas are due by 11:59pm tonight!

Page 2: Mutual Exclusion

2

Plan for TodayRecap: Dijkstra’s Mutual Exclusion ProblemWhy Obvious Solutions FailPractical Solutions with Modern ProcessorsDijkstra’s SolutionLamport’s Solution

Reminder: Project Ideas are due by 11:59pm tonight!

Page 3: Mutual Exclusion

3

Page 4: Mutual Exclusion

4

Final Keynote (Sunday):Steve Huffman

Page 5: Mutual Exclusion

5

Page 6: Mutual Exclusion

6

Decoy Project!

Page 7: Mutual Exclusion

7

Lessons for your Project Submissions:1. Don’t submit something I will think is a

decoy project! (Too late for that here)2. Don’t do something that involves breaking

into my house.3. Do do something creative and unexpected.

Page 8: Mutual Exclusion

8

T2 T3 T4T1

N independent threads

Shared Memory (atomic read and write)

T5 Program:

loop { non-critical { … } critical { … }}

Requirements:1. Only one thread may be in the critical section at any time.2. Each must eventually be able to enter its critical section.3. Must be symmetrical (all run same program).4. Cannot make any assumptions about speed of threads.

Page 9: Mutual Exclusion

9

Clever “Cheating” Solution

loop { if turn == i: critical_section; turn = i + 1;}

T2 T3T1

Shared Memoryturn:

Initially, turn = 1

Page 10: Mutual Exclusion

10

loop { if turn == i: critical_section; turn = i + 1;}

Initially, turn = 1

Page 11: Mutual Exclusion

11

Attempted Solution

loop { if not lock: lock = true; critical_section; lock = false;}

T2 T3T1

Shared Memorylock:

Page 12: Mutual Exclusion

12

Attempted Fix

loop { if lock == 0: lock = i; if lock == i: critical_section; lock = 0;}

T2 T3T1

Shared Memorylock:

Page 13: Mutual Exclusion

13

Attempted Fix of Fixloop { if lock1 == 0: lock1 = i; if lock1 == i: if lock2 == 0: lock2 = i; if lock2 == i: critical_section; lock2 = 0; lock1 = 0;}

T2 T3T1

Shared Memorylock1: lock2:

Page 14: Mutual Exclusion

14

Attempted Fix of Fix of Fix …loop { if lock1 == 0: lock1 = i; if lock1 == i: if lock2 == 0: lock2 = i; if lock2 == i: critical_section; lock2 = 0; lock1 = 0;}

T2 T3T1

Shared Memorylock1: lock2:

Do we need to see why 3-locks still breaks?

Page 15: Mutual Exclusion

15

Uniprocessor

Easy (Kernel Cheating) Solution

loop { non-critical; disable interrupts critical_section; enable interrupts}

T2 T3T1

Shared Memory

Page 18: Mutual Exclusion

18

Uniprocessor

Easy (Kernel Cheating) Solution

loop { non-critical; disable interrupts critical_section; enable interrupts}

T2 T3T1

Shared Memory

How well does this solution work for modern kernels?

Page 19: Mutual Exclusion

19

Easy (Cheating) Solution

T2 T3T1

Shared Memory (with atomic

read/write/test&set)

lock:

test_and_set(v)returns current value of vsets value of v to true

Page 20: Mutual Exclusion

20

Easy (Cheating) Solution

loop { if not test_and_set(lock): critical_section; lock = false;}

T2 T3T1

Shared Memory (with atomic

read/write/test&set)

lock:

test_and_set(v)returns current value of vsets value of v to true

Page 21: Mutual Exclusion

21

Does your processor provide such an instruction?

Page 22: Mutual Exclusion

22

Intel x86

Page 23: Mutual Exclusion

23

ARMv7

Page 24: Mutual Exclusion

24

Page 25: Mutual Exclusion

25

Implementing a Mutex Lock

lock_mutex(lock);criticalunlock_mutex(lock);

LDREX <dest> <location><dest> = <location>Sets monitor on <location> in Exclusive state

STREX <success> <value> <location>Conditionally store <value> into exclusive <location>.If permitted, <success> = 1 and <location> = <value>.If not, <success> = 0 and <location> value unchanged.

Context switch clears monitor (Open) state.

Page 26: Mutual Exclusion

26

lock_mutex(lock);criticalunlock_mutex(lock);

lock_mutex(lock):try_again: LDREX R2, [lock] if R2 goto try_again STREX R2, 1, [lock] if not R2 goto try_again

unlock_mutex(lock): STR [lock], 0

LDREX <dest> <location><dest> = <location>Sets monitor on <location> in Exclusive state

STREX <success> <value> <location>Conditionally store <value> into exclusive <location>.If permitted, <success> = 1 and <location> = <value>.If not, <success> = 0 and <location> value unchanged.

Page 27: Mutual Exclusion

27

lock_mutex(lock);criticalunlock_mutex(lock);

lock_mutex(lock):try_again: LDREX R2, [lock] if R2 goto try_again STREX R2, 1, [lock] if not R2 goto try_again

unlock_mutex(lock): STR [lock], 0

What if you care about energy?

Page 28: Mutual Exclusion

28

Page 29: Mutual Exclusion

29

WFE and WFI do not provide synchronization! Just hints to the processor to save energy.

Page 30: Mutual Exclusion

30

ARMv7

Why two instructions like this instead of one?

Page 31: Mutual Exclusion

31

T2 T3 T4T1

Shared Memory (atomic read and write)

T5

Program:

loop { non-critical { … } critical { … }}

Requirements:1. Only one thread may be in the critical section at any time.2. Each must eventually be able to enter its critical section.3. Must be symmetrical (all run same program).4. Cannot make any assumptions about speed of threads.

no special combined atomic operations (e.g., test-and-set, LDREX/STREX)

Page 32: Mutual Exclusion

32

Dijkstra (1973)From Edgar Daylight’s collection:http://www.dijkstrascry.com/node/59

1965

Page 33: Mutual Exclusion

33

Page 34: Mutual Exclusion

34

Program for Processor i loop { b[i] := falseL1: if k != i c[i] := true if b[k] k := i goto L1 else: c[i] := false for j in [1, …, N]: if j != i and not c[j]: goto L1 critical section; c[i] := true b[i] := true }

Initializationb[1:N] = [true, true, …]c[1:N] = [true, true, …]k = choose([1..N])

Page 35: Mutual Exclusion

35

Safety: only one program can be in critical section

Program for Processor i loop { b[i] := falseL1: if k != i c[i] := true if b[k]: k := i goto L1 else: c[i] := false for j in [1, …, N]: if j != i and not c[j]: goto L1 critical section; c[i] := true b[i] := true }

Page 36: Mutual Exclusion

36

Program for Processor i loop { b[i] := falseL1: if k != i c[i] := true if b[k]: k := i goto L1 else: c[i] := false;L4: for j in [1, …, N]: if j != i and not c[j]: goto L1 critical section; c[i] := true b[i] := true }

How do we know none of the c[.]’s changed during the loop?

Page 37: Mutual Exclusion

37

ChargeThink about Dijkstra’s Solution:

How does it guarantee mutual exclusion?How does it guarantee liveness?

Submit Project Idea by 11:59pm Tonight