concurrency: concurrent execution ©magee/kramer claus brabrand [email protected] university of...
Post on 15-Jan-2016
232 views
TRANSCRIPT
Concurrency: concurrent execution ©Magee/Kramer
Claus Brabrand
University of Aarhus
Concurrent Execution
Concurrency
Concurrency: concurrent execution ©Magee/Kramer
Repetition (Concepts, Models, and Practice)
Concepts:We adopt a model-based approach for the design and
construction of concurrent programs
Safe model => safe program
Models:We use finite state models to represent concurrent behaviour
(Finite State Processes and Labelled Transition Systems)
Practice:We use Java for constructing concurrent programs
Concurrency: concurrent execution ©Magee/Kramer
Repetition (Models; LTS/FSM, FSP)
Model = simplified representation of the real world
Based on Labelled Transition Systems (LTS ):
Described textually as Finite State Processes
(FSP ):
engineOn
speed
engineOff
0 1
EngineOff = (engineOn-> EngineOn), EngineOn = (engineOff-> EngineOff |speed->EngineOn).
Aka. Finite StateMachine (FSM )
Focuses on concurrency aspects (of the program)- everything else abstracted away
Concurrency: concurrent execution ©Magee/Kramer
Repetition (Finite State Processes; FSP)
Finite State Processes (FSP):
P : STOP // termination| (x -> P) // action prefix| (when (…) x -> P) // guard| P | P’ // choice| P +{ … } // alphabet extension| X // process variable
action indexing x[i:1..N]->P or x[i]->P
process parameters P[i:1..N] = …
constant definitions const N = 3
range definitions range R = 0..NWhich constructions do not add expressive power?(and are thus only "syntactic sugar").
Concurrency: concurrent execution ©Magee/Kramer
Repetition (Java Threads)
Subclassing java.lang.Thread:
Implementing java.lang.Runnable:
class MyThread extends Thread { public void run() { // ... }}
class MyRun implements Runnable { public void run() { // ... }}
Thread t = new MyThread();t.start();// ...
Thread t = new Thread(new MyRun());t.start();// ...
Concurrency: concurrent execution ©Magee/Kramer
Chapter 3
Concurrent Execution
Concurrency: concurrent execution ©Magee/Kramer
Concurrent execution
Concepts: processes - concurrent execution and interleaving.
process interaction.
Models: parallel composition of asynchronous processes
- interleavinginteraction - shared actions
process labelling, and action relabelling and hiding
structure diagrams
Practice: Multithreaded Java programs
Concurrency: concurrent execution ©Magee/Kramer
Definition: Parallelism
Parallelism (aka. Real/True Concurrent Execution)
Physically simultaneous processing
Involves multiple processing elements (PEs)
and/or independent device operations
A
Time
B
C
Concurrency: concurrent execution ©Magee/Kramer
Definition: Concurrency
A
Time
B
C
Concurrency (aka. Pseudo-Concurrent Execution)
Logically simultaneous processing
Does not imply multiple processing elements (PEs)
Requires interleaved execution on a single PE
Concurrency: concurrent execution ©Magee/Kramer
Parallelism vs. Concurrency
Both concurrency and parallelism require controlled access to shared resources.
We use the terms parallel and concurrent interchangeably (and generallydo not distinguish between real and pseudo-concurrent execution).
Also, creating software independent of the physical setup, makes us capable of deploying it on any platform!
Both concurrency and parallelism require controlled access to shared resources.
We use the terms parallel and concurrent interchangeably (and generallydo not distinguish between real and pseudo-concurrent execution).
Also, creating software independent of the physical setup, makes us capable of deploying it on any platform!
Parallelism Concurrency
A
Time
B
C
A
Time
B
C
Concurrency: concurrent execution ©Magee/Kramer
3.1 Modelling Concurrency
How do we model concurrency?
Arbitrary relative order of actions from different processes
(interleaving but preservation of each process order)
x
Possible execution sequences?
y
Asynchronousmodel of execution
x ; y y ; x x || y
Concurrency: concurrent execution ©Magee/Kramer
3.1 Modelling Concurrency
How should we model process execution speed?
We choose to abstract away time:
Arbitrary speed!
+: independent of architecture, processor speed, scheduling policies, …
-: we can say nothing of real-time properties
a
b
x
y
Concurrency: concurrent execution ©Magee/Kramer
parallel composition - action interleaving
scratchthinktalk thinkscratchtalk thinktalkscratch
Possible traces as a result of action interleaving?
If P and Q are processes then (P||Q) represents the concurrent execution of P and Q. The operator ‘||’ is the parallel composition operator.
ITCH = (scratch->STOP).CONVERSE = (think->talk->STOP).
||CONVERSE_ITCH = (ITCH || CONVERSE).
Concurrency: concurrent execution ©Magee/Kramer
parallel composition - action interleaving
2 states3 states
(0,0)
(0,1)
(0,2)
(1,2)
(1,1)
(1,0)
from CONVERSEfrom ITCH 2 x 3 states
ITCH
scratch
0 1CONVERSE
think talk
0 1 2
CONVERSE_ITCH
scratch
think
scratch
talk scratch
talk think
0 1 2 3 4 5
Cartesian product?
Concurrency: concurrent execution ©Magee/Kramer
parallel composition - algebraic laws
Commutative: (P||Q) = (Q||P)Associative: (P||(Q||R)) = ((P||Q)||R)
= (P||Q||R).
Clock radio example:
CLOCK = (tick->CLOCK).RADIO = (on->off->RADIO).
||CLOCK_RADIO = (CLOCK || RADIO).
LTS? Traces? Number of states?
Concurrency: concurrent execution ©Magee/Kramer
modeling interaction - shared actions
If processes in a composition have actions in common, these actions are said to be shared. Shared actions are the way that process interaction is modelled. While unshared actions may be arbitrarily interleaved, a shared action must be executed at the same time by all processes that participate in the shared action.
MAKE1 = (make->ready->STOP).USE1 = (ready->use->STOP).
||MAKE1_USE1 = (MAKE1 || USE1).
Shared Actions:
MAKE1 synchronizes with USE1 when ready.
LTS? Traces? Number of states?
Concurrency: concurrent execution ©Magee/Kramer
modeling interaction - example
3 states3 states
3 x 3 states?
MAKE1 = (make->ready->STOP).USE1 = (ready->use->STOP).
||MAKE1_USE1 = (MAKE1 || USE1).
make ready
make
make
ready
ready
readyreadyready
use use useNo…!
Concurrency: concurrent execution ©Magee/Kramer
modeling interaction - example
3 states3 states
MAKE1 = (make->ready->STOP).USE1 = (ready->use->STOP).
||MAKE1_USE1 = (MAKE1 || USE1).
make
ready
use
Interaction may constrain the overall behaviour !
4 states!
ready
make
make
ready
ready
readyreadyready
use use
Concurrency: concurrent execution ©Magee/Kramer
Example
P = (x -> y -> P).Q = (y -> x -> Q).
||R = (P || Q).
LTS? Traces? Number of states?
2 states2 states
Concurrency: concurrent execution ©Magee/Kramer
modeling interaction - example
MAKER = (make->ready->MAKER).USER = (ready->use->USER).
||MAKER_USER = (MAKER || USER).
LTS? Traces?
Can we make sure the MAKER does not “get ahead of” the USER (i.e. never make before use); and if so, how?
Concurrency: concurrent execution ©Magee/Kramer
modeling interaction - handshake
A handshake is an action acknowledged by another:
make ready use
used
0 1 2 3
MAKERv2 = (make->ready->used->MAKERv2).USERv2 = (ready->use->used->USERv2).
||MAKER_USERv2 = (MAKERv2 || USERv2).
Concurrency: concurrent execution ©Magee/Kramer
modeling interaction - multiple processes
Multi-party synchronization:
makeA
makeB makeA ready assemble
used
makeB
0 1 2 3 4 5
MAKE_A = (makeA->ready->used->MAKE_A).MAKE_B = (makeB->ready->used->MAKE_B).ASSEMBLE = (ready->assemble->used->ASSEMBLE).
||FACTORY = (MAKE_A || MAKE_B || ASSEMBLE).
Concurrency: concurrent execution ©Magee/Kramer
composite processes
A composite process is a parallel composition of primitive processes. These composite processes can be used in the definition of further compositions.
||MAKERS = (MAKE_A || MAKE_B).
||FACTORY = (MAKERS || ASSEMBLE).
||FACTORY = ((MAKE_A || MAKE_B)|| ASSEMBLE).
substitution of def’n of MAKERS
associativity!
||FACTORY = (MAKE_A || MAKE_B || ASSEMBLE).
Further simplification?
Concurrency: concurrent execution ©Magee/Kramer
process labelling
a:P prefixes each action label in the alphabet of P with a.
SWITCH = (on->off->SWITCH).
||TWO_SWITCH = (a:SWITCH || b:SWITCH).
Two instances of a switch process:
a:SWITCHa.on
a.off
0 1
b:SWITCHb.on
b.off
0 1
LTS? (a:SWITCH)
Concurrency: concurrent execution ©Magee/Kramer
process labelling
a:P prefixes each action label in the alphabet of P with a.
SWITCH = (on->off->SWITCH).
||TWO_SWITCH = (a:SWITCH || b:SWITCH).
Two instances of a switch process:
||SWITCHES(N=3) = (forall[i:1..N] s[i]:SWITCH).
||SWITCHES(N=3) = (s[i:1..N]:SWITCH).
An array of instances of the switch process:
Concurrency: concurrent execution ©Magee/Kramer
process labelling by a set of prefix labels
{a1,..,an}::P replaces every action label x in the alphabet of P with the labels a1.x,…,an.x. Further, every transition (x->X) in the definition of P is replaced with the transitions ({a1.x,…,an.x} ->X).
Process prefixing is useful for modeling shared resources:
RESOURCE = (acquire->release->RESOURCE).
USER = (acquire->use->release->USER).
||RESOURCE_SHARE = (a:USER || b:USER || {a,b}::RESOURCE).
Concurrency: concurrent execution ©Magee/Kramer
process prefix labels for shared resources
How does the model ensure that the user that acquires the resource is the one to release it?
a:USERa.acquire a.use
a.release
0 1 2b:USER
b.acquire b.use
b.release
0 1 2{a,b}::RESOURCE
a.acquireb.acquire
a.releaseb.release
0 1
RESOURCE_SHARE
a.acquire
b.acquire b.use
b.release
a.use
a.release
0 1 2 3 4
RESOURCE = (acquire->release->RESOURCE).
USER = (acquire->use->release->USER).
||RESOURCE_SHARE = (a:USER || b:USER || {a,b}::RESOURCE).
Concurrency: concurrent execution ©Magee/Kramer
Example
X = (x -> STOP).
LTS? Traces? Number of states?
||SYS_1 = {a,b}:X.
||SYS_2 = {a,b}::X.
LTS? Traces? Number of states?
Concurrency: concurrent execution ©Magee/Kramer
action relabelling
Relabeling to ensure that composed processes synchronize on particular actions:
Relabelling functions are applied to processes to change the names of action labels. The general form of the relabelling function is: /{newlabel1/oldlabel1,… newlabeln/oldlabeln}.
CLIENT = (call->wait->continue->CLIENT).
SERVER = (request->service->reply->SERVER).
Concurrency: concurrent execution ©Magee/Kramer
action relabelling
||C_S = (C || S).
CLIENTcall reply
continue
0 1 2SERVER
call service
reply
0 1 2
CLIENT_SERVERcall service reply
continue
0 1 2 3
CLIENT = (call->wait->continue->CLIENT).
SERVER = (request->service->reply->SERVER).
C S
C_S
C = (CLIENT /{reply/wait}).
S = (SERVER /{call/request}).
Concurrency: concurrent execution ©Magee/Kramer
action relabelling - prefix labels
SERVERv2 = (accept.request ->service->accept.reply->SERVERv2).
CLIENTv2 = (call.request ->call.reply->continue->CLIENTv2).
||CLIENT_SERVERv2 = (CLIENTv2 || SERVERv2) /{call/accept}.
An alternative formulation of the client server system is described below using qualified or prefixed labels:
Concurrency: concurrent execution ©Magee/Kramer
action hiding - abstraction to reduce complexity
When applied to a process P, the hiding operator \{a1..ax} removes the action names a1..ax from the alphabet of P and makes these concealed actions "silent". These silent actions are labelled tau. Silent actions in different processes are not shared.
USER = (acquire->use->release->USER) \{use}.
acquire tau
release
0 1 2
Concurrency: concurrent execution ©Magee/Kramer
action hiding - abstraction to reduce complexity
When applied to a process P, the interface operator @{a1..ax} hides all actions in the alphabet of P not labelled in the set a1..ax.
Sometimes it is more convenient to specify the set of labels to be exposed....
USER = (acquire->use->release->USER) @{acquire,release}.
acquire tau
release
0 1 2
Concurrency: concurrent execution ©Magee/Kramer
action hiding
USER = (acquire->use->release->USER) \{use}.
USER = (acquire->use->release->USER) @{acquire,release}.
The following definitions are equivalent:
acquire tau
release
0 1 2
Minimization removes hidden tau actions to produce an LTS with equivalent observable behavior. acquire
release
0 1
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams
P a
bProcess P withalphabet {a,b}.
P a b Qm
Parallel Composition(P||Q) / {m/a,m/b,c/d}
P Qa
c dc
x xx
S
yxComposite process||S = (P||Q) @ {x,y}
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams
P a
bProcess P withalphabet {a,b}.
P a b Qm
Parallel Composition(P||Q) / {m/a,m/b,c/d}
P Qa
c dc
x xx
S
yxComposite process||S = (P||Q) @ {x,y}
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams
P a
bProcess P withalphabet {a,b}.
P a b Qm
Parallel Composition(P||Q) / {m/a,m/b,c/d}
P Qa
c dc
x xx
S
yxComposite process||S = (P||Q) @ {x,y}
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams
P a
bProcess P withalphabet {a,b}.
P a b Qm
Parallel Composition(P||Q) / {m/a,m/b,c/d}
P Qa
c dc
x xx
S
yxComposite process||S = (P||Q) @ {x,y}
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams
P a
bProcess P withalphabet {a,b}.
P a b Qm
Parallel Composition(P||Q) / {m/a,m/b,c/d}
P Qa
c dc
x xx
S
yxComposite process||S = (P||Q) @ {x,y}
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams
P a
bProcess P withalphabet {a,b}.
P a b Qm
Parallel Composition(P||Q) / {m/a,m/b,c/d}
X Ya
c dc
x xx
S
yxComposite process||S = (X||Y) @ {x,y}
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams
We use structure diagrams to capture the structure of a model expressed by the static combinators: parallel composition, relabeling and hiding.
range T = 0..3BUFF = (in[i:T]->out[i]->BUFF).
a:BUFF b:BUFFa.out
TWOBUFF
outininoutin out
||TWOBUF = (a:BUFF || b:BUFF) /{in/a.in, a.out/b.in, out/b.out} @{in,out}.
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams
Structure diagram for CLIENT_SERVER ?
CLIENT call request SERVERcall
replywait reply servicecontinue
CLIENT = (call->wait->continue->CLIENT).SERVER = (request->service->reply->SERVER).
||CLIENT_SERVER = (CLIENT||SERVER) /{reply/wait, call/request}.
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams
Structure diagram for CLIENT_SERVERv2 ?
CLIENTv2 call accept SERVERv2call
servicecontinue
SERVERv2 = (accept.request ->service->accept.reply->SERVERv2).CLIENTv2 = (call.request ->call.reply->continue->CLIENTv2).
||CLIENT_SERVERv2 = (CLIENTv2 || SERVERv2) /{call/accept}.
Concurrency: concurrent execution ©Magee/Kramer
structure diagrams - resource sharing
a:USER
printer
b:USER
printer
printer:RESOURCE
acquirerelease
PRINTER_SHARE
RESOURCE = (acquire->release->RESOURCE).USER = (printer.acquire->use->printer.release->USER).
||PRINTER_SHARE = (a:USER || b:USER || {a,b}::printer:RESOURCE).
Concurrency: concurrent execution ©Magee/Kramer
ThreadDemo model
THREAD = OFF,
OFF = (toggle->ON |abort->STOP),
ON = (toggle->OFF |output->ON |abort->STOP).
||THREAD_DEMO = (a:THREAD || b:THREAD) /{stop/{a,b}.abort}.
Interpret:
toggle, abort as inputs;
output as output
a:T b:Tstop
a.toggle
a.output b.output
b.toggleTHREAD_DEMO
Concurrency: concurrent execution ©Magee/Kramer
ThreadDemo code: MyThread
class MyThread extends Thread { private boolean on;
MyThread() { super(); this.on = false; }
public void toggle() { on = !on; }
public void abort() { this.interrupt(); }
private void output() { System.out.println(“output”); }
public void run() { try { while (true) { if (on) output(); sleep(1000); } } catch(Int’Exc’ _) { System.out.println(“Done!”);}}}
Concurrency: concurrent execution ©Magee/Kramer
ThreadDemo code: ThreadDemo
class ThreadDemo { public static void main(String[] args) { MyThread a = new MyThread(); MyThread b = new MyThread(); a.start(); b.start(); while (true) { switch (readChar()) { case ‘a’: a.toogle(); break; case ‘b’: b.toogle(); break; case ‘i’: stop(a,b); return; } private stop(MyThread a, MyThread b) { a.abort(); b.abort(); }}}}
Concurrency: concurrent execution ©Magee/Kramer
Summary
Conceptsconcurrent processes and process interaction
ModelsAsynchronous (arbitrary speed) & interleaving (arbitrary
order).
Parallel composition as a finite state process with action
interleaving.
Process interaction by shared actions.
Process labeling and action relabeling and hiding.
Structure diagrams
PracticeMultiple threads in Java.
Concurrency: concurrent execution ©Magee/Kramer
Claus Brabrand
University of Aarhus
Shared Objects and Mutual Exclusion
Concurrency
Concurrency: concurrent execution ©Magee/Kramer
Repetition (FSP)
FSP:P || Q // parallel compositiona:P // parameterized parallel
composition{…}::P // set prefixing (usually for
sharing)P / {x/y} // action relablingP \ {…} // hidingP @ {…} // keeping (hide complement)
Structure Diagrams:a:BUFF b:BUFFa.out
TWOBUFF
outininoutin out
Concurrency: concurrent execution ©Magee/Kramer
Chapter 4
Shared Objects & Mutual Exclusion
Concurrency: concurrent execution ©Magee/Kramer
Shared Objects & Mutual Exclusion
Concepts:Process interference
Mutual exclusion
Models:Model-checking for interference
Modelling mutual exclusion
Practice:Thread interference in shared objects in Java
Mutual exclusion in Java
synchronized objects, methods, and statements
Concurrency: concurrent execution ©Magee/Kramer
4.1 Interference
Garden
WestTurnstile
East
Turnstilepeople
People enter an ornamental garden through either of two turnstiles. Management wishes to know how many are in the garden at any time. (Nobody can exit).
The ”Ornamental Garden Problem ”:
Counter
012
Concurrency: concurrent execution ©Magee/Kramer
…and now for something completely different!
Der var engang en hytte lang ude i skoven...
En fysiker En biolog En matematiker
Måleusikkerhed!
Måleusikkerhed!
Reproduktion!Reproduktion!
Hvis der går1 person ind i
hytten,så er den tom!
Hvis der går1 person ind i
hytten,så er den tom!
...og...
3 4
Concurrency: concurrent execution ©Magee/Kramer
4.1 Ornamental Garden Problem (cont’d)
Garden
WestTurnstile
East
Turnstilepeople
Java implementation:
The concurrent program consists of:
two concurrent threads (west & east); and
a shared counter object
Counter
2
Concurrency: concurrent execution ©Magee/Kramer
Class Diagram
setvalue()
NumberCanvas
Applet
init()go()
Garden
Thread
Turnstile
run()
Counter
increment()
displaydisplay
east,west people
eastD,westD,counterD
counter
40 2020
Concurrency: concurrent execution ©Magee/Kramer
Ornamental Garden Program
The go() method of the Garden applet…
…creates the shared Counter object & the Turnstile threads.
class Garden extends Applet { NumberCanvas counterD, westD, eastD; Turnstile east, west; ... private void go() { counter = new Counter(counterD); west = new Turnstile(westD,counter); east = new Turnstile(eastD,counter); west.start(); east.start(); }}
Concurrency: concurrent execution ©Magee/Kramer
The Turnstile Class
class Turnstile extends Thread { NumberCanvas display; Counter counter;
public void run() { try { display.setvalue(0); for (int i=1; i<=Garden.MAX; i++) { Thread.sleep(1000); display.setvalue(i); counter.increment(); } } catch (InterruptedException _) {} }}
The Turnstile thread simulates periodic arrival of visitors by invoking the counter object’s increment() method every second
The Turnstile thread simulates periodic arrival of visitors by invoking the counter object’s increment() method every second
Concurrency: concurrent execution ©Magee/Kramer
The Shared Counter Class
class Counter { int value; NumberCanvas display;
void increment() { value = value + 1; display.setvalue(value); }}
The increment() method of the Counter class increments its internal value and updates the display.
Concurrency: concurrent execution ©Magee/Kramer
Running the Applet
After the East and West turnstile threads each have incremented the counter 20 times, the garden people counter is not the sum of the counts displayed. Why?
39 2020
Concurrency: concurrent execution ©Magee/Kramer
The Shared Counter Class (cont’d)
class Counter { int value; NumberCanvas display;
void increment() { value = value + 1; display.setvalue(value); }}
aload_0 // push “this” onto stackdup // duplicate top stack elementgetfield #2 // get value of “this.value”iconst_1 // push 1 onto stackiadd // add two top stack elementsputfield #2 // put result into “this.value”
Thread switch?
Concurrency: concurrent execution ©Magee/Kramer
Concurrent Method Activation
Thus, threads east and west may be executing the code for the increment method at the same time.
east
west
programcounter program
counter
PC PC
Shared code:
Java method activation is not atomic!
Counter.class:
aload_0 // thisdupgetfield #2 // xiconst_1iaddputfield #2 // xreturn
Concurrency: concurrent execution ©Magee/Kramer
Pedagogification; the Counter Class (cont’d)
class Counter { void increment() {
value = value + 1;
display.setvalue(value); }}
Concurrency: concurrent execution ©Magee/Kramer
Pedagogification; the Counter Class (cont’d)
class Counter { void increment() { int temp = value; // read Simulate.HWinterrupt(); value = temp + 1; // write display.setvalue(value); }}
The counter simulates a hardware interrupt during an increment(), between reading and writing to the shared counter value.class Simulate { // randomly force thread switch! public static void HWinterrupt() { if (random()<0.5) Thread.yield(); }}
Concurrency: concurrent execution ©Magee/Kramer
Running the Applet
Now the erroneous behaviour occurs all the time!
Concurrency: concurrent execution ©Magee/Kramer
Garden Model (Structure Diagram)
VAR:models read and write access to the shared counter value.
TURNSTILE:Increment is modelled inside TURNSTILE, since Java method activation is not atomic (i.e., thread objects east and west may interleave their read and write actions).
value:VARdisplay
write
GARDEN
west:TURNSTILE
value
endgo
arrive
east:TURNSTILE
value
endgo
arrive
goend
read
GARDEN
Concurrency: concurrent execution ©Magee/Kramer
Ornamental Garden Model (FSP)
const N = 4range T = 0..N
VAR = VAR[0],VAR[u:T] = (read[u] -> VAR[u] | write[v:T] -> VAR[v]).
TURNSTILE = (go -> RUN),RUN = (arrive -> INCREMENT | end -> TURNSTILE),INCREMENT = (value.read[x:T] -> value.write[x+1] -> RUN) +{value.write[0]}.
||GARDEN = (east:TURNSTILE || west:TURNSTILE || {east,west,display}::value:VAR) /{ go / {east,west}.go , end / {east,west}.end}.
(VAR) ?
(TURNSTILE) ?
(value:VAR) ? ({east,west,display}::value:VAR) ?
(east:TURNSTILE) ?
value:VARdisplay
write
GARDEN
west:TURNSTILE
value
endgo
arrive
east:TURNSTILE
value
endgo
arrive
goend
read
Concurrency: concurrent execution ©Magee/Kramer
Checking for Errors - Animation
Scenario checking - use animation to produce a trace.
Is the modelcorrect?
“Never send a human to do a machines job”
- Agent Smith (1999)
Concurrency: concurrent execution ©Magee/Kramer
Checking for Errors - Compose with Error Detector
TEST = TEST[0],TEST[v:T] = (when (v<N) west.arrive->TEST[v+1] |when (v<N) east.arrive->TEST[v+1] |end -> CHECK[v]),
CHECK[v:T] = (display.value.read[u:T] -> (when (u==v) right -> TEST[v] |when (u!=v) wrong -> ERROR)) +{display.value.write[T]}.
Exhaustive checking - compose the model with a TEST process which sums the arrivals and checks against the display value:
Concurrency: concurrent execution ©Magee/Kramer
Checking for Errors - Exhaustive Analysis
||TESTGARDEN = (GARDEN || TEST).
Use LTSA to perform an exhaustive search for ERROR:
Trace to property violation in TEST:goeast.arriveeast.value.read.0west.arrivewest.value.read.0east.value.write.1west.value.write.1enddisplay.value.read.1
wrong
LTSA produces the shortest path to reach the ERROR state.
LTSA produces the shortest path to reach the ERROR state.
Concurrency: concurrent execution ©Magee/Kramer
Interference and Mutual Exclusion
Interference bugs are extremely difficult to locate.
The general solution is:
Give methods mutually exclusive access to shared objects.
Mutual exclusion can be modelled as atomic actions.
Destructive update, caused by the arbitrary interleaving of read and write actions, is termed interference.
Concurrency: concurrent execution ©Magee/Kramer
4.2 Mutual Exclusion in Java
class SynchronizedCounter extends Counter { SynchronizedCounter(NumberCanvas n) { super(n); } synchronized void increment() { super.increment(); }}
We correct the Counter class by deriving a class from it and making its increment method synchronized:
Concurrent activations of a method in Java can be made mutually exclusive by prefixing the method with the keyword synchronized.
Concurrency: concurrent execution ©Magee/Kramer
The Garden Class (revisited)
If the fixit checkbox is ticked, the go() method creates a SynchronizedCounter:
class Garden extends Applet { private void go() { if (!fixit.getState()) counter = new Counter(counterD); else counter = new SynchCounter(counterD); west = new Turnstile(westD,counter); east = new Turnstile(eastD,counter); west.start(); east.start(); }}
Concurrency: concurrent execution ©Magee/Kramer
Mutual Exclusion - The Ornamental Garden
Java associates a lock with every object.
The Java compiler inserts code to: acquire the lock before executing a synchronized method release the lock after the synchronized method returns.
Concurrent threads are blocked until the lock is released.
Concurrency: concurrent execution ©Magee/Kramer
Java synchronized Statement
void increment() { synchronized(counter) { value = value + 1; } display.setvalue(value);}
synchronized void increment() { super.increment();}
Synchronized methods:
Variant - the synchronized statement :
Use synch methodswhenever possible.Use synch methodswhenever possible.
object reference
Concurrency: concurrent execution ©Magee/Kramer
Java -> Java Bytecode
Method void m()>> max_stack=3, max_locals=3 <<
0 aload_0 1 dup 2 astore_1 3 monitorenter 4 aload_0 5 dup 6 getfield #2 <Field X.x:int> 9 iconst_1 10 iadd 11 putfield #2 <Field X.x:int> 14 aload_1 15 monitorexit 16 goto 24 19 astore_2 20 aload_1 21 monitorexit 22 aload_2 23 athrow 24 return
Exception table: from to target type 4 16 19 any 19 22 19 any
1 class X {2 int x;3 void m() {4 synchronized(this) {5 x++;6 }7 }8 }
compile
Concurrency: concurrent execution ©Magee/Kramer
Define a mutual exclusion LOCK process:
4.3 Modeling Mutual Exclusion
LOCK = (acq -> rel -> LOCK).
TURNSTILE = (go -> RUN),RUN = (arrive -> INCREMENT | end -> TURNSTILE),INCREMENT = (value.acq -> value.read[x:T] -> value.write[x+1] -> value.rel->RUN ) +{value.write[0]}
Modify TURNSTILE to acquire and release the lock:
||LOCKVAR = (LOCK || VAR).
…and compose it with the shared VAR in the Garden:
||GARDEN = (east:TURNSTILE || west:TURNSTILE || {east,west,display}::value:LOCKVAR)
Concurrency: concurrent execution ©Magee/Kramer
Revised Ornamental Garden Model - Checking for Errors
A sample trace:
Use LTSA to performan exhaustive check: “is TEST satisfied”?
go east.arrive east.value.acq east.value.read.0 east.value.write.1 east.value.rel west.arrive west.value.acq west.value.read.1 west.value.write.2 west.value.rel end display.value.read.2 right
Concurrency: concurrent execution ©Magee/Kramer
Summary
Conceptsprocess interference
mutual exclusion
Modelsmodel checking for interference
modelling mutual exclusion
Practicethread interference in shared Java objects
mutual exclusion in Java (synchronized
objects/methods).