41
Concurrency: Deadlock ©Magee/ Kramer Claus Brabrand [email protected] University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer Claus Brabrand [email protected] University of Aarhus Deadlock Concurrency

  • View
    224

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Claus Brabrand

[email protected]

University of Aarhus

Deadlock

Concurrency

Page 2: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Repetition

Monitors and Condition Synchronization

Page 3: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Monitors & Condition Synchronization

Concepts: monitors: encapsulated data + access procedures +mutual exclusion + condition

synchronization + single access procedure active in the

monitor nested monitors

Models: guarded actions

Practice: private data and synchronized methods (exclusion).

wait(), notify() and notifyAll() for condition synch. single thread active in the monitor at a time

Page 4: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

wait(), notify(), and notifyAll()

Thread A Thread B

wait()notify()

Monitor

data

Wait() causes the thread to exit the monitor,permitting other threads to enter the monitor

public final void wait() throws InterruptedException;

public final void notify();

public final void notifyAll();

Page 5: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Condition Synchronization (in Java)

class CarParkControl { protected int spaces, capacity;

synchronized void arrive() throws Int’Exc’ { while (!(spaces>0)) wait(); --spaces; notifyAll(); }

synchronized void depart() throws Int’Exc’ { while (!(spaces<capacity)) wait(); ++spaces; notifyAll(); }}

CONTROL(N=4) = SPACES[N],SPACES[i:0..N] = (when(i>0) arrive -> SPACES[i-1] |when(i<N) depart -> SPACES[i+1]).

Page 6: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Semaphores

Semaphores are widely used for dealing with inter-process synchronization in operating systems.

Semaphore s : integer var that can take only non-neg. values.

sem.p(); // “passern”; decrement (block if counter = 0)

sem.v(); // “vrijgeven”; increment counter (allowing one “p”)

Page 7: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

LTSA’s (analyse safety) predicts a possible DEADLOCK:

This situation is known as the nested monitor problem.

Composing potential DEADLOCK States Composed: 28 Transitions: 32 in 60ms Trace to DEADLOCK: get

Nested Monitors - Bounded Buffer Model

Page 8: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Chapter 6

Deadlock

Page 9: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Deadlock

Concepts: system deadlock (no further progress)

4 necessary & sufficient conditions

Models: deadlock - no eligible actions

Practice: blocked threads

Aim: deadlock avoidance - to design systems where deadlock cannot occur.

Page 10: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Deadlock: 4 Necessary and Sufficient Conditions

1. Mutual exclusion cond. (aka. “Serially reusable resources”):

the processes involved share resources which they use under mutual exclusion.

2. Hold-and-wait condition (aka. “Incremental acquisition”):

processes hold on to resources already allocated to them while waiting to acquire additional resources.

3. No pre-emption condition:

once acquired by a process, resources cannot be “pre-empted” (forcibly withdrawn) but are only released voluntarily.

4. Circular-wait condition (aka. “Wait-for cycle”):

a circular chain (or cycle) of processes exists such that each process holds a resource which its successor in the cycle is waiting to acquire.

Page 11: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Wait-For Cycle

A

B

CD

E

Has A awaits B

Has B awaits C

Has C awaits DHas D awaits E

Has E awaits A

Page 12: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

6.1 Deadlock Analysis - Primitive Processes

Deadlocked state is one with no outgoing transitions

In FSP: (modelled by) the STOP processMOVE = (north->(south->MOVE|north->STOP)).

Analysis using LTSA:

MOVEnorth north

south

0 1 2

Trace to DEADLOCK:northnorth

Shortest path to DEADLOCK:

Page 13: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Deadlock Analysis - Parallel Composition

In practise, deadlock arises from parallel composition of interacting processes.

RESOURCE = (get-> put-> RESOURCE).

P = (printer.get-> scanner.get-> copy-> printer.put-> scanner.put-> P).

Q = (scanner.get-> printer.get-> copy-> scanner.put-> printer.put-> Q).

||SYS = (p:P || q:Q || {p,q}::printer:RESOURCE || {p,q}::scanner:RESOURCE).

printer:RESOURCEgetput

SYS

scanner:RESOURCEgetput

p:Pprinter

scanner

q:Qprinter

scanner

Deadlock trace? Avoidance...

P = (x -> y -> P).Q = (y -> x -> Q).||D = (P || Q).

Trace to DEADLOCK: p.printer.get q.scanner.get

Page 14: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Recall the 4 conditions

1. Mutual exclusion cond. (aka. “Serially reusable resources”):

the processes involved share resources which they use under mutual exclusion.

2. Hold-and-wait condition (aka. “Incremental acquisition”):

processes hold on to resources already allocated to them while waiting to acquire additional resources.

3. No pre-emption condition:

once acquired by a process, resources cannot be “pre-empted” (forcibly withdrawn) but are only released voluntarily.

4. Circular-wait condition (aka. “Wait-for cycle”):

a circular chain (or cycle) of processes exists such that each process holds a resource which its successor in the cycle is waiting to acquire.

Page 15: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Deadlock Analysis – Avoidance (#1 ?)

Have two printers and two scanners (no shared resources)

1. Mutual exclusion cond. (aka. “Serially reusable resources”):

the processes involved share resources which they use under mutual exclusion.

Deadlock? Scalability?

Page 16: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Deadlock Analysis – Avoidance (#2 ?)

Only one “mutex” lock for both scanner and printer:

Deadlock? Efficiency/Scalability?

2. Hold-and-wait condition (aka. “Incremental acquisition”):

processes hold on to resources already allocated to them while waiting to acquire additional resources.

LOCK = (acquire-> release-> LOCK).

P = (scanner_printer.acquire-> printer.get-> scanner.get-> copy-> scanner.put-> printer.put-> scanner_printer.release-> P).

Page 17: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Deadlock Analysis – Avoidance (#3 ?)

Force release (e.g., through timeout or arbiter):

P = (printer.get-> GETSCANNER),GETSCANNER = (scanner.get-> copy-> printer.put -> scanner.put-> P |timeout -> printer.put-> P).

Q = (scanner.get-> GETPRINTER),GETPRINTER = (printer.get-> copy-> printer.put -> scanner.put-> Q |timeout -> scanner.put-> Q).

Progress?

3. No pre-emption condition:

once acquired by a process, resources cannot be pre-empted (forcibly withdrawn) but are only released voluntarily.

Deadlock?

Page 18: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Deadlock Analysis – Avoidance (#4 ?)

Acquire resources in the same order:

Scalability/Progress/…?

4. Circular-wait condition (aka. “Wait-for cycle”):

a circular chain (or cycle) of processes exists such that each process holds a resource which its successor in the cycle is waiting to acquire.

Deadlock?

P = (printer.get-> scanner.get-> copy-> printer.put-> scanner.put-> P).

Q = (printer.get-> scanner.get-> copy-> printer.put-> scanner.put-> Q).

General solution: “sort resource acquisitions”

Page 19: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

6.2 Dining Philosophers

Five philosophers sit around a circular table. Each philosopher spends his life alternately thinking and eating. In the centre of the table is a large bowl of spaghetti. A philosopher needs two forks to eat a helping of spaghetti.

0

1

23

40

1

2

3

4

One fork is placed between each pair of philosophers and they agree that each will only use the fork to his immediate right and left.

Page 20: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Dining Philosophers - Model Structure Diagram

phil[4]:PHIL

phil[1]:PHIL

phil[3]:PHIL

phil[0]:PHIL

phil[2]:PHIL

FORK FORK

FORK

FORK FORK

lef tright

right

right

right

lef t

lef t

right

lef t

lef t

Each FORK is a shared resource with actions get and put.

When hungry, each PHIL must first get his right and left forks before he can start eating.

Page 21: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Dining Philosophers - Model

const N = 5

FORK = (get-> put-> FORK).

PHIL = (sitdown -> right.get -> left.get -> eat -> left.put -> right.put -> arise -> PHIL).

||DINING_PHILOSOPHERS =

forall [i:0..N-1] (phil[i]:PHIL ||

FORK).

Can this system deadlock?

Can this system deadlock?

0

1

23

40

1

2

3

4

{ phil[i].left, phil[((i-1)+N)%N].right }::

Page 22: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Dining Philosophers - Model Analysis

This is the situation where all the philosophers become hungry at the same time, sit down at the table and each philosopher picks up the fork to his right.

The system can make no further progress since each philosopher is waiting for a left fork held by his neighbour (i.e., a wait-for cycle exists)!

Trace to DEADLOCK: phil.0.sitdown phil.0.right.get phil.1.sitdown phil.1.right.get phil.2.sitdown phil.2.right.get phil.3.sitdown phil.3.right.get phil.4.sitdown phil.4.right.get

Page 23: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Dining Philosophers

Deadlock is easily detected in our model.

How easy is it to detect a potential deadlock in an implementation?

Page 24: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Dining Philosophers - Implementation in Java

Forks: shared passive entities (implement as

monitors)Applet

Diners

Thread

Philosopher1 n

Fork

1

n

PhilCanvas

display

controller

view

display

Philosophers: active entities (implement as

threads)

Page 25: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Dining Philosophers – Fork (Monitor)

class Fork { private boolean taken = false; private PhilCanvas display; private int identity;

Fork(PhilCanvas disp, int id) { display = disp; identity = id;}

synchronized void get() throws Int’Exc’ { while (taken) wait(); // cond. synch. (!) taken = true; display.setFork(identity, taken); }

synchronized void put() { taken = false; display.setFork(identity, taken); notify(); // cond. synch. (!) }}

taken encodes the state of the fork

taken encodes the state of the fork

FORK = (get-> put-> FORK).

Page 26: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Dining Philosophers – Philosopher (Thread)

class Philosopher extends Thread { public void run() { try { while (true) { view.setPhil(identity,view.SIT); sleep(controller.thinkTime()); right.get(); view.setPhil(identity,view.GOTRIGHT); sleep(500); // constant pause! left.get(); view.setPhil(identity,view.EATING); sleep(controller.eatTime()); left.put(); right.put(); view.setPhil(identity,view.ARISE); sleep(controller.standupTime()); } } catch (InterruptedException _) {} }}

PHIL = (sit -> right.get -> left.get -> eat -> left.put -> right.put -> arise -> PHIL).

Page 27: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Dining Philosophers – Main Applet

for (int i=0; i<N; i++) { phil[i] = new Philosopher(this, i, fork[(i-1+N)%N], fork[i]); phil[i].start();}

The Applet’s start() method creates (an arrary of) shared Fork monitors…:for (int i=0; i<N; i++) { fork[i] = new Fork(display, i);}

…and (an array of) Philosopher threads each of which is start()’ed:

left right

||DINING_PHILOSOPHERS = forall [i:0..N-1] (phil[i]:PHIL || { phil[i].left, phil[((i-1)+N)%N].right }::FORK).

Page 28: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Dining Philosophers

To ensure deadlock occurs eventually, the slider control may be moved to the left. This reduces the time each philosopher spends thinking and eating.

This "speedup" increases the probability of deadlock occurring.

Page 29: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Deadlock-free Philosophers

Deadlock can be avoided by ensuring that a wait-for cycle cannot exist.

Introduce an asymmetry into definition of philosophers.

Use the identity ‘i’ of a philosopher to make even numbered philosophers get their left forks first, odd their right first.

How?

PHIL[i:0..N-1] = (when (i%2==0) sitdown-> left.get ->...-> PHIL |when (i%2==1) sitdown-> right.get->...-> PHIL).

How does this solution compare tothe “sort-shared-acquisitions” idea?

Other strategies?

Page 30: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Summary

Conceptsdeadlock (no further progress)

4x necessary and sufficient conditions:

1. Mutual exclusion condition

2. Hold-and-wait condition

3. No pre-emption condition

4. Circular-wait condition

Modelsno eligible actions (analysis gives shortest path trace)

Practiceblocked threads

Aim - deadlock avoidance:

“Break at least one of

the deadlock conditions”.

Page 31: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Claus Brabrand

[email protected]

University of Aarhus

Program Correctness

Concurrency

Page 32: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Outline

PredicatesInductionInvariantsCorrectnessTerminationMonitor Invariants

Page 33: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Predicates (and Invariants)

A predicate is a boolean function:P: VARS -> BOOL , BOOL = {true,

false}

Predicate is an assertion about a program’s variables: It may be true or false, depending on the state of the program

(i.e., the values of the variables):

DEFINTION:valid predicate (aka. an invariant):

…if it is true every time the program gets therevalid program:

…if all of its predicates are valid

P(x,y) x>2 x + y = 10

For state {x=3, y=7}, P(x,y) is trueFor state {x=2, y=8}, P(x,y) is false

E.g.

E.g.

Page 34: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Induction: ”The Principle of Mathematical Induction”

Example:

Proof?!

For the example:

nN: P(n)

nN : [ 20 + 21 + … + 2n = 2n+1 – 1 ]

P(0)

induction stepbase case

Principle of mathematical induction:

P(n) [ 20 + 21 + … + 2n = 2n+1 – 1 ]

P(i) P(i+1)

Page 35: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Example Induction Proof

Example:

Base case (i.e. prove: P(0))

Induction step (i.e. prove: P(i) => P(i+1)):Assume the induction hypothesis

i.e. we have that P(i):

Now prove P(i+1)i.e. that:

P(n) [ 20 + 21 + … + 2n = 2n+1 – 1 ]

P(0) [ 20 = 20+1 – 1 ]

[ 20 + 21 + … + 2i = 2i+1 – 1 ]

[ 20 + 21 + … + 2i+1 = 2(i+1)+1 – 1 ]

20 + 21 + … + 2i + 2i+1 (20 + 21 + … + 2i) + 2i+1=

(2i+1 – 1) + 2i+1 == 2*2i+1 – 1 = 2(i+1)+1 – 1 I.H.

Page 36: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Invariants: Proof (Predicates + Induction)

Loop invariants (attached to while-loops)Proof: (induction in #loop iterations!):

Base case (P(i=0)):Prove that: INV true having done “0” iterations

Induction step (P(i) P(i+1)):Assume (induction hypothesis) : INV true having done “i” iterations

Prove that: INV true having done “i+1” iterations

int rest = amount;int n1 = 0, n5 = 0, n10 = 0;while (rest > 0) { // INV: [ ( amount = 10*n10 + 5*n5 + 1*n1 + rest ) ( rest > 0 ) ] if (rest >= 10) { rest = rest – 10; n10 = n10 + 1; } else if (rest >= 5) {rest = rest – 5; n5 = n5 + 1; } else if (rest >= 1) {rest = rest – 1; n1 = n1 + 1; }}

Page 37: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Program Correctness (Example: Money Change)

Decorated program: Invariants should be useful! (not: {2+2 = 4} )!Usually associated with while(/if) statements

Proving the invariants helps us establish program correctness;in this case, that:

void change(int amount) { if (amount < 0) abort(); // INV: [ amount >= 0 ] int rest = amount; int n1 = 0, n5 = 0, n10 = 0; while (rest != 0) { // INV: [ ( amount = 10*n10 + 5*n5 + 1*n1 + rest ) ] if (rest >= 10) { rest = rest – 10; n10 = n10 + 1; } else if (rest >= 5) {rest = rest – 5; n5 = n5 + 1; } else if (rest >= 1) {rest = rest – 1; n1 = n1 + 1; } } // INV: [ amount = 10*n10 + 5*n5 + 1*n1 ] output(amount, n10, n5, n1);}

amount = 10*n10 + 5*n5 + 1*n1 is calculated

if (b) abort();{ b }

Induction: [ P(0) ( P(i) => P(i+1) ) ]

while (b) {I} S{I b }

Page 38: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Termination (Undecidable in General!)

“if the program terminates, then the result is correct”However, says nothing about termination!!

In fact; termination is undecidable:Proof (by-contradiction):

Assume decidability (i.e. there exists program, H, such that):

Now construct program Pthis:

What would H say about this program (Pthis)?!?

H(P) = true, if program P terminates = false, if program P doesn’t terminate

if (H(Pthis)) loop();else terminate();

:-o

Page 39: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Termination (Sufficient Condition)

“If there’s something (discrete) that gets strictly smaller for every iteration and the loop stops when that something is zero,then the loop terminates”!

That something is called a termination function, T:T: State -> N

Example:

Here, we can use termination function:

while (rest > 0) { if (rest >= 10) { rest = rest – 10; n10 = n10 + 1; } else if (rest >= 5) {rest = rest – 5; n5 = n5 + 1; } else if (rest >= 1) {rest = rest – 1; n1 = n1 + 1; }}

T(state) = rest

Page 40: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

Monitor Invariants

Interleavings make it hard to use invariants!!! However, monitors:

mutual exclusionhave (complex) state and state correlations

=> invariants can help here: monitor invariants!

{MI} must be true when there’s no thread executing inside…=> also when we exit the monitor by invoking wait()!

Monitor invariant:

Class Buffer { protected int in, out, count, size; // {monitor invariant}

synchronized void put(Object o) throws Int’Exc’ { while (!(count<size)) wait(); ...; notifyAll(); }}

( 0 <= count <= size) ( 0 <= in < size) ( 0 <= out < size) ( in = (out + count) % size)

Page 41: Concurrency: Deadlock ©Magee/Kramer Claus Brabrand brabrand@daimi.au.dk University of Aarhus Deadlock Concurrency

Concurrency: Deadlock ©Magee/Kramer

</Invariants>

Exercises:-1) Induction proof

-2) Factorial-3) Buffer