0% found this document useful (0 votes)
172 views

Concurrency State Models Java Programs

This document discusses concurrency, concurrent programming, and modeling concurrent systems. It provides an introduction to modeling concurrent systems using state machines and labeled transition systems. It then discusses using the LTSA tool to model and analyze a cruise control system as an example. The document also mentions that Java is used for examples and exercises due to its widespread availability and concurrency features. The overall objective of the course is to provide an understanding of concepts, models, and practices for designing concurrent software.

Uploaded by

japfx
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
172 views

Concurrency State Models Java Programs

This document discusses concurrency, concurrent programming, and modeling concurrent systems. It provides an introduction to modeling concurrent systems using state machines and labeled transition systems. It then discusses using the LTSA tool to model and analyze a cruise control system as an example. The document also mentions that Java is used for examples and exercises due to its widespread availability and concurrency features. The overall objective of the course is to provide an understanding of concepts, models, and practices for designing concurrent software.

Uploaded by

japfx
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 56

See discussions, stats, and author profiles for this publication at: https://www.researchgate.

net/publication/236896079

Concurrency: State Models & Java Programs

Book · January 2006

CITATIONS READS

760 7,785

2 authors:

Jeff Magee Jeff Kramer


Imperial College London Imperial College London
210 PUBLICATIONS   13,804 CITATIONS    379 PUBLICATIONS   19,099 CITATIONS   

SEE PROFILE SEE PROFILE

All content following this page was uploaded by Jeff Kramer on 06 May 2014.

The user has requested enhancement of the downloaded file.


Concurrency What is a Concurrent Program? Why Concurrent Programming?

State Models and Java Programs  Performance gain from multiprocessing hardware
A sequential program has a
single thread of control.  parallelism.

 Increased application throughput


 an I/O call need only block one thread.
A concurrent program has
multiple threads of control  Increased application responsiveness
allowing it perform multiple
 high priority thread for user requests.
computations in parallel and to
control multiple external  More appropriate structure
Jeff Magee and Jeff Kramer activities which occur at the
 for programs which interact with the environment, control
same time.
multiple activities and handle multiple events.
Concurrency: introduction 1 Concurrency: introduction 2 Concurrency: introduction 3
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Do I need to know about concurrent programming? a Cruise Control System models


When the car ignition is A model is a simplified representation of the real world.
Concurrency is widespread but error prone. switched on and the on
button is pressed, the Engineers use models to gain confidence in the adequacy
current speed is recorded and validity of a proposed design.
♦ Therac - 25 computerised radiation therapy machine and the system is enabled:
Concurrent programming errors contributed to accidents it maintains the speed of ♦ focus on an aspect of interest - concurrency
causing deaths and serious injuries.
the car at the recorded
setting. ♦ model animation to visualise a behaviour
♦ Mars Rover Pressing the brake, ♦ mechanical verification of properties (safety & progress)
Problems with interaction between concurrent tasks accelerator or off button
caused periodic software resets reducing availability for disables the system.
Pressing resume re-enables
Models are described using state machines, known as
exploration. buttons
the system. Labelled Transition Systems LTS. These are described
♦ Is the system safe? textually as finite state processes (FSP) and displayed
♦ Would testing be sufficient to discover all errors? and analysed by the LTSA analysis tool.
Concurrency: introduction 4 Concurrency: introduction 5 Concurrency: introduction 6
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
modeling the Cruise Control System programming practice in Java course objective
LTSA Animator to step through Java is
system actions and events. This course is intended to provide a sound
♦ widely available, generally accepted and portable
engineOn
understanding of the concepts, models and practice
♦ provides sound set of concurrency features involved in designing concurrent software.
0 1 Hence Java is used for all the illustrative examples, the
speed The emphasis on principles and concepts provides a
demonstrations and the exercises. Later chapters will
thorough understanding of both the problems and the
engineOff LTS of the process explain how to construct Java programs such as the
that monitors speed. solution techniques. Modeling provides insight into
Cruise Control System.
concurrent behavior and aids reasoning about particular
designs. Concurrent programming in Java provides the
Later chapters will explain how
“Toy” problems are also used as they programming practice and experience.
to construct models such as this
so as to perform animation and crystallize particular aspects of
verification. concurrent programming problems!
Concurrency: introduction 7 Concurrency: introduction 8 Concurrency: introduction 9
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Course Outline Web based course material Book

♦ Processes and Threads


Concurrency:
♦ Concurrent Execution
http://www.doc.ic.ac.uk/~jnm/book/
State Models &
♦ Shared Objects & Interference
Concepts  Java examples and demonstration programs Java Programs

♦ Monitors & Condition Synchronization Models  State models for the examples Jeff Magee &
 Labelled Transition System Analyser (LTSA) for Jeff Kramer
♦ Deadlock Practice modeling concurrency, model animation and model
♦ Safety and Liveness Properties WILEY
property checking.
♦ Model-based Design
♦ Dynamic systems ♦Concurrent Software Architectures
♦ Message Passing ♦Timed Systems
Concurrency: introduction 10 Concurrency: introduction 11 Concurrency: introduction 12
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Summary

 Concepts
 we adopt a model-based approach for the design and
construction of concurrent programs

 Models
 we use finite state models to represent concurrent behavior.

 Practice
 we use Java for constructing concurrent programs.

Examples are used to illustrate the concepts, models and


demonstration programs.
Concurrency: introduction 13
©Magee/Kramer
Chapter 2 concurrent processes processes and threads

We structure complex systems as Concept of a process as


Processes & Threads sets of simpler activities, each a sequence of actions. Concepts: processes - units of sequential execution.
represented as a sequential process.
Processes can overlap or be
concurrent, so as to reflect the
Models: finite state processes (FSP)
concurrency inherent in the physical to model processes as sequences of actions.
Model processes as
world, or to offload time-consuming labelled transition systems (LTS)
finite state machines.
tasks, or to manage communications or to analyse, display and animate behavior.
other devices.
Practice: Java threads
Designing concurrent software can be
complex and error prone. A rigorous Program processes as
engineering approach is essential. threads in Java.
Concurrency: processes & threads 1 Concurrency: processes & threads 2 Concurrency: processes & threads 3
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

2.1 Modeling Processes modeling processes FSP - action prefix

Models are described using state machines, If x is an action and P a process then (x-> P)
A process is the execution of a sequential program. It is
known as Labelled Transition Systems LTS. modeled as a finite state machine which transits from describes a process that initially engages in the action
These are described textually as finite state state to state by executing a sequence of atomic actions. x and then behaves exactly as described by P.
processes (FSP) and displayed and analysed by on
the LTSA analysis tool.
a light switch
ONESHOT = (once -> STOP). ONESHOT state
machine
♦ LTS - graphical form
once
0 1 LTS
(terminating process)
♦ FSP - algebraic form 0 1
off
a sequence of
off
on on
off
on
off
 ………. actions or trace Convention: actions begin with lowercase letters
PROCESSES begin with uppercase letters
Concurrency: processes & threads 4 Concurrency: processes & threads 5 Concurrency: processes & threads 6
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
FSP - action prefix & recursion animation using LTSA FSP - action prefix

Repetitive behaviour uses recursion: on The LTSA animator can be FSP model of a traffic light :
used to produce a trace. TRAFFICLIGHT = (red->orange->green->orange
SWITCH = OFF,
0 1 Ticked actions are eligible -> TRAFFICLIGHT).
OFF = (on -> ON),
ON = (off-> OFF). for selection.
LTS generated using LTSA:
off
In the LTS, the last action is
red orange green
Substituting to get a more succinct definition: highlighted in red.
SWITCH = OFF,
on
0 1 2 3
OFF = (on ->(off->OFF)).
0 1
And again: Trace: orange

SWITCH = (on->off->SWITCH). off


orange
red green
orange
red
orange
green …
Concurrency: processes & threads 7 Concurrency: processes & threads 8 Concurrency: processes & threads 9
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

FSP - choice FSP - choice Non-deterministic choice

FSP model of a drinks machine : Process (x-> P | x -> Q) describes a process which
If x and y are actions then (x-> P | y-> Q) DRINKS = (red->coffee->DRINKS engages in x and then behaves as either P or Q.
describes a process which initially engages in either of |blue->tea->DRINKS
the actions x or y. After the first action has ). COIN = (toss->HEADS|toss->TAILS),
occurred, the subsequent behavior is described by P if blue
HEADS= (heads->COIN), toss
the first action was x and Q if the first action was y. LTS generated using LTSA: TAILS= (tails->COIN).
red
toss

Tossing a
Who or what makes the choice? 0 1 2 coin. 0 1 2
Is there a difference between input and
output actions? Possible traces? coffee
Possible traces?
heads

tea
Concurrency: processes & threads 10 Concurrency: processes & threads 11 Concurrency: processes & threads tails 12
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Modeling failure FSP - indexed processes and actions FSP - constant & range declaration
in.1.1
How do we model an unreliable communication channel Single slot buffer that inputs a value in the range 0 to 3
index expressions to in.1.0
which accepts in actions and if a failure occurs produces and then outputs that value: in.0.1
model calculation:
no output, otherwise performs an out action? BUFF = (in[i:0..3]->out[i]-> BUFF). in.0.0

equivalent to
Use non-determinism... in
BUFF = (in[0]->out[0]->BUFF 0 1 2 3
|in[1]->out[1]->BUFF
|in[2]->out[2]->BUFF out.0
0 1 const N = 1
in |in[3]->out[3]->BUFF
range T = 0..N
). out.1
CHAN = (in->CHAN range R = 0..2*N
|in->out->CHAN out or using a process parameter with default value: out.2

). BUFF(N=3) = (in[i:0..N]->out[i]-> BUFF). SUM = (in[a:T][b:T]->TOTAL[a+b]),


TOTAL[s:R] = (out[s]->SUM).
Concurrency: processes & threads 13 Concurrency: processes & threads 14 Concurrency: processes & threads 15
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

FSP - guarded actions FSP - guarded actions FSP - guarded actions


A countdown timer which beeps after N ticks, or can be
The choice (when B x -> P | y -> Q) means that
when the guard B is true then the actions x and y are stopped. What is the following FSP process equivalent to?
both eligible to be chosen, otherwise if B is false then COUNTDOWN (N=3) = (start->COUNTDOWN[N]),
the action x cannot be chosen. COUNTDOWN[i:0..N] = const False = 0
(when(i>0) tick->COUNTDOWN[i-1] P = (when (False) doanything->P).
COUNT (N=3) = COUNT[0], |when(i==0)beep->STOP
stop
COUNT[i:0..N] = (when(i<N) inc->COUNT[i+1] |stop->STOP
Answer:
|when(i>0) dec->COUNT[i-1] ). stop

). stop STOP
inc inc inc stop
start tick tick tick beep

0 1 2 3
0 1 2 3 4 5
dec dec dec
Concurrency: processes & threads 16 Concurrency: processes & threads 17 Concurrency: processes & threads 18
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
FSP - process alphabets 2.2 Implementing processes Implementing processes - the OS view

The alphabet of a process is the set of actions in Modeling processes as O S Proc ess
which it can engage. finite state machines
using FSP/LTS. D ata C ode D escriptor

Alphabet extension can be used to extend the implicit Stack Stack Stack
alphabet of a process:
Implementing threads D escriptor D escriptor D escriptor
WRITER = (write[1]->write[3]->WRITER) in Java.
T hread 1 T hread 2 T hread n
+{write[0..3]}.
A (heavyweight) process in an operating system is represented by its code,
Alphabet of WRITER is the set {write[0..3]} Note: to avoid confusion, we use the term process when referring to data and the state of the machine registers, given in a descriptor. In order to
(we make use of alphabet extensions in later chapters) the models, and thread when referring to the implementation in Java. support multiple (lightweight) threads of control, it has multiple stacks, one
for each thread.
Concurrency: processes & threads 19 Concurrency: processes & threads 20 Concurrency: processes & threads 21
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

threads in Java threads in Java thread life-cycle in Java

A Thread class manages a single sequential thread of control. Since Java does not permit multiple inheritance, we often An overview of the life-cycle of a thread as state transitions:
Threads may be created and deleted dynamically. implement the run() method in a class not derived from Thread but
new Thread() start() causes the thread to call its
from the interface Runnable.
run() method.
The Thread class executes instructions from its method target
Thread Runnable Thread start()
run(). The actual code executed depends on the Created Alive
implementation provided for run() in a derived class. run() public interface Runnable {
run()
public abstract void run(); stop(), or
class MyThread extends Thread { } st
op run() returns
public void run() { ()
//...... MyRun class MyRun implements Runnable{
MyThread } public void run() { Terminated
} run() The predicate isAlive() can be
//.....
run() } used to test if a thread has been started but
Thread x = new MyThread(); } not terminated. Once terminated, it cannot
be restarted (cf. mortals).
Thread x = new Thread(new MyRun());
Concurrency: processes & threads 22 Concurrency: processes & threads 23 Concurrency: processes & threads 24
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
thread alive states in Java Java thread lifecycle - an FSP specification Java thread lifecycle - an FSP specification
start yield
Once started, an alive thread has a number of substates : THREAD = CREATED,
sleep
CREATED = (start ->RUNNING stop suspend resume
start() |stop ->TERMINATED),
Running s
su lee RUNNING = ({suspend,sleep}->NON_RUNNABLE
sp p
en () |yield ->RUNNABLE 0 1 2 3 4
d( run
) |{stop,end} ->TERMINATED
yield() dispatch |run ->RUNNING),
RUNNABLE = (suspend ->NON_RUNNABLE end, run, stop suspend
suspend() end
|dispatch ->RUNNING dispatch are
Runnable Non-Runnable
resume() |stop ->TERMINATED), not methods of stop dispatch

NON_RUNNABLE = (resume ->RUNNABLE class Thread.


stop(), or |stop ->TERMINATED), stop
wait() also makes a Thread Non-Runnable, and run() returns States 0 to 4 correspond to CREATED, TERMINATED, RUNNING,
notify() Runnable (used in later chapters).
TERMINATED = STOP.
NON-RUNNABLE, and RUNNABLE respectively.
Concurrency: processes & threads 25 Concurrency: processes & threads 26 Concurrency: processes & threads 27
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

CountDown timer example CountDown timer - class diagram CountDown class


public class CountDown extends Applet
COUNTDOWN (N=3) = (begin->COUNTDOWN[N]), Applet Runnable The class NumberCanvas implements Runnable {
COUNTDOWN[i:0..N] = provides the display canvas. Thread counter; int i;
(when(i>0) tick->COUNTDOWN[i-1] final static int N = 10;
|when(i==0)beep->STOP CountDown AudioClip beepSound, tickSound;
|end->STOP init() counter target NumberCanvas display;
Thread
). start()
begin()
end()
stop() public void init() {...}
display
run() NumberCanvas public void begin() {...}
tick() public void end() {...}
Implementation in Java? beep() setvalue()
public void run() {...}
private void tick() {...}
The class CountDown derives from Applet and contains the
private void beep() {...}
implementation of the run() method which is required by Thread.
}
Concurrency: processes & threads 28 Concurrency: processes & threads 29 Concurrency: processes & threads 30
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
CountDown class - start(), stop() and run() Summary
COUNTDOWN Model  Concepts
public void begin() { begin ->
counter = new Thread(this);  process - unit of concurrency, execution of a program
i = N; counter.start();
 Models
}
public void end() { end ->  LTS to model processes as state machines - sequences of
counter = null; atomic actions
}  FSP to specify processes using prefix “->”, choice ” | ”
public void run() { COUNTDOWN[i] process and recursion.
while(true) { recursion as a while loop
if (counter == null) return; STOP  Practice
if (i>0) { tick(); --i; } when(i>0) tick -> CD[i-1]
when(i==0)beep -> STOP
 Java threads to implement processes.
if (i==0) { beep(); return;}
}  Thread lifecycle - created, running, runnable, non-
} STOP when run() returns
runnable, terminated.
Concurrency: processes & threads 31 Concurrency: processes & threads 32
©Magee/Kramer ©Magee/Kramer
Chapter 3 Concurrent execution Definitions

Concepts: processes - concurrent execution  Concurrency


Concurrent Execution and interleaving.  Logically simultaneous processing. A
process interaction. Does not imply multiple processing
B
elements (PEs). Requires
interleaved execution on a single PE. C
Models: parallel composition of asynchronous processes
- interleaving  Parallelism
Time
interaction - shared actions  Physically simultaneous processing.
process labeling, and action relabeling and hiding Involves multiple PEs and/or
structure diagrams independent device operations.

Both concurrency and parallelism require controlled access to


Practice: Multithreaded Java programs shared resources . We use the terms parallel and concurrent
interchangeably and generally do not distinguish between real and
pseudo-parallel execution.
Concurrency: concurrent execution 1 Concurrency: concurrent execution 2 Concurrency: concurrent execution 3
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

3.1 Modeling Concurrency parallel composition - action interleaving parallel composition - action interleaving
scratch
 How should we model process execution speed? think talk
If P and Q are processes then (P||Q) represents the ITCH CONVERSE
 arbitrary speed
concurrent execution of P and Q. The operator || is 0 1 0 1 2
(we abstract away time) the parallel composition operator. 2 states scratch
3 states

 How do we model concurrency?


ITCH = (scratch->STOP). scratch
 arbitrary relative order of actions from different processes CONVERSE = (think->talk->STOP).
(interleaving but preservation of each process order )
think talk scratch
||CONVERSE_ITCH = (ITCH || CONVERSE). CONVERSE_ITCH
 What is the result? 0 1 2 3 4 5
talk
think scratch Possible traces as
 provides a general model independent of scheduling (0,0) (0,1) (0,2) (1,2) (1,1) (1,0)
scratch
think talk a result of action talk think
(asynchronous model of execution)
think
scratch talk interleaving.
from ITCH 2 x 3 states
Concurrency: concurrent execution 4 Concurrency: concurrent execution 5 Concurrency: concurrent execution
from CONVERSE 6
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
parallel composition - algebraic laws modeling interaction - shared actions modeling interaction - handshake

If processes in a composition have actions in common, A handshake is an action acknowledged by another:


Commutative: (P||Q) = (Q||P) these actions are said to be shared. Shared actions are
MAKERv2 = (make->ready->used->MAKERv2). 3 states
Associative: (P||(Q||R)) = ((P||Q)||R) the way that process interaction is modeled. While
USERv2 = (ready->use->used ->USERv2). 3 states
= (P||Q||R). unshared actions may be arbitrarily interleaved, a
shared action must be executed at the same time by all
||MAKER_USERv2 = (MAKERv2 || USERv2). 3 x 3
processes that participate in the shared action.
Clock radio example: states?

CLOCK = (tick->CLOCK). MAKER = (make->ready->MAKER). MAKER make ready use


RADIO = (on->off->RADIO). USER = (ready->use->USER). synchronizes 4 states
with USER 0 1 2 3 Interaction
||CLOCK_RADIO = (CLOCK || RADIO). constrains
||MAKER_USER = (MAKER || USER). when ready.
the overall
LTS? Traces? Number of states? LTS? Traces? Number of states? used behaviour.
Concurrency: concurrent execution 7 Concurrency: concurrent execution 8 Concurrency: concurrent execution 9
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

modeling interaction - multiple processes composite processes process labeling

Multi-party synchronization: A composite process is a parallel composition of primitive a:P prefixes each action label in the alphabet of P with a.
MAKE_A = (makeA->ready->used->MAKE_A). processes. These composite processes can be used in the
MAKE_B = (makeB->ready->used->MAKE_B). definition of further compositions. Two instances of a switch process:
ASSEMBLE = (ready->assemble->used->ASSEMBLE). SWITCH = (on->off->SWITCH).
||MAKERS = (MAKE_A || MAKE_B).
||FACTORY = (MAKE_A || MAKE_B || ASSEMBLE). ||TWO_SWITCH = (a:SWITCH || b:SWITCH).
a.on b.on
makeA ||FACTORY = (MAKERS || ASSEMBLE).
a:SWITCH b:SWITCH
0 1 0 1
Substituting the definition for MAKERS in FACTORY and applying the
makeB makeA ready assemble commutative and associative laws for parallel composition results in a.off b.off
the original definition for FACTORY in terms of primitive processes.
0 1 2 3 4 5 An array of instances of the switch process:
||FACTORY = (MAKE_A || MAKE_B || ASSEMBLE). ||SWITCHES(N=3) = (forall[i:1..N] s[i]:SWITCH).
||SWITCHES(N=3) = (s[i:1..N]:SWITCH).
Concurrency: concurrent execution makeB 10 Concurrency: concurrent execution 11 Concurrency: concurrent execution 12
used ©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
process labeling by a set of prefix labels process prefix labels for shared resources action relabeling
a.acquire a.use b.acquire b.use
a:USER
{a1,..,ax}::P replaces every action label n in the b:USER
Relabeling functions are applied to processes to change
0 1 2 0 1 2
alphabet of P with the labels a1.n,…,ax.n. Further, the names of action labels. The general form of the
every transition (n->X) in the definition of P is relabeling function is:
a.release b.release
replaced with the transitions ({a1.n,…,ax.n} ->X). b.acquire /{newlabel_1/oldlabel_1,… newlabel_n/oldlabel_n}.
How does the model ensure a.acquire
that the user that acquires {a,b}::RESOURCE
the resource is the one to 0 1
Process prefixing is useful for modeling shared resources: release it? a.acquire
Relabeling to ensure that composed
a.release
RESOURCE = (acquire->release->RESOURCE). b.release processes synchronize on particular actions.
b.acquire b.use a.use
USER = (acquire->use->release->USER). RESOURCE_SHARE
CLIENT = (call->wait->continue->CLIENT).
0 1 2 3 4
||RESOURCE_SHARE = (a:USER || b:USER SERVER = (request->service->reply->SERVER).
|| {a,b}::RESOURCE).
b.release

Concurrency: concurrent execution 13 Concurrency: concurrent execution 14 Concurrency: concurrent execution 15


©Magee/Kramer a.release ©Magee/Kramer ©Magee/Kramer

action relabeling action relabeling - prefix labels action hiding - abstraction to reduce complexity

||CLIENT_SERVER = (CLIENT || SERVER) An alternative formulation of the client server system is


/{call/request, reply/wait}. When applied to a process P, the hiding operator \{a1..ax}
described below using qualified or prefixed labels: removes the action names a1..ax from the alphabet of P
and makes these concealed actions "silent". These silent
CLIENT
call reply
SERVER
call service SERVERv2 = (accept.request actions are labeled tau. Silent actions in different
0 1 2 0 1 2 ->service->accept.reply->SERVERv2). processes are not shared.
CLIENTv2 = (call.request
continue reply ->call.reply->continue->CLIENTv2).
Sometimes it is more convenient to specify the set of
labels to be exposed....
CLIENT_SERVER
call service reply ||CLIENT_SERVERv2 = (CLIENTv2 || SERVERv2)
0 1 2 3 /{call/accept}. When applied to a process P, the interface
operator @{a1..ax} hides all actions in the
continue
alphabet of P not labeled in the set a1..ax.
Concurrency: concurrent execution 16 Concurrency: concurrent execution 17 Concurrency: concurrent execution 18
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
action hiding structure diagrams structure diagrams
The following definitions are equivalent: We use structure
P a TWOBUFF
USER = (acquire->use->release->USER) Process P with diagrams to capture the
b structure of a model
\{use}. alphabet {a,b}. in
a:BUFF
a.out
b:BUFF
out
expressed by the static in out in out
USER = (acquire->use->release->USER) m combinators:
P a b Q Parallel Composition
@{acquire,release}. c d
parallel composition,
c
x
x x
(P||Q) / {m/a,m/b,c/d} relabeling and hiding.
acquire tau
Minimization removes hidden
tau actions to produce an range T = 0..3
0 1 2 LTS with equivalent
observable behavior. S Composite process BUFF = (in[i:T]->out[i]->BUFF).
acquire x P a Q y ||S = (P||Q) @ {x,y} ||TWOBUF = ?
release
0 1

release
Concurrency: concurrent execution 19 Concurrency: concurrent execution 20 Concurrency: concurrent execution 21
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

structure diagrams structure diagrams - resource sharing 3.2 Multi-threaded Programs in Java

Structure diagram for CLIENT_SERVER ? PRINTER_SHARE Concurrency in Java occurs when more than one thread is alive.
a:USER ThreadDemo has two threads which rotate displays.
CLIENT call request printer
call SERVER
printer:
continue reply service RESOURCE
wait reply
acquire
b:USER release
printer
Structure diagram for CLIENT_SERVERv2 ?

CLIENTv2 call accept


call SERVERv2 RESOURCE = (acquire->release->RESOURCE).
USER = (printer.acquire->use
continue service ->printer.release->USER).

||PRINTER_SHARE
= (a:USER||b:USER||{a,b}::printer:RESOURCE).
Concurrency: concurrent execution 22 Concurrency: concurrent execution 23 Concurrency: concurrent execution 24
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
ThreadDemo model ThreadDemo implementation in Java - class diagram Rotator class
ThreadDemo creates two ThreadPanel displays when initialized.
THREAD_DEMO ThreadPanel manages the display and control buttons, and delegates calls to class Rotator implements Runnable {
a.run b.run rotate() to DisplayThread. Rotator implements the runnable interface.
a.pause b.pause
public void run() {
a:ROTATOR b:ROTATOR try {
a.rotate stop b.rotate Applet Panel
while(true) ThreadPanel.rotate();
GraphicCanvas
} catch(InterruptedException e) {}
A,B display }
ThreadDemo ThreadPanel
ROTATOR = PAUSED, }
Interpret init() rotate() thread Thread
PAUSED = (run->RUN | pause->PAUSED run, start()
start()
|interrupt->STOP), pause, stop() stop() Rotator implements the runnable interface, calling
RUN = (pause->PAUSED |{run,rotate}->RUN interrupt DisplayThread
ThreadPanel.rotate() to move the display.
|interrupt->STOP). as inputs, rotate()
rotate as Runnable run()finishes if an exception is raised by Thread.interrupt().
||THREAD_DEMO = (a:ROTATOR || b:ROTATOR)
/{stop/{a,b}.interrupt}. an output. target
Rotator

Concurrency: concurrent execution 25 Concurrency: concurrent execution run() 26 Concurrency: concurrent execution 27
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

ThreadPanel class ThreadPanel ThreadDemo class Summary


manages the display
public class ThreadPanel extends Panel { and control buttons for public class ThreadDemo extends Applet {  Concepts
a thread. ThreadPanel A; ThreadPanel B;
// construct display with title and segment color c  concurrent processes and process interaction
public ThreadPanel(String title, Color c) {…} public void init() {
A = new ThreadPanel("Thread A",Color.blue);  Models
// rotate display of currently running thread 6 degrees
Calls to rotate() B = new ThreadPanel("Thread B",Color.blue);
// return value not used in this example  Asynchronous (arbitrary speed) & interleaving (arbitrary order).
are delegated to add(A); add(B);
public static boolean rotate() ThreadDemo creates two
DisplayThread. }  Parallel composition as a finite state process with action
throws InterruptedException {…} ThreadPanel displays
public void start() { interleaving.
// create a new thread with target r and start it running when initialized and two
A.start(new Rotator()); threads when started.  Process interaction by shared actions.
public void start(Runnable r) {
B.start(new Rotator());
thread = new DisplayThread(canvas,r,…);  Process labeling and action relabeling and hiding.
}
thread.start(); Threads are created by
} the start() method, public void stop() { ThreadPanel is used  Structure diagrams
and terminated by the A.stop(); extensively in later
// stop the thread using Thread.interrupt()
B.stop();
 Practice
public void stop() {thread.interrupt();} stop() method. demonstration programs.
} Concurrency: concurrent execution
}  Multiple threads in Java.
28 Concurrency:
} concurrent execution 29 Concurrency: concurrent execution 30
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Chapter 4 Shared Objects & Mutual Exclusion 4.1 Interference

Shared Objects & Concepts: process interference.


Ornamental garden problem:

mutual exclusion. People enter an ornamental garden through either of two


Mutual Exclusion turnstiles. Management wish to know how many are in the
garden at any time.
Models: model checking for interference Garden
modeling mutual exclusion

Practice: thread interference in shared Java objects West people East


mutual exclusion in Java Turnstile Turnstile
(synchronized objects/methods).

The concurrent program consists of two concurrent


threads and a shared counter object.
Concurrency: shared objects & mutual exclusion 1 Concurrency: shared objects & mutual exclusion 2 Concurrency: shared objects & mutual exclusion 3
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

ornamental garden Program - class diagram ornamental garden program Turnstile class

Applet Thread The Counter object and Turnstile threads are created by the class Turnstile extends Thread {
NumberCanvas display;
go() method of the Garden applet: Counter people; The run()
east,west people private void go() { Turnstile(NumberCanvas n,Counter c) method exits
Garden Turnstile Counter and the thread
counter = new Counter(counterD); { display = n; people = c; }
init() run() increment() terminates after
west = new Turnstile(westD,counter); public void run() { Garden.MAX
go()
east = new Turnstile(eastD,counter); try{ visitors have
eastD, display display west.start(); display.setvalue(0); entered.
westD, NumberCanvas east.start(); for (int i=1;i<=Garden.MAX;i++){
counterD Thread.sleep(500); //0.5 second between arrivals
setvalue() } display.setvalue(i);
people.increment();
The Turnstile thread simulates the periodic arrival of a visitor to
Note that counterD, westD and eastD are objects of }
the garden every second by sleeping for a second and then invoking NumberCanvas used in chapter 2. } catch (InterruptedException e) {}
the increment() method of the counter object. }
Concurrency: shared objects & mutual exclusion 4 Concurrency: shared objects & mutual exclusion 5 }
Concurrency: shared objects & mutual exclusion 6
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Counter class ornamental garden program - display concurrent method activation

class Counter { Java method activations are not atomic - thread


int value=0; Hardware interrupts can occur objects east and west may be executing the code for
NumberCanvas display; at arbitrary times.
the increment method at the same time.
Counter(NumberCanvas n) { The counter simulates a
display=n; hardware interrupt during an
display.setvalue(value); increment(), between west east
shared code
} reading and writing to the PC PC
void increment() { shared counter value. increment:
int temp = value; //read value Interrupt randomly calls program
Simulate.HWinterrupt(); Thread.yield() to force counter program
read value
value=temp+1; //write value a thread switch. After the East and West turnstile threads have each counter
display.setvalue(value); incremented its counter 20 times, the garden people
} write value + 1
counter is not the sum of the counts displayed. Counter
}
increments have been lost. Why?
Concurrency: shared objects & mutual exclusion 7 Concurrency: shared objects & mutual exclusion 8 Concurrency: shared objects & mutual exclusion 9
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

ornamental garden Model ornamental garden model checking for errors - animation
go const N = 4
end
go GARDEN range T = 0..N The alphabet of Scenario checking
end
arrive set VarAlpha = { value.{read[T],write[T]} } process VAR is - use animation to
value
declared explicitly
east: value:VAR VAR = VAR[0], as a set constant, produce a trace.
TURNSTILE display
VAR[u:T] = (read[u] ->VAR[u]
read VarAlpha.
go |write[v:T]->VAR[v]).
end write
arrive value
TURNSTILE = (go -> RUN), The alphabet of Is this trace
RUN = (arrive-> INCREMENT TURNSTILE is
west: |end -> TURNSTILE), correct?
TURNSTILE extended with
INCREMENT = (value.read[x:T]
VarAlpha to ensure
Process VAR models read and write access to the shared -> value.write[x+1]->RUN
)+VarAlpha. no unintended free
counter value. actions in VAR ie. all
||GARDEN = (east:TURNSTILE || west:TURNSTILE actions in VAR must
Increment is modeled inside TURNSTILE since Java method || { east,west,display} ::value:VAR)
be controlled by a
activations are not atomic i.e. thread objects east and west /{ go /{ east,west} .go,
TURNSTILE.
may interleave their read and write actions. end/{ east,west} .end} .
Concurrency: shared objects & mutual exclusion 10 Concurrency: shared objects & mutual exclusion 11 Concurrency: shared objects & mutual exclusion 12
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
checking for errors - exhaustive analysis ornamental garden model - checking for errors Interference and Mutual Exclusion

Exhaustive checking - compose the model with a TEST ||TESTGARDEN = (GARDEN || TEST).
process which sums the arrivals and checks against the Use LTSA to perform an exhaustive search for ERROR. Destructive update, caused by the arbitrary
display value: interleaving of read and write actions, is termed
Trace to property violation in TEST:
TEST = TEST[0], go interference.
TEST[v:T] = east.arrive
(when (v<N){east.arrive,west.arrive}->TEST[v+1] east.value.read.0
|end->CHECK[v] west.arrive Interference bugs are extremely difficult to
), west.value.read.0 locate. The general solution is to give methods
CHECK[v:T] = Like STOP, ERROR is east.value.write.1 LTSA produces
(display.value.read[u:T] -> mutually exclusive access to shared objects.
a predefined FSP west.value.write.1 the shortest
(when (u==v) right -> TEST[v] local process (state), end path to reach
Mutual exclusion can be modeled as atomic
|when (u!=v) wrong -> ERROR numbered -1 in the display.value.read.1 ERROR. actions.
) equivalent LTS. wrong
)+{display.VarAlpha}.
Concurrency: shared objects & mutual exclusion 13 Concurrency: shared objects & mutual exclusion 14 Concurrency: shared objects & mutual exclusion 15
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

4.2 Mutual exclusion in Java mutual exclusion - the ornamental garden Java synchronized statement

Concurrent activations of a method in Java can be made Access to an object may also be made mutually exclusive by using the
synchronized statement:
mutually exclusive by prefixing the method with the keyword
synchronized. synchronized (object) { statements }
A less elegant way to correct the example would be to modify the
We correct COUNTER class by deriving a class from it and Turnstile.run() method:
making the increment method synchronized: synchronized(counter) {counter.increment();}
class SynchronizedCounter extends Counter {
SynchronizedCounter(NumberCanvas n) Why is this “less elegant”?
{super(n);} Java associates a lock with every object. The Java compiler inserts
synchronized void increment() { code to acquire the lock before executing the body of the
super.increment(); synchronized method and code to release the lock before the To ensure mutually exclusive access to an object,
} method returns. Concurrent threads are blocked until the lock is all object methods should be synchronized.
} released.
Concurrency: shared objects & mutual exclusion 16 Concurrency: shared objects & mutual exclusion 17 Concurrency: shared objects & mutual exclusion 18
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
4.3 Modeling mutual exclusion Revised ornamental garden model - checking for errors COUNTER: Abstraction using action hiding
To add locking to our model, define a LOCK, compose it with A sample animation
go To model shared objects
the shared VAR in the garden, and modify the alphabet set : east.arrive directly in terms of their
execution trace east.value.acquire const N = 4
synchronized methods, we
LOCK = (acquire->release->LOCK). east.value.read.0 range T = 0..N
can abstract the details by
||LOCKVAR = (LOCK || VAR). east.value.write.1 VAR = VAR[0], hiding.
set VarAlpha = {value.{read[T],write[T], east.value.release VAR[u:T] = ( read[u]->VAR[u]
west.arrive For SynchronizedCounter
acquire, release}} | write[v:T]->VAR[v]).
west.value.acquire we hide read, write,
Modify TURNSTILE to acquire and release the lock: west.value.read.1 LOCK = (acquire->release->LOCK). acquire, release actions.
TURNSTILE = (go -> RUN), west.value.write.2 INCREMENT = (acquire->read[x:T]
RUN = (arrive-> INCREMENT west.value.release -> (when (x<N) write[x+1]
|end -> TURNSTILE), end ->release->increment->INCREMENT
INCREMENT = (value.acquire display.value.read.2 )
-> value.read[x:T]->value.write[x+1] right )+{read[T],write[T]}.
-> value.release->RUN
)+VarAlpha. Use TEST and LTSA to perform an exhaustive check. ||COUNTER = (INCREMENT||LOCK||VAR)@{increment}.
Concurrency: shared objects & mutual exclusion 19 Concurrency: shared objects & mutual exclusion Is TEST satisfied? 20 Concurrency: shared objects & mutual exclusion 21
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

COUNTER: Abstraction using action hiding Summary

Minimized  Concepts
increment increment increment increment
LTS:
 process interference
0 1 2 3 4
 mutual exclusion

We can give a more abstract, simpler description of a  Models


COUNTER which generates the same LTS:  model checking for interference
COUNTER = COUNTER[0]  modeling mutual exclusion
COUNTER[v:T] = (when (v<N) increment -> COUNTER[v+1]).
 Practice
 thread interference in shared Java objects
This therefore exhibits “equivalent” behavior i.e. has the
 mutual exclusion in Java (synchronized objects/methods).
same observable behavior.

Concurrency: shared objects & mutual exclusion 22 Concurrency: shared objects & mutual exclusion 23
©Magee/Kramer ©Magee/Kramer
Chapter 5 monitors & condition synchronization 5.1 Condition synchronization

Monitors & Concepts: monitors:


encapsulated data + access procedures
Condition Synchronization mutual exclusion + condition synchronization
single access procedure active in the monitor
nested monitors

Models: guarded actions

Practice: private data and synchronized methods (exclusion). A controller is required for a carpark, which only permits
wait(), notify() and notifyAll() for condition synch. cars to enter when the carpark is not full and does not
single thread active in the monitor at a time permit cars to leave when there are no cars in the carpark.
Car arrival and departure are simulated by separate threads.
Concurrency: monitors & condition synchronization 1 Concurrency: monitors & condition synchronization 2 Concurrency: monitors & condition synchronization 3
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

carpark model carpark model carpark program

♦ Events or actions of interest? CARPARKCONTROL(N=4) = SPACES[N], ♦ Model - all entities are processes interacting by actions
SPACES[i:0..N] = (when(i>0) arrive->SPACES[i-1]
arrive and depart |when(i<N) depart->SPACES[i+1] ♦ Program - need to identify threads and monitors
♦ Identify processes. ). ♦thread - active entity which initiates (output) actions
arrivals, departures and carpark control ARRIVALS = (arrive->ARRIVALS). ♦monitor - passive entity which responds to (input) actions.
♦ Define each process and interactions (structure). DEPARTURES = (depart->DEPARTURES). For the carpark?
||CARPARK = CARPARK
CARPARK (ARRIVALS||CARPARKCONTROL(4)||DEPARTURES).
ARRIVALS arrive CARPARK depart DEPARTURES
ARRIVALS arrive CARPARK depart DEPARTURES CONTROL
CONTROL
Guarded actions are used to control arrive and depart.
LTS?
Concurrency: monitors & condition synchronization 4 Concurrency: monitors & condition synchronization 5 Concurrency: monitors & condition synchronization 6
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
carpark program - class diagram carpark program carpark program - Arrivals and Departures threads
Runnable Arrivals and Departures implement Runnable, class Arrivals implements Runnable {
Applet
CarParkControl provides the control (condition synchronization). CarParkControl carpark;
arrivals,
departures Arrivals(CarParkControl c) {carpark = c;}
CarPark ThreadPanel Arrivals carpark Instances of these are created by the start() method of the
CarPark applet : public void run() {
carDisplay try {
Departures while(true) { Similarly Departures
public void start() { which calls
ThreadPanel.rotate(330);
CarParkControl
CarParkControl c = carpark.arrive(); carpark.depart().
arrive() new DisplayCarPark(carDisplay,Places); ThreadPanel.rotate(30);
depart() arrivals.start(new Arrivals(c)); }
We have omitted departures.start(new Departures(c)); } catch (InterruptedException e){}
disp DisplayThread and } }
CarParkCanvas DisplayCarPark GraphicCanvas }
threads managed by
ThreadPanel.
How do we implement the control of CarParkControl?
Concurrency: monitors & condition synchronization 7 Concurrency: monitors & condition synchronization 8 Concurrency: monitors & condition synchronization 9
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Carpark program - CarParkControl monitor condition synchronization in Java condition synchronization in Java

class CarParkControl { Java provides a thread wait set per monitor (actually per object) We refer to a thread entering a monitor when it acquires the mutual
mutual exclusion with the following methods:
protected int spaces; by synch methods exclusion lock associated with the monitor and exiting the monitor
protected int capacity; public final void notify() when it releases the lock.
CarParkControl(int n) condition Wakes up a single thread that is waiting on this object's set. Wait() - causes the thread to exit the monitor,
{capacity = spaces = n;} synchronization? permitting other threads to enter the monitor.
public final void notifyAll()
synchronized void arrive() { Wakes up all threads that are waiting on this object's set.
block if full?
… --spaces; … Monitor
(spaces==0) public final void wait()
} Thread A Thread B
throws InterruptedException data
synchronized void depart() { block if empty? Waits to be notified by another thread. The waiting thread wait()
… ++spaces; … (spaces==N) releases the synchronization lock associated with the monitor. notify()
} When notified, the thread must wait to reacquire the monitor
} before resuming execution.
Concurrency: monitors & condition synchronization 10 Concurrency: monitors & condition synchronization 11 Concurrency: monitors & condition synchronization 12
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
condition synchronization in Java CarParkControl - condition synchronization models to monitors - summary
class CarParkControl {
FSP: when cond act -> NEWSTAT protected int spaces; Active entities (that initiate actions) are implemented as threads.
protected int capacity; Passive entities (that respond to actions) are implemented as monitors.
Java: public synchronized void act() CarParkControl(int n)
throws InterruptedException {capacity = spaces = n;} Each guarded action in the model of a monitor is
{ implemented as a synchronized method
synchronized void arrive() throws InterruptedException {
while (!cond) wait(); while (spaces==0) wait();
which uses a while loop and wait() to
// modify monitor data --spaces; implement the guard. The while loop condition is
notifyAll() notify(); the negation of the model guard condition.
}
}
synchronized void depart() throws InterruptedException {
The while loop is necessary to retest the condition cond to ensure that while (spaces==capacity) wait(); Changes in the state of the monitor are signaled to
cond is indeed satisfied when it re-enters the monitor. ++spaces; waiting threads using notify() or notifyAll().
notify();
notifyall() is necessary to awaken other thread(s) that may be Why is it safe to use notify()
}
waiting
Concurrency: to enter
monitors the monitor
& condition now that the monitor data has been changed.
synchronization 13
here rather than notifyAll()14?
}Concurrency: monitors & condition synchronization Concurrency: monitors & condition synchronization 15
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

5.2 Semaphores modeling semaphores modeling semaphores


Semaphores are widely used for dealing with inter-process up up up
To ensure analyzability, we only model semaphores that
synchronization in operating systems. Semaphore s is an take a finite range of values. If this range is exceeded
integer variable that can take only non-negative values. -1 0 1 2 3
then we regard this as an ERROR. N is the initial value.
The only down(s): if s >0 then
down down down
operations const Max = 3
decrement s
permitted on range Int = 0..Max
else
up
s are up(s) block execution of the calling process SEMAPHORE(N=0) = SEMA[N],
and down(s). SEMA[v:Int] = (up->SEMA[v+1] Action down is only accepted when value v of the
Blocked up(s): if processes blocked on s then |when(v>0) down->SEMA[v-1] semaphore is greater than 0.
processes are awaken one of them ),
Action up is not guarded.
held in a else SEMA[Max+1] = ERROR.
FIFO queue. increment s Trace to a violation:
LTS? up  up  up  up
Concurrency: monitors & condition synchronization 16 Concurrency: monitors & condition synchronization 17 Concurrency: monitors & condition synchronization 18
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
semaphore demo - model semaphore demo - model semaphores in Java
p.1.mutex.down
Three processes p[1..3] use a shared semaphore mutex Semaphores are public class Semaphore {
to ensure mutually exclusive access (action critical) to passive objects, private int value;
some resource. p.2.mutex.down
therefore public Semaphore (int initial)
implemented as {value = initial;}
LOOP = (mutex.down->critical->mutex.up->LOOP).
p.3.mutex.down p.3.critical p.2.critical p.1.critical monitors. synchronized public void up() {
||SEMADEMO = (p[1..3]:LOOP ++value;
(In practice,
||{p[1..3]}::mutex:SEMAPHORE(1)). 0 1 2 3 4 5 6 notify();
semaphores are a
}
low-level mechanism
often used in synchronized public void down()
For mutual exclusion, the semaphore initial value is 1. Why? p.3.mutex.up
implementing the throws InterruptedException {
higher-level monitor while (value== 0) wait();
Is the ERROR state reachable for SEMADEMO?
p.2.mutex.up
construct.) --value;
Is a binary semaphore sufficient (i.e. Max=1) ? }
}
LTS? p.1.mutex.up
Concurrency: monitors & condition synchronization 19 Concurrency: monitors & condition synchronization 20 Concurrency: monitors & condition synchronization 21
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

SEMADEMO display SEMADEMO SEMADEMO program - revised ThreadPanel class

public class ThreadPanel extends Panel {


current What if we adjust the time that each thread spends in its // construct display with title and rotating arc color c
semaphore critical section ? public ThreadPanel(String title, Color c) {…}
value // hasSlider == true creates panel with slider
♦large resource requirement - more conflict? public ThreadPanel
thread 1 is (String title, Color c, boolean hasSlider) {…}
executing (eg. more than 67% of a rotation)? // rotate display of currently running thread 6 degrees
critical // return false when in initial color, return true when in second color
actions. ♦ small resource requirement - no conflict? public static boolean rotate()
throws InterruptedException {…}
thread 2 is (eg. less than 33% of a rotation)? // rotate display of currently running thread by degrees
blocked public static void rotate(int degrees)
waiting. throws InterruptedException {…}
Hence the time a thread spends in its critical // create a new thread with target r and start it running
thread 3 is public void start(Runnable r) {…}
executing section should be kept as short as possible. // stop the thread using Thread.interrupt()
non-critical public void stop() {…}
actions. }
Concurrency: monitors & condition synchronization 22 Concurrency: monitors & condition synchronization 23 Concurrency: monitors & condition synchronization 24
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
SEMADEMO program - MutexLoop 5.3 Bounded Buffer bounded buffer - a data-independent model
class MutexLoop implements Runnable {
Semaphore mutex; Threads and BOUNDEDBUFFER
semaphore are
MutexLoop (Semaphore sema) {mutex=sema;} PRODUCER put get
created by the BUFFER CONSUMER
public void run() { applet
try { start()
while(true) { method.
while(!ThreadPanel.rotate()); The behaviour of BOUNDEDBUFFER is independent of
mutex.down(); // get mutual exclusion the actual data values, and so can be modelled in a data-
while(ThreadPanel.rotate()); //critical actions independent manner.
mutex.up(); //release mutual exclusion A bounded buffer consists of a fixed number of slots.
}
Items are put into the buffer by a producer process and LTS: put put put put put
} catch(InterruptedException e){}
} removed by a consumer process. It can be used to smooth 0 1 2 3 4 5
} ThreadPanel.rotate() returns out transfer rates between the producer and consumer.
false while executing non-critical get get get get get
actions (dark color) and true otherwise. (see car park example)
Concurrency: monitors & condition synchronization 25 Concurrency: monitors & condition synchronization 26 Concurrency: monitors & condition synchronization 27
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

bounded buffer - a data-independent model bounded buffer program - buffer monitor bounded buffer program - producer process
public interface Buffer {…}
We separate the class Producer implements Runnable {
BUFFER(N=5) = COUNT[0], class BufferImpl implements Buffer { interface to Buffer buf;
COUNT[i:0..N] … permit an String alphabet= "abcdefghijklmnopqrstuvwxyz";
= (when (i<N) put->COUNT[i+1] public synchronized void put(Object o) alternative Producer(Buffer b) {buf = b;}
throws InterruptedException { implementation
|when (i>0) get->COUNT[i-1] while (count==size) wait(); public void run() { Similarly Consumer
buf[in] = o; ++count; in=(in+1)%size; later. try { which calls buf.get().
).
notify(); int ai = 0;
} while(true) {
PRODUCER = (put->PRODUCER). public synchronized Object get() ThreadPanel.rotate(12);
CONSUMER = (get->CONSUMER). throws InterruptedException { buf.put(new Character(alphabet.charAt(ai)));
while (count==0) wait(); ai=(ai+1) % alphabet.length();
Object o =buf[out]; ThreadPanel.rotate(348);
||BOUNDEDBUFFER = buf[out]=null; --count; out=(out+1)%size; }
notify();
(PRODUCER||BUFFER(5)||CONSUMER). return (o); } catch (InterruptedException e){}
} }
}
}
Concurrency: monitors & condition synchronization 28 Concurrency: monitors & condition synchronization 29 Concurrency: monitors & condition synchronization 30
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
5.4 Nested Monitors nested monitors - bounded buffer program nested monitors - bounded buffer model
Suppose that, in place of using the count variable and condition synchronized public void put(Object o) const Max = 5
throws InterruptedException { range Int = 0..Max
synchronization directly, we instead use two semaphores full and empty.down();
empty to reflect the state of the buffer. buf[in] = o; SEMAPHORE ...as before...
++count; in=(in+1)%size;
class SemaBuffer implements Buffer { full.up(); BUFFER = (put -> empty.down ->full.up ->BUFFER
… } |get -> full.down ->empty.up ->BUFFER
Semaphore full; //counts number of items synchronized public Object get() ).
throws InterruptedException{
Semaphore empty; //counts number of spaces full.down(); PRODUCER = (put -> PRODUCER).
Object o =buf[out]; buf[out]=null; CONSUMER = (get -> CONSUMER).
SemaBuffer(int size) { --count; out=(out+1)%size;
this.size = size; buf = new Object[size]; empty.up(); Does this behave
||BOUNDEDBUFFER = (PRODUCER|| BUFFER || CONSUMER
full = new Semaphore(0); return (o); as desired? ||empty:SEMAPHORE(5)
empty= new Semaphore(size); }
||full:SEMAPHORE(0)
} empty is decremented during a put operation, which is blocked
… )@{put,get}. Does this behave
if empty is zero; full is decremented by a get operation, which
} as desired?
is blocked if full is zero.
Concurrency: monitors & condition synchronization 31 Concurrency: monitors & condition synchronization 32 Concurrency: monitors & condition synchronization 33
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

nested monitors - bounded buffer model nested monitors - revised bounded buffer program nested monitors - revised bounded buffer model

LTSA analysis predicts a possible DEADLOCK: The only way to avoid it in Java is by careful design. In this BUFFER = (put -> BUFFER
Composing example, the deadlock can be removed by ensuring that the monitor |get -> BUFFER
potential DEADLOCK lock for the buffer is not acquired until after semaphores are ).
States Composed: 28 Transitions: 32 in 60ms decremented.
Trace to DEADLOCK: PRODUCER =(empty.down->put->full.up->PRODUCER).
public void put(Object o) CONSUMER =(full.down->get->empty.up->CONSUMER).
get
throws InterruptedException {
The Consumer tries to get a character, but the buffer is empty.down(); The semaphore actions have been moved to the producer
empty. It blocks and releases the lock on the semaphore synchronized(this){ and consumer. This is exactly as in the implementation
full. The Producer tries to put a character into the buf[in] = o; ++count; in=(in+1)%size; where the semaphore actions are outside the monitor .
}
buffer, but also blocks. Why? Does this behave as desired?
full.up();
This situation is known as the nested monitor problem. } Minimized LTS?
Concurrency: monitors & condition synchronization 34 Concurrency: monitors & condition synchronization 35 Concurrency: monitors & condition synchronization 36
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
5.5 Monitor invariants Summary
An invariant for a monitor is an assertion concerning the variables
it encapsulates. This assertion must hold whenever there is no thread  Concepts
executing inside the monitor i.e. on thread entry to and exit from a  monitors: encapsulated data + access procedures
monitor . mutual exclusion + condition synchronization
CarParkControl Invariant: 0 ≤ spaces ≤ N
 nested monitors
Semaphore Invariant: 0 ≤ value
 Model
Buffer Invariant: 0 ≤ count ≤ size
and 0 ≤ in < size  guarded actions
and 0 ≤ out< size  Practice
and in = (out + count) modulo size
 private data and synchronized methods in Java
Invariants can be helpful in reasoning about correctness of monitors  wait(), notify() and notifyAll() for condition synchronization
using a logical proof-based approach. Generally we prefer to use a
 single thread active in the monitor at a time
model-based approach amenable to mechanical checking .
Concurrency: monitors & condition synchronization 37 Concurrency: monitors & condition synchronization 38
©Magee/Kramer ©Magee/Kramer
Chapter 6 Deadlock Deadlock: four necessary and sufficient conditions

♦ Serially reusable resources:


Deadlock Concepts: system deadlock: no further progress the processes involved share resources which they use under mutual
four necessary & sufficient conditions exclusion.
♦ Incremental acquisition:
Models: deadlock - no eligible actions processes hold on to resources already allocated to them while waiting
to acquire additional resources.
Practice: blocked threads ♦ No pre-emption:
once acquired by a process, resources cannot be pre-empted (forcibly
withdrawn) but are only released voluntarily.
Aim: deadlock avoidance - to design ♦ Wait-for cycle:
systems where deadlock cannot occur.
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.
Concurrency: Deadlock 1 Concurrency: Deadlock 2 Concurrency: Deadlock 3
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Wait-for cycle 6.1 Deadlock analysis - primitive processes deadlock analysis - parallel composition

♦ deadlocked state is one with no outgoing transitions ♦ in systems, deadlock may arise from the
Has A awaits B
parallel composition of interacting processes.
♦ in FSP: STOP process
A RESOURCE = (get->put->RESOURCE).
Has E awaits A MOVE = (north->(south->MOVE|north->STOP)). p:P
SYS
printer: P = (printer.get->scanner.get
printer RESOURCE ->copy
north north
E MOVE scanner
get
->printer.put->scanner.put
B Has B awaits C put
->P).
0 1 2
q:Q scanner:
Q = (scanner.get->printer.get
south printer RESOURCE ->copy
scanner get ->scanner.put->printer.put
D C ♦ animation to produce a trace. put
->Q).
||SYS = (p:P||q:Q
Has C awaits D ♦analysis using LTSA: Trace to DEADLOCK: Deadlock Trace? ||{p,q}::printer:RESOURCE
Has D awaits E north ||{p,q}::scanner:RESOURCE
(shortest trace to STOP) Avoidance?
north ).
Concurrency: Deadlock 4 Concurrency: Deadlock 5 Concurrency: Deadlock 6
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
deadlock analysis - avoidance 6.2 Dining Philosophers Dining Philosophers - model structure diagram

♦ acquire resources in the same order? Five philosophers sit around a


right
phil[0]:
lef t
FORK
FORK
circular table. Each philosopher Each FORK is a PHIL
♦ Timeout: 3 2
spends his life alternately 2 shared resource lef t right
P = (printer.get-> GETSCANNER), thinking and eating. In the centre with actions get
GETSCANNER = (scanner.get->copy->printer.put and put. phil[1]: phil[4]:
->scanner.put->P
of the table is a large bowl of 3 1
PHIL
PHIL
|timeout -> printer.put->P spaghetti. A philosopher needs When hungry,
). two forks to eat a helping of 4 1 each PHIL must
right lef t

Q = (scanner.get-> GETPRINTER), spaghetti. 4 0


first get his
GETPRINTER = (printer.get->copy->printer.put FORK FORK
->scanner.put->Q right and left
One fork is placed between each 0
|timeout -> scanner.put->Q forks before he lef t right
pair of philosophers and they agree
). can start eating.
that each will only use the fork to his phil[2]: right
FORK
lef t phil[3]:
immediate right and left. PHIL PHIL
Deadlock? Progress?
Concurrency: Deadlock 7 Concurrency: Deadlock 8 Concurrency: Deadlock 9
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Dining Philosophers - model Dining Philosophers - model analysis Dining Philosophers

FORK = (get -> put -> FORK). Trace to DEADLOCK: This is the situation where
PHIL = (sitdown ->right.get->left.get phil.0.sitdown all the philosophers become Deadlock is easily
->eat ->right.put->left.put phil.0.right.get hungry at the same time, sit detected in our
->arise->PHIL). phil.1.sitdown down at the table and each model.
phil.1.right.get philosopher picks up the How easy is it to
phil.2.sitdown fork to his right. detect a potential
Table of philosophers:
phil.2.right.get deadlock in an
||DINERS(N=5)= forall [i:0..N-1] phil.3.sitdown The system can make no
further progress since each implementation?
(phil[i]:PHIL || phil.3.right.get
{phil[i].left,phil[((i-1)+N)%N].right}::FORK phil.4.sitdown philosopher is waiting for a
). phil.4.right.get fork held by his neighbor i.e.
a wait-for cycle exists!
Can this system deadlock?
Concurrency: Deadlock 10 Concurrency: Deadlock 11 Concurrency: Deadlock 12
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Dining Philosophers - implementation in Java Dining Philosophers - Fork monitor Dining Philosophers - Philosopher implementation
class Fork { class Philosopher extends Thread {
private boolean taken=false; taken ...
Applet Thread public void run() {
private PhilCanvas display; encodes the
try {
♦philosophers: private int identity; state of the while (true) { // thinking
1 n view active entities Fork(PhilCanvas disp, int id) fork view.setPhil(identity,view.THINKING);
Diners Philosopher { display = disp; identity = id;} sleep(controller.sleepTime()); // hungry
1 - implement as
display synchronized void put() { view.setPhil(identity,view.HUNGRY);
threads taken=false; right.get(); // gotright chopstick
n view.setPhil(identity,view.GOTRIGHT);
Fork display ♦forks: shared display.setFork(identity,taken);
notify(); sleep(500); Follows
passive entities } left.get(); // eating from the
- implement as view.setPhil(identity,view.EATING); model
synchronized void get() sleep(controller.eatTime()); (sitting
controller monitors throws java.lang.InterruptedException { right.put(); down and
PhilCanvas while (taken) wait(); left.put();
♦display taken=true; }
leaving the
table have
display.setFork(identity,taken); } catch (java.lang.InterruptedException e){} been
} }
Concurrency: Deadlock 13 Concurrency: Deadlock 14 Concurrency: Deadlock omitted).15
} }
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Dining Philosophers - implementation in Java Dining Philosophers Deadlock-free Philosophers


Deadlock can be avoided by ensuring that a wait-for cycle
To ensure deadlock
Code to create the philosopher cannot exist. How?
occurs eventually, PHIL(I=0)
threads and fork monitors: the slider control Introduce an = (when (I%2==0) sitdown
may be moved to the asymmetry into our ->left.get->right.get
for (int i =0; i<N; ++i) left. This reduces definition of ->eat
fork[i] = new Fork(display,i); the time each philosophers. ->left.put->right.put
for (int i =0; i<N; ++i){ philosopher spends Use the identity I of ->arise->PHIL
phil[i] = thinking and eating. a philosopher to make |when (I%2==1) sitdown
new Philosopher even numbered ->right.get->left.get
This "speedup"
(this,i,fork[(i-1+N)%N],fork[i]); philosophers get ->eat
increases the
phil[i].start(); their left forks first, ->left.put->right.put
probability of
} odd their right first. ->arise->PHIL
deadlock occurring.
).
Other strategies?
Concurrency: Deadlock 16 Concurrency: Deadlock 17 Concurrency: Deadlock 18
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Maze example - shortest path to “deadlock” Maze example - shortest path to “deadlock” Summary
We can exploit the shortest path trace produced by the  Concepts
deadlock detection mechanism of LTSA to find the ||GETOUT = MAZE(7). Shortest path
shortest path out of a maze to the STOP process! escape trace from  deadlock: no futher progress
position 7 ?  four necessary and sufficient conditions:
STOP We must first  serially reusable resources
model the MAZE. STOP Trace to
north  incremental acquisition
0 1 2 DEADLOCK: Aim: deadlock avoidance
Each position can  no preemption
0 1 2 north east - to design systems where
3 4 5 west east be modelled by the north  wait-for cycle deadlock cannot occur.
moves that it
3 4 5 west east north  Models
7 8 south permits. The MAZE
6 west
parameter gives the south  no eligable actions (analysis gives shortest path trace)
starting position. 6 7 8 west
eg. MAZE(Start=8) = P[Start], north  Practice
P[0] = (north->STOP|east->P[1]),...  blocked threads
Concurrency: Deadlock 19 Concurrency: Deadlock 20 Concurrency: Deadlock 21
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Chapter 7 safety & liveness properties 7.1 Safety

Safety & Liveness Concepts: properties: true for every possible execution A safety property asserts that nothing bad happens.
safety: nothing bad happens
♦ STOP or deadlocked state (no outgoing transitions)
Properties liveness: something good eventually happens
♦ ERROR process (-1) to detect erroneous behaviour
Models: safety: no reachable ERROR/STOP state command

progress: an action is eventually executed ACTUATOR


fair choice and action priority -1 0 1 =(command->ACTION),
ACTION
=(respond->ACTUATOR
Practice: threads and monitors respond
|command->ERROR).
command

Aim: property satisfaction. ♦ analysis using LTSA: Trace to ERROR:


(shortest trace) command
Concurrency: safety & liveness properties 1 Concurrency: safety & liveness properties 2 Concurrency: safety & liveness properties command 3
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Safety - property specification Safety properties Safety properties


♦ERROR conditions state what is not required (cf. exceptions). Property that it is polite to knock before entering a room. Safety property P defines a deterministic
♦ in complex systems, it is usually better to specify safety Traces: enter
knock enter process that asserts that any trace including
properties by stating directly what is required. actions in the alphabet of P, is accepted by P.
knock
knock
command
property SAFE_ACTUATOR property POLITE Thus, if P is composed with S, then traces of actions
= (command = (knock->enter->POLITE). knock
in the alphabet of S ∩ alphabet of P must also be
-1 0 1 valid traces of P, otherwise ERROR is reachable.
-> respond
-> SAFE_ACTUATOR
respond respond -1 0 1 Transparency of safety properties:
).
In all states, all the Since all actions in the alphabet of a property are eligible
command choices, composing a property with a set of processes does not
actions in the alphabet enter enter affect their correct behavior. However, if a behavior can occur
of a property are which violates the safety property, then ERROR is reachable.
♦ analysis using LTSA as before. eligible choices. Properties must be deterministic to be transparent.
knock
Concurrency: safety & liveness properties 4 Concurrency: safety & liveness properties 5 Concurrency: safety & liveness properties 6
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Safety properties Safety - mutual exclusion 7.2 Single Lane Bridge problem

♦ How can we specify that some action, disaster, LOOP = (mutex.down -> enter -> exit
never occurs? -> mutex.up -> LOOP).
||SEMADEMO = (p[1..3]:LOOP
||{p[1..3]}::mutex:SEMAPHORE(1)).
-1 0

disaster How do we property MUTEX =(p[i:1..3].enter


check that this -> p[i].exit
property CALM = STOP + {disaster}. does indeed -> MUTEX ).
ensure mutual ||CHECK = (SEMADEMO || MUTEX).
exclusion in the
critical section? A bridge over a river is only wide enough to permit a single lane of
A safety property must be specified so as to include all the
acceptable, valid behaviors in its alphabet. Check safety using LTSA. traffic. Consequently, cars can only move concurrently if they are
moving in the same direction. A safety violation occurs if two cars
What happens if semaphore is initialized to 2? moving in different directions enter the bridge at the same time.
Concurrency: safety & liveness properties 7 Concurrency: safety & liveness properties 8 Concurrency: safety & liveness properties 9
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Single Lane Bridge - model Single Lane Bridge - CARS model Single Lane Bridge - CONVOY model

♦ Events or actions of interest? NOPASS1 = C[1], //preserves entry order


const N = 3 // number of each type of car
enter and exit C[i:ID] = ([i].enter-> C[i%N+1]).
range T = 0..N // type of car count
♦ Identify processes. NOPASS2 = C[1], //preserves exit order
range ID= 1..N // car identities
property C[i:ID] = ([i].exit-> C[i%N+1]).
cars and bridge CARS
ONEWAY
♦ Identify properties. CAR = (enter->exit->CAR). ||CONVOY = ([ID]:CAR||NOPASS1||NOPASS2).
oneway 1.enter 2.enter 1.exit 2.exit
To model the fact that cars cannot pass each other
♦Define each process Single red[ID]. blue[ID]. on the bridge, we model a CONVOY of cars in the 0 1 2 0 1 2
Lane {enter,exit} {enter,exit}
and interactions same direction. We will have a red and a blue convoy
Bridge BRIDGE 3.enter 3.exit
(structure). of up to N cars for each direction:
Permits  2.enter
1.enter  1.exit
 2.exit
||CARS = (red:CONVOY || blue:CONVOY). but not  2.enter
1.enter  2.exit
 1.exit
ie. no overtaking.
Concurrency: safety & liveness properties 10 Concurrency: safety & liveness properties 11 Concurrency: safety & liveness properties 12
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Single Lane Bridge - BRIDGE model Single Lane Bridge - safety property ONEWAY Single Lane Bridge - model analysis
Cars can move concurrently on the bridge only if in the same direction. We now specify a safety property to check that cars do not collide!
The bridge maintains counts of blue and red cars on the bridge. Red cars While red cars are on the bridge only red cars can enter; similarly for ||SingleLaneBridge = (CARS|| BRIDGE||ONEWAY).
are only allowed to enter when the blue count is zero and vice-versa. blue cars. When the bridge is empty, either a red or a blue car may enter.
BRIDGE = BRIDGE[0][0], // initially empty property ONEWAY =(red[ID].enter -> RED[1] Is the safety
property ONEWAY No deadlocks/errors
BRIDGE[nr:T][nb:T] = //nr is the red count, nb the blue |blue.[ID].enter -> BLUE[1]
(when(nb==0) ), violated?
red[ID].enter -> BRIDGE[nr+1][nb] //nb==0 RED[i:ID] = (red[ID].enter -> RED[i+1]
| red[ID].exit -> BRIDGE[nr-1][nb] |when(i==1)red[ID].exit -> ONEWAY ||SingleLaneBridge = (CARS||ONEWAY).
|when (nr==0) |when(i>1) red[ID].exit -> RED[i-1]
blue[ID].enter-> BRIDGE[nr][nb+1] //nr==0 ), //i is a count of red cars on the bridge Without the BRIDGE
| blue[ID].exit -> BRIDGE[nr][nb-1] BLUE[i:ID]= (blue[ID].enter-> BLUE[i+1] contraints, is the Trace to property violation in ONEWAY:
). |when(i==1)blue[ID].exit -> ONEWAY safety property red.1.enter
Even when 0, exit actions permit the |when( i>1)blue[ID].exit -> BLUE[i-1] ONEWAY violated? blue.1.enter
car counts to be decremented. LTSA
Concurrency: safety & liveness properties maps these undefined states to ERROR. 13
).
Concurrency: safety & liveness properties
//i is a count of blue cars on the bridge
14 Concurrency: safety & liveness properties 15
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Single Lane Bridge - implementation in Java Single Lane Bridge - BridgeCanvas Single Lane Bridge - RedCar
An instance of BridgeCanvas class is created by SingleLaneBridge class RedCar implements Runnable {
Applet Thread Runnable applet - ref is passed to each newly created RedCar and BlueCar object.
BridgeCanvas display; Bridge control; int id;
blue, class BridgeCanvas extends Canvas { RedCar(Bridge b, BridgeCanvas d, int id) {
red display display
Single RedCar BlueCar public void init(int ncars) {…} //set number of cars display = d; this.id = id; control = b;
Lane }
control control //move red car with the identity i a step
Bridge Bridge //returns true for the period from just before,until just after car on bridge public void run() {
public boolean moveRed(int i) try {
throws InterruptedException{…} while(true) {
Active entities (cars) are Safe while (!display.moveRed(id)); // not on bridge
//move blue car with the identity i a step control.redEnter(); // request access to bridge
implemented as threads. Bridge //returns true for the period from just before,until just after car on bridge while (display.moveRed(id)); // move over bridge
Passive entity (bridge) is public boolean moveBlue(int i) control.redExit(); // release access to bridge
throws InterruptedException{…} }
implemented as a monitor. BridgeCanvas
public synchronized void freeze(){…}// freeze display } catch (InterruptedException e) {}
BridgeCanvas enforces no public synchronized void thaw(){…} //unfreeze display }
overtaking. } }
Similarly for the BlueCar
Concurrency: safety & liveness properties 16 Concurrency: safety & liveness properties 17 Concurrency: safety & liveness properties 18
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Single Lane Bridge - class Bridge Single Lane Bridge Single Lane Bridge - SafeBridge

class Bridge { class SafeBridge extends Bridge {


synchronized void redEnter() private int nred = 0; //number of red cars on bridge
throws InterruptedException {} private int nblue = 0; //number of blue cars on bridge
synchronized void redExit() {} // Monitor Invariant: ≥0 and nblue≥
nred≥ ≥0 and
synchronized void blueEnter() // not (nred>0 and nblue>0)
throws InterruptedException {}
synchronized void redEnter()
synchronized void blueExit() {}
throws InterruptedException {
} while (nblue>0) wait();
++nred; This is a direct
Class Bridge provides a null implementation of the } translation from
access methods i.e. no constraints on the access to the synchronized void redExit(){ the BRIDGE
bridge. --nred; model.
if (nred==0)notifyAll();
Result………… ? To ensure safety, the “safe” check box must be chosen }
in order to select the SafeBridge implementation.
Concurrency: safety & liveness properties 19 Concurrency: safety & liveness properties 20 Concurrency: safety & liveness properties 21
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Single Lane Bridge - SafeBridge 7.3 Liveness Progress properties - fair choice

synchronized void blueEnter() Fair Choice: If a choice over a set of transitions is


throws InterruptedException { A safety property asserts that nothing bad happens.
while (nred>0) wait(); executed infinitely often, then every transition in the
++nblue; A liveness property asserts that something good set will be executed infinitely often.
} eventually happens.
synchronized void blueExit(){ If a coin were tossed an COIN =(toss->heads->COIN
--nblue;
Single Lane Bridge: Does every car eventually get an infinite number of times,
if (nblue==0)notifyAll(); |toss->tails->COIN).
} opportunity to cross the bridge? we would expect that
toss
} heads would be chosen
ie. make PROGRESS?
To avoid unnecessary thread switches, we use conditional notification infinitely often and that toss

to wake up waiting threads only when the number of cars on the A progress property asserts that it is always the case that tails would be chosen
bridge is zero i.e. when the last car leaves the bridge. an action is eventually executed. Progress is the opposite of infinitely often. 0 1 2

But does every car eventually get an opportunity starvation, the name given to a concurrent programming
This requires Fair Choice !
to cross the bridge? This is a liveness property. situation in which an action is never executed. heads

Concurrency: safety & liveness properties 22 Concurrency: safety & liveness properties 23 Concurrency: safety & liveness properties 24
tails
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Progress properties Progress properties Progress properties
pick
Suppose that there were two possible coins that could be
toss
progress P = {a1,a2..an} defines a progress picked up: pick
pick toss toss
property P which asserts that in an infinite execution of toss
a trick coin
a target system, at least one of the actions a1,a2..an pick toss toss
0 1 2 3 4 5
and a regular
will be executed infinitely often. 0 1 2 3 4 5
coin…… progress HEADS = {heads} heads tails
heads
heads tails
progress TAILS = {tails}
heads Progress violation: TAILS
COIN system: progress HEADS = {heads} ? TWOCOIN = (pick->COIN|pick->TRICK), LTSA check progress Path to terminal set of states:
progress TAILS = {tails} ? TRICK = (toss->heads->TRICK), pick
COIN = (toss->heads->COIN|toss->tails->COIN). Actions in terminal set:
{toss, heads}
LTSA check progress: No progress violations detected.
TWOCOIN: progress HEADS = {heads} ?
progress TAILS = {tails} ? progress HEADSorTails = {heads,tails} ?
Concurrency: safety & liveness properties 25 Concurrency: safety & liveness properties 26 Concurrency: safety & liveness properties 27
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Progress analysis Progress analysis Progress analysis


A terminal set of states is one in which every state is reachable from A progress property is violated if analysis finds a Default analysis for Progress violation for actions:
every other state in the set via one or more transitions, and there is no TWOCOIN: separate
{pick}
transition from within the set to any state outside the set.
terminal set of states in which none of the progress Path to terminal set of states:
set actions appear. progress property for pick
every action. Actions in terminal set:
pick
Terminal sets {toss, heads, tails}
toss progress TAILS = {tails} in {1,2} and
for TWOCOIN: pick toss toss
Progress violation for actions:
{1,2} and Default: given fair choice, for every action in the alphabet of the {pick, tails}
{3,4,5} 0 1 2 3 4 5 target system, that action will be executed infinitely often. This is pick
toss Path to terminal set of states:
equivalent to specifying a separate progress property for every action. pick toss toss
pick
heads tails
pick
0 1 2 3 4 5 Actions in terminal set:
heads
Default heads tails {toss, heads}
toss
Given fair choice, each terminal set represents an execution in which analysis for heads
pick toss toss
each action used in a transition in the set is executed infinitely often. TWOCOIN?
If the default holds, then every other progress property holds
Since there is no transition out of a terminal set, any action that is not 0 1 2 3 4 5 i.e. every action is executed infinitely often and system consists
used in the set cannot occur infinitely often in all executions of the of a single terminal set of states.
heads tails
system -safety
Concurrency: and& hence represents a potential progress violation!
liveness properties 28 Concurrency: safety & liveness properties 29 Concurrency: safety & liveness properties 30
heads
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
sleep
Progress - single lane bridge Progress - action priority Progress - action priority
work
The Single Lane Action priority expressions describe scheduling properties:
Bridge implementation NORMAL =(work->play->NORMAL
||C = (P||Q)<<{a1,…,an} specifies a composition |sleep->play->NORMAL). 0 1 2
can permit progress
High in which the actions a1,..,an have higher priority
violations. than any other action in the alphabet of P||Q play
However, if default Priority including the silent action tau. In any choice in this Action priority simplifies the resulting LTS by play
progress analysis is (“<<”) system which has one or more of the actions discarding lower priority actions from choices. work
applied to the model a1,..,an labeling a transition, the transitions
then no violations are labeled with lower priority actions are discarded. ||HIGH =(NORMAL)<<{work}. 0 1
detected! progress BLUECROSS = {blue[ID].enter}
progress REDCROSS = {red[ID].enter} ||C = (P||Q)>>{a1,…,an} specifies a composition
Why not? No progress violations detected. in which the actions a1,..,an have lower priority
play
Low sleep
than any other action in the alphabet of P||Q
Priority including the silent action tau. In any choice in this
Fair choice means that eventually every possible execution occurs, 0 1
including those in which cars do not starve. To detect progress
(“>>”) system which has one or more transitions not labeled ||LOW =(NORMAL)>>{work}.
problems we must superimpose some scheduling policy for actions, by a1,..,an, the transitions labeled by a1,..,an play
which models the situation in which the bridge is congested. are discarded.
Concurrency: safety & liveness properties 31 Concurrency: safety & liveness properties 32 Concurrency: safety & liveness properties 33
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

7.4 Congested single lane bridge congested single lane bridge model congested single lane bridge model

progress BLUECROSS = {blue[ID].enter} Progress violation: BLUECROSS ||CongestedBridge = (SingleLaneBridge)


This corresponds
progress REDCROSS = {red[ID].enter} Path to terminal set of states: >>{red[ID].exit,blue[ID].exit}.
with the
red.1.enter
observation that, red.1.enter
BLUECROSS - eventually one of the blue cars will be able to enter red.2.enter
with more than
Actions in terminal set:
REDCROSS - eventually one of the red cars will be able to enter one car, it is
{red.1.enter, red.1.exit, red.2.enter,
possible that blue.1.enterblue.2.enter blue.1.exit blue.1.enter red.2.enter red.1.exit red.1.enter
Congestion using action priority? red.2.exit, red.3.enter, red.3.exit}
whichever color
Could give red cars priority over blue (or vice versa) ? car enters the 0 1 2 3 4 5 6 7 8
Progress violation: REDCROSS
In practice neither has priority over the other. bridge first will
Path to terminal set of states:
Instead we merely encourage congestion by lowering the continuously
blue.1.enter blue.2.exit red.2.exit
priority of the exit actions of both cars from the bridge. occupy the bridge
blue.2.enter
preventing the
||CongestedBridge = (SingleLaneBridge) Actions in terminal set:
other color from Will the results be the same if we model congestion by giving car entry
>>{red[ID].exit,blue[ID].exit}. {blue.1.enter, blue.1.exit, blue.2.enter,
ever crossing. to the bridge high priority?
blue.2.exit, blue.3.enter, blue.3.exit}
Progress Analysis ? LTS? Can congestion occur if there is only one car moving in each direction?
Concurrency: safety & liveness properties 34 Concurrency: safety & liveness properties 35 Concurrency: safety & liveness properties 36
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Progress - revised single lane bridge model Progress - revised single lane bridge model Progress - analysis of revised single lane bridge model
The bridge needs to know whether or not cars are /* nr– number of red cars on the bridge wr – number of red cars waiting to enter Trace to DEADLOCK: The trace is the scenario
waiting to cross. nb– number of blue cars on the bridge wb – number of blue cars waiting to enter red.1.request in which there are cars
*/ red.2.request waiting at both ends, and
Modify CAR: BRIDGE = BRIDGE[0][0][0][0], red.3.request consequently, the bridge
CAR = (request->enter->exit->CAR). BRIDGE[nr:T][nb:T][wr:T][wb:T] = blue.1.request does not allow either red
(red[ID].request -> BRIDGE[nr][nb][wr+1][wb] blue.2.request or blue cars to enter.
Modify BRIDGE: |when (nb==0 && wb==0) blue.3.request
red[ID].enter -> BRIDGE[nr+1][nb][wr-1][wb] Solution?
Red cars are only allowed to enter the bridge if there |red[ID].exit -> BRIDGE[nr-1][nb][wr][wb]
are no blue cars on the bridge and there are no blue |blue[ID].request -> BRIDGE[nr][nb][wr][wb+1] Introduce some asymmetry in the problem (cf. Dining philosophers).
cars waiting to enter the bridge. |when (nr==0 && wr==0) This takes the form of a boolean variable (bt) which breaks the
blue[ID].enter -> BRIDGE[nr][nb+1][wr][wb-1] deadlock by indicating whether it is the turn of blue cars or red
Blue cars are only allowed to enter the bridge if there
|blue[ID].exit -> BRIDGE[nr][nb-1][wr][wb] cars to enter the bridge.
are no red cars on the bridge and there are no red ).
cars waiting to enter the bridge. Arbitrarily set bt to true initially giving blue initial precedence.
OK now?
Concurrency: safety & liveness properties 37 Concurrency: safety & liveness properties 38 Concurrency: safety & liveness properties 39
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Progress - 2 nd revision of single lane bridge model Revised single lane bridge implementation - FairBridge Revised single lane bridge implementation - FairBridge
const True = 1 class FairBridge extends Bridge { synchronized void blueEnter(){
const False = 0
Analysis ? private int nred = 0; //count of red cars on the bridge throws InterruptedException {
private int nblue = 0; //count of blue cars on the bridge ++waitblue;
range B = False..True while (nred>0||(waitred>0 && !blueturn)) wait();
private int waitblue = 0; //count of waiting blue cars
/* bt - true indicates blue turn, false indicates red turn */ private int waitred = 0; //count of waiting red cars --waitblue;
BRIDGE = BRIDGE[0][0][0][0][True], private boolean blueturn = true; ++nblue;
} The “fair” check
BRIDGE[nr:T][nb:T][wr:T][wb:T][bt:B] = synchronized void redEnter() box must be
(red[ID].request -> BRIDGE[nr][nb][wr+1][wb][bt] throws InterruptedException { synchronized void blueExit(){ chosen in order to
|when (nb==0 && (wb==0||!bt)) ++waitred; --nblue; select the
while (nblue>0||(waitblue>0 && blueturn)) wait(); blueturn = false; FairBridge
red[ID].enter -> BRIDGE[nr+1][nb][wr-1][wb][bt] if (nblue==0) notifyAll();
--waitred; implementation.
|red[ID].exit -> BRIDGE[nr-1][nb][wr][wb][True] This is a direct }
++nred;
|blue[ID].request -> BRIDGE[nr][nb][wr][wb+1][bt] } translation from }
|when (nr==0 && (wr==0||bt))
synchronized void redExit(){ the model.
blue[ID].enter -> BRIDGE[nr][nb+1][wr][wb-1][bt] Note that we did not need to introduce a new request monitor method.
--nred; The existing enter methods can be modified to increment a wait count
|blue[ID].exit -> BRIDGE[nr][nb-1][wr][wb][False] blueturn = true;
if (nred==0)notifyAll(); before testing whether or not the caller can access the bridge.
).
Concurrency: safety & liveness properties 40 Concurrency:
} safety & liveness properties 41 Concurrency: safety & liveness properties 42
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
7.5 Readers and Writers readers/writers model readers/writers model - READER & WRITER

♦ Events or actions of interest? set Actions =


{acquireRead,releaseRead,acquireWrite,releaseWrite}
acquireRead, releaseRead, acquireWrite, releaseWrite
♦ Identify processes. READER = (acquireRead->examine->releaseRead->READER)
+ Actions
Light Readers, Writers & the RW_Lock \ {examine}.
blue
indicates ♦ Identify properties. WRITER = (acquireWrite->modify->releaseWrite->WRITER)
database reader[1..Nread]: writer[1..Nwrite]: + Actions
access. RW_Safe READER WRITER
\ {modify}.
RW_Progress
Alphabet extension is used to ensure that the other access
♦Define each process READERS READWRITELOCK actions cannot occur freely for any prefixed instance of the
A shared database is accessed by two kinds of processes. Readers _WRITERS acquireRead acquireWrite
execute transactions that examine the database while Writers both and interactions releaseRead releaseWrite
process (as before).
examine and update the database. A Writer must have exclusive access (structure). Action hiding is used as actions examine and modify are not
to the database; any number of Readers may concurrently access it. relevant for access synchronisation.
Concurrency: safety & liveness properties 43 Concurrency: safety & liveness properties 44 Concurrency: safety & liveness properties 45
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

readers/writers model - RW_LOCK readers/writers model - safety readers/writers model


acquireRead
property SAFE_RW An ERROR occurs if a reader
const False = 0 const True = 1 The lock = (acquireRead -> READING[1] acquireWrite acquireRead
or writer is badly behaved
range Bool = False..True maintains a |acquireWrite -> WRITING (release before acquire
count of the -1 0 1 2 3
const Nread = 2 // Maximum readers ), or more than two readers).
const Nwrite= 2 // Maximum writers number of READING[i:1..Nread]
releaseRead releaseWrite releaseRead We can now compose the
readers, and = (acquireRead -> READING[i+1] releaseWrite
READWRITELOCK with
RW_LOCK = RW[0][False], a Boolean for |when(i>1) releaseRead -> READING[i-1] releaseRead releaseRead
READER and WRITER
RW[readers:0..Nread][writing:Bool] = the writers. |when(i==1) releaseRead -> SAFE_RW
(when (!writing)
releaseWrite
processes according to our
),
acquireRead -> RW[readers+1][writing] acquireRead structure… …
WRITING = (releaseWrite -> SAFE_RW). releaseWrite

|releaseRead -> RW[readers-1][writing]


|when (readers==0 && !writing) We can check that RW_LOCK satisfies the safety property…… ||READERS_WRITERS
acquireWrite -> RW[readers][True] = (reader[1..Nread] :READER Safety and
|releaseWrite -> RW[readers][False] ||READWRITELOCK = (RW_LOCK || SAFE_RW). || writer[1..Nwrite]:WRITER Progress
). ||{reader[1..Nread], Analysis ?
writer[1..Nwrite]}::READWRITELOCK).
Safety Analysis ? LTS?
Concurrency: safety & liveness properties 46 Concurrency: safety & liveness properties 47 Concurrency: safety & liveness properties 48
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
readers/writers - progress readers/writers model - progress readers/writers implementation - monitor interface

progress WRITE = {writer[1..Nwrite].acquireWrite} Progress violation: WRITE Writer We concentrate on the monitor implementation:
progress READ = {reader[1..Nread].acquireRead} Path to terminal set of states: starvation: interface ReadWrite {
reader.1.acquireRead The number public void acquireRead()
WRITE - eventually one of the writers will acquireWrite Actions in terminal set: of readers throws InterruptedException;
READ - eventually one of the readers will acquireRead {reader.1.acquireRead, reader.1.releaseRead, never drops public void releaseRead();
reader.2.acquireRead, reader.2.releaseRead} to zero. public void acquireWrite()
Adverse conditions using action priority? throws InterruptedException;
reader.1.acquireRead
we lower the priority of the release actions for both Try the public void releaseWrite();
readers and writers. Applet! }
reader.2.acquireRead
||RW_PROGRESS = READERS_WRITERS writer.1.acquireWrite
We define an interface that identifies the monitor
>>{reader[1..Nread].releaseRead,
writer[1..Nread].releaseWrite}.
writer.2.acquireWrite reader.1.acquireRead reader.2.releaseRead
methods that must be implemented, and develop a number
0 1 2 3 4 5
of alternative implementations of this interface.
Progress Analysis ? LTS? Firstly, the safe READWRITELOCK.
writer.2.releaseWrite reader.1.releaseRead reader.2.acquireRead
Concurrency: safety & liveness properties 49 Concurrency: safety & liveness properties
writer.1.releaseWrite 50 Concurrency: safety & liveness properties 51
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

readers/writers implementation - ReadWriteSafe readers/writers implementation - ReadWriteSafe readers/writers - writer priority

class ReadWriteSafe implements ReadWrite { public synchronized void acquireWrite()


private int readers =0; throws InterruptedException {
private boolean writing = false; while (readers>0 || writing) wait(); Strategy:
writing = true; Block readers
public synchronized void acquireRead() } if there is a
throws InterruptedException { writer waiting.
while (writing) wait(); public synchronized void releaseWrite() {
++readers; writing = false;
} notifyAll();
}
public synchronized void releaseRead() { } set Actions = {acquireRead,releaseRead,acquireWrite,
--readers; releaseWrite,requestWrite}
if(readers==0) notify(); Unblock all readers
} WRITER =(requestWrite->acquireWrite->modify
However, this monitor implementation suffers from the WRITE
->releaseWrite->WRITER
progress problem: possible writer starvation if the number of
Unblock a single writer when no more readers. )+Actions\{modify}.
readers never drops to zero.
Concurrency: safety & liveness properties 52 Concurrency: safety & liveness properties
Solution? 53 Concurrency: safety & liveness properties 54
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
readers/writers model - writer priority readers/writers model - writer priority readers/writers implementation - ReadWritePriority
RW_LOCK = RW[0][False][0], property RW_SAFE:
class ReadWritePriority implements ReadWrite{
RW[readers:0..Nread][writing:Bool][waitingW:0..Nwrite] private int readers =0;
No deadlocks/errors
= (when (!writing && waitingW==0) private boolean writing = false;
acquireRead -> RW[readers+1][writing][waitingW] private int waitingW = 0; // no of waiting Writers.
progress READ and WRITE:
|releaseRead -> RW[readers-1][writing][waitingW]
|when (readers==0 && !writing) Progress violation: READ public synchronized void acquireRead()
acquireWrite-> RW[readers][True][waitingW-1] Reader throws InterruptedException {
Path to terminal set of states:
|releaseWrite-> RW[readers][False][waitingW] starvation: while (writing || waitingW>0) wait();
writer.1.requestWrite
|requestWrite-> RW[readers][writing][waitingW+1] if always a ++readers;
writer.2.requestWrite
). writer }
Actions in terminal set:
waiting.
{writer.1.requestWrite, writer.1.acquireWrite, public synchronized void releaseRead() {
Safety and Progress Analysis ? writer.1.releaseWrite, writer.2.requestWrite, --readers;
writer.2.acquireWrite, writer.2.releaseWrite} if (readers==0) notify();
}
In practice, this may be satisfactory as is usually more read access
than write, and readers generally want the most up to date information.
Concurrency: safety & liveness properties 55 Concurrency: safety & liveness properties 56 Concurrency: safety & liveness properties 57
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

readers/writers implementation - ReadWritePriority Summary

synchronized public void acquireWrite() {


 Concepts
++waitingW;  properties: true for every possible execution
while (readers>0 || writing) try{ wait();}  safety: nothing bad happens
catch(InterruptedException e){}
 liveness: something good eventually happens
--waitingW;
writing = true;  Models
}  safety: no reachable ERROR/STOP state
synchronized public void releaseWrite() { compose safety properties at appropriate stages
writing = false;  progress: an action is eventually executed
notifyAll();
} fair choice and action priority
} apply progress check on the final target system model
 Practice
Both READ and WRITE progress properties can be satisfied by Aim: property satisfaction
 threads and monitors
introducing a turn variable as in the Single Lane Bridge.
Concurrency: safety & liveness properties 58 Concurrency: safety & liveness properties 59
©Magee/Kramer ©Magee/Kramer
Chapter 8 Model-based Design 8.1 from requirements to models

Model-Based Design Concepts: design process: ♦ goals of the system


♦ scenarios (Use Case models)
requirements to models to implementations Requirements
♦ properties of interest
Models: check properties of interest: Any
- safety on the appropriate (sub)system appropriate ♦ identify the main events, actions, and interactions
design ♦ identify and define the main processes
- progress on the overall system
approach
can be ♦ identify and define the properties of interest
Practice: model interpretation - to infer actual system used. ♦ structure the processes into an architecture
behavior
threads and monitors
♦ check traces of interest
Model
Aim: rigorous design process. ♦ check properties of interest

Concurrency: model-based design 1 Concurrency: model-based design 2 Concurrency: model-based design 3


©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

a Cruise Control System - requirements a Cruise Control System - hardware model - outline design
When the car Parallel Interface Adapter (PIA) is polled every 100msec. It ♦outline processes and interactions.
ignition is switched records the actions of the sensors: • buttons (on, off, resume)
on and the on Sensor Scan monitors Cruise Controller triggers
buttons • brake (pressed)
button is pressed, the buttons, brake, clear speed and record
polled
the current speed brake • accelerator (pressed) accelerator and speed, and enables or
PIA Sensors
is recorded and the accelerator engine events. disables the speed control.
system is enabled: CPU • engine (on, off).
engine
it maintains the Engine Prompts
speed of the car at
the recorded wheel interrupt D/A throttle Input Speed monitors Speed Control clears and Throttle
setting. the speed when the records the speed, and sets the
engine is on, and sets the throttle actual
Pressing the brake, Wheel revolution sensor generates interrupts to enable the car provides the current accordingly when enabled. throttle.
accelerator or off speed to be calculated. speed readings to speed
setThrottle
button disables the speed control.
buttons system. Pressing Output: The cruise control system controls the car speed by setting
resume or on re- the throttle via the digital-to-analogue converter.
Concurrency: model-based design 4 Concurrency: model-based design 5 Concurrency: model-based design 6
enables the system.
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
model -design model - structure, actions and interactions model elaboration - process definitions

♦ Main events, actions and interactions. The CONTROL CRUISE SENSORSCAN = ({Sensors} -> SENSORSCAN).
CONTROL CONTROL // monitor speed when engine on
on, off, resume, brake, accelerator system is SENSOR Sensors INPUTSPEED = (engineOn -> CHECKSPEED),
Sensors CRUISE SYSTEM
engine on, engine off, structured SCAN CONTROLLER CHECKSPEED = (speed -> CHECKSPEED
speed, setThrottle as two |engineOff -> INPUTSPEED
processes. Engine Prompts ).
clearSpeed,recordSpeed,
Prompts The main // zoom when throttle set
enableControl,disableControl INPUT speed THROTTLE THROTTLE =(setThrottle -> zoom -> THROTTLE).
actions and SPEED set
♦ Identify main processes. interactions SPEED
CONTROL Throttle // perform speed control when enabled
are as SPEEDCONTROL = DISABLED,
Sensor Scan, Input Speed, shown. DISABLED =({speed,clearSpeed,recordSpeed}->DISABLED
Cruise Controller, Speed Control and | enableControl -> ENABLED
set Sensors = {engineOn,engineOff,on,off, ),
Throttle
resume,brake,accelerator} ENABLED = ( speed -> setThrottle -> ENABLED
♦ Identify main properties. set Engine = {engineOn,engineOff} |{recordSpeed,enableControl} -> ENABLED
set Prompts = {clearSpeed,recordSpeed, | disableControl -> DISABLED
safety - disabled when off, brake or accelerator pressed. ).
enableControl,disableControl}
♦Define and structure
Concurrency: model-based design each process. 7 Concurrency: model-based design 8 Concurrency: model-based design 9
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

model elaboration - process definitions model - CONTROL subsystem model - Safety properties

// enable speed control when cruising, ||CONTROL =(CRUISECONTROLLER Safety checks are compositional. If there is no violation
// disable when off, brake or accelerator pressed ||SPEEDCONTROL at a subsystem level, then there cannot be a violation
CRUISECONTROLLER = INACTIVE, ). when the subsystem is composed with other subsystems.
INACTIVE =(engineOn -> clearSpeed -> ACTIVE),
ACTIVE =(engineOff -> INACTIVE This is because, if the ERROR state of a particular safety
|on->recordSpeed->enableControl->CRUISING
Animate to check particular However, we need to property is unreachable in the LTS of the subsystem, it
), traces: - Is control enabled analyse to exhaustively remains unreachable in any subsequent parallel
CRUISING =(engineOff -> INACTIVE after the engine is check: Safety: Is the composition which includes the subsystem. Hence...
|{ off,brake,accelerator} switched on and the on control disabled
-> disableControl -> STANDBY button is pressed? when off, brake or Safety properties should be composed with the
|on->recordSpeed->enableControl->CRUISING - Is control disabled accelerator is
), when the brake is appropriate system or subsystem to which the
pressed?
STANDBY =(engineOff -> INACTIVE then pressed? Progress: Can every
property refers. In order that the property can check
|resume -> enableControl -> CRUISING - Is control re- action eventually be the actions in its alphabet, these actions must not be
|on->recordSpeed->enableControl->CRUISING enabled when resume selected? hidden in the system.
). is then pressed?
Concurrency: model-based design 10 Concurrency: model-based design 11 Concurrency: model-based design 12
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
model - Safety properties model analysis model - Progress properties
property CRUISESAFETY = We can now compose the whole system: Progress checks are not compositional. Even if there is no
({off,accelerator,brake,disableControl} -> CRUISESAFETY violation at a subsystem level, there may still be a
|{on,resume} -> SAFETYCHECK ||CONTROL = violation when the subsystem is composed with other
), (CRUISECONTROLLER||SPEEDCONTROL||CRUISESAFETY subsystems.
SAFETYCHECK = )@ {Sensors,speed,setThrottle}.
({on,resume} -> SAFETYCHECK This is because an action in the subsystem may satisfy
|{off,accelerator,brake} -> SAFETYACTION ||CRUISECONTROLSYSTEM = progress yet be unreachable when the subsystem is
|disableControl -> CRUISESAFETY (CONTROL||SENSORSCAN||INPUTSPEED||THROTTLE). composed with other subsystems which constrain its
), behavior. Hence...
SAFETYACTION =(disableControl->CRUISESAFETY).
LTS?
Deadlock? Progress checks should be conducted on the complete
||CONTROL =(CRUISECONTROLLER No deadlocks/errors
||SPEEDCONTROL Safety? target system after satisfactory completion of the
||CRUISESAFETY safety checks.
Is CRUISESAFETY
).
violated? Progress?
Concurrency: model-based design 13 Concurrency: model-based design 14 Concurrency: model-based design 15
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

model - Progress properties cruise control model - minimized LTS model - revised cruise control system
Check with no ||CRUISEMINIMIZED = (CRUISECONTROLSYSTEM) Modify CRUISECONTROLLER so that control is disabled when the
hidden actions engine is switched off:
Progress violation for actions: @ {Sensors,speed}.

{engineOn, clearSpeed, engineOff, on, recordSpeed, engineOff CRUISING =(engineOff -> disableControl -> INACTIVE
enableControl, off, disableControl, brake, accelerator |{ off,brake,accelerator} -> disableControl -> STANDBY
accelerator...........} brake
|on->recordSpeed->enableControl->CRUISING
engineOn on off engineOn
Path to terminal set of states: ),
engineOn …
clearSpeed
OK now?
0 1 2 3 4 5 Modify the safety property:
on speed on speed speed
recordSpeed speed
property IMPROVEDSAFETY = ({off,accelerator,brake,disableControl,
engineOff} -> IMPROVEDSAFETY
enableControl Control is not disabled |{on,resume} -> SAFETYCHECK
engineOff on
engineOff when the engine is resume Action hiding and minimization ),
engineOn switched off ! can help to reduce the size of SAFETYCHECK = ({on,resume} -> SAFETYCHECK
Actions in terminal set: the LTS diagram and make it |{off,accelerator,brake,engineOff} -> SAFETYACTION
{speed, setThrottle, zoom} easier to interpret. |disableControl -> IMPROVEDSAFETY
engineOff ),
Concurrency: model-based design 16 Concurrency: model-based design 17 Concurrency: model-based design
SAFETYACTION =(disableControl -> IMPROVEDSAFETY). 18
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
model - revised cruise control system model - system sensitivities model interpretation

Minimized LTS: accelerator


||SPEEDHIGH = CRUISECONTROLSYSTEM << {speed}. Models can be used to indicate system sensitivities.
brake
engineOn on off
No deadlocks/errors If it is possible that erroneous situations detected in the
Progress violation for actions: model may occur in the implemented system, then the
{engineOn, engineOff, on, off, brake, accelerator, model should be revised to find a design which ensures
0 1 2 3
speed on speed resume, setThrottle, zoom} that those violations are avoided.
speed Path to terminal set of states:
No progress engineOn However, if it is considered that the real system will not
engineOff on
resume violations detected. tau exhibit this behavior, then no further model revisions are
Actions in terminal set: necessary.
engineOff {speed} The system may be
sensitive to the Model interpretation and correspondence to the
engineOff priority of the implementation are important in determining the relevance
What about under adverse conditions? action speed. and adequacy of the model design and its analysis.
Check for system sensitivities.
Concurrency: model-based design 19 Concurrency: model-based design 20 Concurrency: model-based design 21
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

The central role of design architecture 8.2 from models to implementations cruise control system - class diagram
Architecture
Design Applet
CarSpeed
architecture Model setThrottle()
getSpeed()
describes the
gross ♦ identify the main active entities dis p
CruiseControl
car
CarSimulator
organization - to be implemented as threads
and global control
Behavioural View Performance View Implementation View ♦ identify the main (shared) passive entities Controller Runnable
structure of
brake()
the system in - to be implemented as monitors accelerator() sc cs
SpeedControl
terms of its ♦ identify the interactive display environment engineOff()
constituent engineOn() enableControl() SpeedControl
components. Analysis Program Construction - to be implemented as associated classes on() disableControl() interacts with
off() recordSpeed() the car
♦ structure the classes as a class diagram resume() clearSpeed()
simulation via
We consider that the models for analysis and Java interface
dis p
the implementation should be considered as CruiseDisplay CarSpeed.
elaborated views of this basic design structure.
Concurrency: model-based design 22 Concurrency: model-based design 23 Concurrency: model-based design 24
©Magee/Kramer ©Magee/Kramer CRUISECONTROLLER SPEEDCONTROL
©Magee/Kramer
cruise control system - class Controller cruise control system - class Controller cruise control system - class SpeedControl
class Controller { synchronized void engineOn(){ class SpeedControl implements Runnable {
final static int INACTIVE = 0; // cruise controller states Controller if(controlState==INACTIVE) final static int DISABLED = 0; //speed control states SpeedControl
final static int ACTIVE = 1; {sc.clearSpeed(); controlState=ACTIVE;} final static int ENABLED = 1; is an active
final static int CRUISING = 2;
is a passive This is a private int state = DISABLED; //initial state
} entity - when
final static int STANDBY = 3; entity - it direct private int setSpeed = 0; //target speed
private int controlState = INACTIVE; //initial state synchronized void on(){ private Thread speedController; enabled, a new
reacts to if(controlState!=INACTIVE){ translation
private CarSpeed cs; //interface to control speed
private SpeedControl sc; from the thread is
events. sc.recordSpeed(); sc.enableControl(); private CruiseDisplay disp;
Controller(CarSpeed cs, CruiseDisplay disp) Hence we controlState=CRUISING; model. SpeedControl(CarSpeed cs, CruiseDisplay disp){ created which
{sc=new SpeedControl(cs,disp);} }
implement it } this.cs=cs; this.disp=disp; periodically
synchronized void brake(){ disp.disable(); disp.record(0); obtains car
if (controlState==CRUISING ) as a monitor synchronized void off(){ }
{sc.disableControl(); controlState=STANDBY; } if(controlState==CRUISING ) speed and sets
synchronized void recordSpeed(){
} {sc.disableControl(); controlState=STANDBY;} setSpeed=cs.getSpeed(); disp.record(setSpeed); the throttle.
synchronized void accelerator(){ } }
if (controlState==CRUISING ) synchronized void resume(){ synchronized void clearSpeed(){
{sc.disableControl(); controlState=STANDBY; } if(controlState==STANDBY) if (state==DISABLED) {setSpeed=0;disp.record(setSpeed);}
} {sc.enableControl(); controlState=CRUISING;} }
synchronized void engineOff(){ }
if(controlState!=INACTIVE) { } synchronized void enableControl(){
if (controlState==CRUISING) sc.disableControl(); if (state==DISABLED) {
controlState=INACTIVE; disp.enable(); speedController= new Thread(this);
}
Concurrency: model-based design 25 Concurrency: model-based design 26 Concurrency:speedController.start();
model-based design state=ENABLED; 27
} ©Magee/Kramer ©Magee/Kramer
} ©Magee/Kramer
}

cruise control system - class SpeedControl Summary Course Outline


synchronized void disableControl(){
if (state==ENABLED) {disp.disable(); state=DISABLED;}
 Concepts ♦ Processes and Threads
}  design process:
public void run() { // the speed controller thread from requirements to models to implementations
♦ Concurrent Execution
try {
while (state==ENABLED) {  design architecture ♦ Shared Objects & Interference
Concepts
Thread.sleep(500);
if (state==ENABLED) synchronized(this) {
double error = (float)(setSpeed-cs.getSpeed())/6.0;
 Models ♦ Monitors & Condition Synchronization Models
double steady = (double)setSpeed/12.0;  check properties of interest
}
cs.setThrottle(steady+error); //simplified feed back control
safety: compose safety properties at appropriate (sub)system ♦ Deadlock Practice
}
} catch (InterruptedException e) {} progress: apply progress check on the final target system model ♦ Safety and Liveness Properties
speedController=null;
}  Practice ♦ Model-based Design
}
SpeedControl is an example of a class that  model interpretation - to infer actual system behavior
combines both synchronized access methods  threads and monitors ♦ Dynamic systems ♦Concurrent Software Architectures
(to update local variables ) and a thread.
Aim: rigorous design process. ♦ Message Passing ♦Timed Systems
Concurrency: model-based design 28 Concurrency: model-based design 29 Concurrency: model-based design 30
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Chapter 10 Message Passing 10.1 Synchronous Message Passing - channel

Message Passing Concepts: synchronous message passing - channel Channel c


asynchronous message passing - port Sender Receiver
- send and receive / selective receive send(e,c) v=receive(c)
rendezvous bidirectional comms - entry one-to-one
- call and accept ... reply
♦ send(e,c) - send the ♦ v = receive(c) - receive
Models: channel : relabelling, choice & guards value of the expression e a value into local variable v
port : message queue, choice & guards to channel c. The process from channel c. The
entry : port & channel calling the send operation process calling the receive
is blocked until the operation is blocked
Practice: distributed computing (disjoint memory) message is received from waiting until a message is
threads and monitors (shared memory) the channel. sent to the channel.
Concurrency: message passing 1 Concurrency: message passing 2 Concurrency: message passing cf. distributed assignment v = e 3
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

synchronous message passing - applet Java implementation - channel Java implementation - sender

A sender class Channel extends Selectable { class Sender implements Runnable {


The private Channel chan;
communicates Object chann = null;
implementation private SlotCanvas display;
with a receiver
public synchronized void send(Object v) of Channel is a Sender(Channel c, SlotCanvas d)
using a single
throws InterruptedException { monitor that has {chan=c; display=d;}
channel.
chann = v; synchronized
The sender signal(); access methods public void run() {
sends a while (chann != null) wait(); for send and try { int ei = 0;
sequence of } receive. while(true) {
integer values display.enter(String.valueOf(ei));
from 0 to 9 and public synchronized Object receive() ThreadPanel.rotate(12);
Channel chan = new Channel(); throws InterruptedException { chan.send(new Integer(ei));
then restarts at
tx.start(new Sender(chan,senddisp)); block(); clearReady(); //part of Selectable display.leave(String.valueOf(ei));
0 again.
rx.start(new Receiver(chan,recvdisp)); Object tmp = chann; chann = null; ei=(ei+1)%10; ThreadPanel.rotate(348);
notifyAll(); //could be notify() }
return(tmp); } catch (InterruptedException e){}
Instances of ThreadPanel Instances of SlotCanvas Selectable is
} described later. }
Concurrency: message passing 4 Concurrency: message passing 5 Concurrency: message passing 6
©Magee/Kramer
} ©Magee/Kramer
} ©Magee/Kramer
Java implementation - receiver model selective receive
class Receiver implements Runnable { range M = 0..9 // messages with values up to 9
private Channel chan; Channels How
private SlotCanvas display; SENDER = SENDER[0], // shared channel chan Sender
Receiver(Channel c, SlotCanvas d) SENDER[e:M] = (chan.send[e]-> SENDER[(e+1)%10]). Sender c1 should we deal
send(e,c) c2 with multiple
{chan=c; display=d;} Sender[n]
send(e,c)
RECEIVER = (chan.receive[v:M]-> RECEIVER).
send(en,cn)
cn channels?
public void run() {
try { Integer v=null;
// relabeling to model synchronization
while(true) { ||SyncMsg = (SENDER || RECEIVER)
select
ThreadPanel.rotate(180); LTS? when G1 and v1=receive(chan1) => S1;
/{chan/chan.{send,receive}}. Select
if (v!=null) display.leave(v.toString()); or
v = (Integer)chan.receive(); statement...
when G2 and v2=receive(chan2) => S2;
display.enter(v.toString()); How can this be message operation FSP model
ThreadPanel.rotate(180); modelled directly
or
send(e,chan) ? How would we
} without the need when Gn and vn=receive(chann) => Sn;
model this in FSP?
} catch (InterruptedException e){} for relabeling? v = receive(chan) ? end
}
Concurrency: message passing 7 Concurrency: message passing 8 Concurrency: message passing 9
} ©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

selective receive Java implementation - selective receive Java implementation - selective receive
public void run() {
CARPARK class MsgCarPark implements Runnable {
try {
private Channel arrive,depart;
ARRIVALS arrive CARPARK depart DEPARTURES Select sel = new Select();
CONTROL private int spaces,N;
sel.add(depart);
private StringCanvas disp;
sel.add(arrive);
while(true) {
public MsgCarPark(Channel a, Channel l,
CARPARKCONTROL(N=4) = SPACES[N], ThreadPanel.rotate(12);
StringCanvas d,int capacity) {
SPACES[i:0..N] = (when(i>0) arrive->SPACES[i-1] arrive.guard(spaces>0);
depart=l; arrive=a; N=spaces=capacity; disp=d;
depart.guard(spaces<N);
|when(i<N) depart->SPACES[i+1] }
switch (sel.choose()) {
). … Implement case 1:depart.receive();display(++spaces);
public void run() {…} CARPARKCONTROL as a
ARRIVALS = (arrive->ARRIVALS). break;
Implementation } thread MsgCarPark
DEPARTURES = (depart->DEPARTURES). case 2:arrive.receive();display(--spaces);
using message which receives signals break;
||CARPARK = (ARRIVALS||CARPARKCONTROL(4) passing? from channels arrive }
||DEPARTURES). and depart. } See
} catch InterrruptedException{} Applet
Concurrency: message passing 10 Concurrency: message passing 11 Concurrency: message passing 12
©Magee/Kramer ©Magee/Kramer } ©Magee/Kramer
10.2 Asynchronous Message Passing - port asynchronous message passing - applet Java implementation - port

Two senders class Port extends Selectable {


The
Port p communicate Vector queue = new Vector();
implementation
Sender
Sender Receiver with a receiver public synchronized void send(Object v){ of Port is a
Sender[n]
send(e,c) v=receive(p)
via an queue.addElement(v); monitor that has
send(e,c) “unbounded”
send(en,p) signal(); synchronized
many-to-one port. } access methods
Each sender for send and
public synchronized Object receive() receive.
sends a
♦ send(e,p) - send the ♦ v = receive(p) - receive sequence of
throws InterruptedException {
value of the expression e to a value into local variable v block(); clearReady();
integer values Port port = new Port(); Object tmp = queue.elementAt(0);
port p. The process calling from port p. The process from 0 to 9 and tx1.start(new Asender(port,send1disp)); queue.removeElementAt(0);
the send operation is not calling the receive then restarts at tx2.start(new Asender(port,send2disp)); return(tmp);
blocked. The message is operation is blocked if 0 again. rx.start(new Areceiver(port,recvdisp)); }
queued at the port if the there are no messages }
Instances of ThreadPanel Instances of SlotCanvas
receiver is not
Concurrency: message waiting.
passing queued to the port. 13 Concurrency: message passing 14 Concurrency: message passing 15
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

port model model of applet 10.3 Rendezvous - entry


range M = 0..9 // messages with values up to 9 AsynchMsg Rendezvous is a form of request-reply to support client
set S = {[M],[M][M]} // queue of up to three messages S[1..2]: server communication. Many clients may request service,
port:PORT ARECEIVER
PORT //empty state, only send permitted
ASENDER but only one is serviced at a time.
S[1..2].port.send port.receive
= (send[x:M]->PORT[x]),
PORT[h:M] //one message queued to port Client Server
= (send[x:M]->PORT[x][h]
ASENDER = ASENDER[0],
|receive[h]->PORT
ASENDER[e:M] = (port.send[e]->ASENDER[(e+1)%10]). res=call(entry,req)
),
Request
PORT[t:S][h:M] //two or more messages queued to port
= (send[x:M]->PORT[x][t][h]
ARECEIVER = (port.receive[v:M]->ARECEIVER). message req=accept(entry)
suspended
|receive[h]->PORT[t] perform service
||AsyncMsg = (s[1..2]:ASENDER || ARECEIVER||port:PORT)
).
LTS? /{s[1..2].port.send/port.send}. Reply
reply(entry,res)
message
// minimise to see result of abstracting from data values
||APORT = PORT/{send/send[M],receive/receive[M]}.
Safety?
Concurrency: message passing 16 Concurrency: message passing 17 Concurrency: message passing 18
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer
Rendezvous asynchronous message passing - applet Java implementation - entry

♦ res=call(e,req) - send the ♦ req=accept(e) - receive Two clients call a Entries are implemented as list
Select Selectable
server which services a extensions of ports, add() guard()
value req as a request the value of the request request at a time. thereby supporting queuing choose()

message which is queued to message from the entry e and selective receipt.
Channel Port
the entry e. into local variable req. The send() send()
calling process is blocked if The call method creates a
receive() receive()

there are no messages channel object on which to


queued to the entry. receive the reply message. Entry
clientChan
It constructs and sends to call()
♦The calling process is ♦ reply(e,res) - send the Entry entry = new Entry(); the entry a message
accept()
reply()
blocked until a reply message value res as a reply clA.start(new Client(entry,clientAdisp,"A")); consisting of a reference
is received into the local clB.start(new Client(entry,clientBdisp,"B")); to this channel and a The accept method keeps a copy of
message to entry e. sv.start(new Server(entry,serverdisp)); reference to the req the channel reference; the reply
variable req. object. It then awaits the method sends the reply message to
Instances of ThreadPanel reply on the channel. this channel.
Concurrency: message passing 19 Concurrency: message passing
Instances of SlotCanvas 20 Concurrency: message passing 21
©Magee/Kramer ©Magee/Kramer ©Magee/Kramer

Java implementation - entry model of entry and applet rendezvous Vs monitor method invocation
public class Entry extends Port { We reuse the models for ports and channels …
private CallMsg cm; What is the difference?
public Object call(Object req) throws InterruptedException { EntryDemo … from the point of view of the client?
Channel clientChan = new Channel();
send(new CallMsg(req,clientChan)); CLIENT() entry:ENTRY SERVER
return clientChan.receive();
… from the point of view of the server?
} entry.call[M] entry.accept
… mutual exclusion?
public Object accept()throws InterruptedException {
cm = (CallMsg) receive();
return cm.request; set M = {replyA,replyB} // reply channels
}
||ENTRY = PORT/{call/send, accept/receive}.
Which implementation is more efficient?
public void reply(Object res) throws InterruptedException {
cm.replychan.send(res); … in a local context (client and server in same computer)?
CLIENT(CH='reply) = (entry.call[CH]->[CH]->CLIENT).
}
SERVER = (entry.accept[ch:M]->[ch]->SERVER). … in a distributed context (in different computers)?
private class CallMsg { Action labels
Object request; Channel replychan;
CallMsg(Object m, Channel c) ||EntryDemo = (CLIENT('replyA)||CLIENT('replyB) used in
expressions or
Do call, accept and || entry:ENTRY || SERVER ).
{request=m; replychan=c;} as parameter
} reply need to be values must be
Concurrency:
} message passing synchronized methods?
22 Concurrency: message passing prefixed23with Concurrency: message passing 24
©Magee/Kramer a©Magee/Kramer
single quote. ©Magee/Kramer
Summary Course Outline
 Concepts ♦ Processes and Threads
 synchronous message passing – channel
 asynchronous message passing – port
♦ Concurrent Execution
- send and receive / selective receive ♦ Shared Objects & Interference
Concepts
 rendezvous bidirectional comms - entry
- call and accept ... reply
♦ Monitors & Condition Synchronization Models
 Models ♦ Deadlock Practice
 channel : relabelling, choice & guards ♦ Safety and Liveness Properties
 port : message queue, choice & guards
 entry : port & channel ♦ Model-based Design
 Practice ♦ Dynamic systems ♦Concurrent Software Architectures
 distributed computing (disjoint memory)
♦ Message Passing ♦Timed Systems
 threads and monitors (shared memory)
Concurrency: message passing 25 Concurrency: message passing 26
©Magee/Kramer ©Magee/Kramer
This is highlighted when LTSA is performing a computation, which could potentially take a long time such
LTSA User Manual as minimisation. Clicking on the Stop button will abort the activity.

www.doc.ic.ac.uk/~jnm/book/firstbook/ltsa/ltsa-doc/User- Target
manual.html The target choice box is used to select the composite process to be analysed. If there is only one composite
process then this is set automatically. If no composite process is specified then the target displays
User manual "DEFAULT" which is the composite process consisting of the composition of all primitive processes in the
current specification. For a specification with multiple composite processes, it is necessary to initialise the
target choice when a specification is first loaded by invoking Parse from the Build menu.

It is the hope of the designers of LTSA that this manual should be largely unnecessary. In most cases, the
user simply has to enter a specification in the FSP window and invoke one of the analysis functions from the
Check menu. LTSA will perform the necessary compilation and LTS composition.

Contents

LTSA Window

LTS construction - Build

Analysis functions - Check

Display functions - Window

LTSA Settings - Options

LTSA Window

The LTSA window has the following controls in addition to the menubar.

Edit Button

This brings the FSP window to the front. The FSP window is used to enter the FSP specification text to be
analysed. Text can be loaded from file (using the File menu) if LTSA is running as an application or it may
be pasted into the window if LTSA is running as an applet.
LTS construction - Build
Results Button

Brings the Output window to the front. This displays the results of analysis, error messages etc. This menu contains all the functions necessary to generate an LTS from an FSP description. However,
usually, it is not necessary to invoke these functions directly. For example, compilation is implicitly invoked
Stop Button if the description is changed between successive calls to the safety check function.

Parse

1/7 2/7
Performs a syntax check on the text in the FSP window. The location of the first error detected is Run
highlighted and an error message displayed in the output window. Consequently, errors are located and
fixed one at a time. Performs a user-controlled animation of the target composite process. Uses the component LTSs rather than
the composite LTS, so larger systems can be animated even if they cannot be exhaustively checked.
After a successful parse, the target choice will contain the list of composite processes. The visible process is DEFAULT is the alphabet of the target composite process and allows explicit contol of all actions. This
the target for compilation etc. In addition, the list of actions menu's available from Check/Run is updated. may be reduced by declaring an explicit menu e.g.

Compile menu RUN = {toss}

Generates an LTS for each of the component processes (whether primitive or composite) of the target The current state of each component LTS displayed in a Draw window is updated by the animator. By
composite process. After compilation, the component processes may be viewed either graphically or default, the Animator window includes Run and Step buttons. These are used to control actions which are
textually - see Window. Compile will automatically invoke parse if the FSP window has been changed since not in the action menu and consequently do not have click boxes. These buttons do not appear if the autorun
the last Compile (or Parse). However, if a new target or action menu is added, Parse must be invoked option is selected in the Options menu. The Run button permits a sequence of actions to occur where
explicitly to update the target and run lists these actions are not explicitly controlled. The Step button permits a single such action to occur.

Compose

Generates a single LTS by composing the component LTSs produced by compile for a specified target.
After composition, the LTS may be viewed graphically or textually. Error messages produced during
composition indicate safety property violations and deadlocks.

Minimise

Minimises the LTS produced by composition according to Milner's observation equivalence relation.

Reachable
Analysis functions - Check Performs an "on-the-fly" depth first search on the set of component LTS for the target. Since the composite
LTS is not required, this uses less storage than Safety. Property violations and deadlocks are detected,
however, no counter examples (traces) are produced.
The analysis functions operate on the target composite process indicated in the Target choice box. If this
has not been compiled or composed, compilation and composition are automatically invoked.

Safety

Performs a breadth first search on the target LTS. If a property violation or deadlock is found, the shortest Display functions - Window
trace of actions that would lead to the property violation or deadlock is displayed in the output window.

Progress Alphabet
Computes the connected components for the target LTS. Checks for progress violations with respect to the Displays the action alphabet for either the component process of a target or the target LTS itself. The
declared progress properties. If no progress properties are declared then a check with respect to a default alphabet is by default displayed concisely - actions with common prefixes are collected into sets or ranges.
property is performed. The default property has all the actions in the alphabet of the current target. The alphabet may also be viewed in an expanded form by choosing Expanded from the View menu. The

3/7 4/7
view can be adjusted between fully expanded and the concise view using Expand and Contract from
View.

Text
Displays as text the LTS for either the component process of a target or the target LTS itself. When LTSA is
running as an application, the textual representation may be saved to file.
A separate window for the process is created when the process is selected from the Draw menu. When
LTSA is running as an application, the graphical representation may be saved to file (in PICT format) from
this window. The Freeze Drawing while adjusting Window option under the File menu allows the LTS
graph to be repositioned inside the window before the PICT image is saved.

Draw
Displays graphically the LTS for either the component process of a target or the target LTS itself. A button
Options
for each process in the target appears at the left of the window. Clicking on the process button displays the
LTS for that process. During animation the process buttons for each process participating in the last action
to occur are coloured red.
Display warning messages

5/7 6/7
Displays a warning message when an undefined state is mapped to the ERROR state during compilation.
Default is set.

Treat warnings as errors

Halts compilation with an error message when an undefined state is found. Default is not set.

Minimise during Composition

If set, composite processes are minimised by default during compilation (ie. Composite processes which are
components of the target). Default is not set.

Use big font

Use large font in all windows. Useful for demonstrations and presentations. Default is not set.

Use arrows when drawing LTS

Transitions are always drawn clockwise, consequently, arrows are not strictly necessary. The LTS will
sometimes be clearer without arrows. Default is set.

Display name when drawing LTS

Displays the process name for an LTS in the Draw window. Defaults is not set.

Process Buttons in LTS Draw window

Enables process buttons in Draw window. Default is set.

Autorun actions in Animator

Removes Run and Step buttons from Animator window. Actions are selected until an action in the menu
set is enabled. Default is not set.

7/7
FSP Quick Reference Guide A.2 Composite Processes
http://www.doc.ic.ac.uk/~jnm/book/ltsa/Appendix-A-2e.html A composite process is the parallel composition of one or more processes. The definition of a composite
process is preceded by ||.

Appendix A Example

||Composite = (P || Q).
FSP Quick Reference
Parallel If P and Q are processes then (P||Q) represents the
Composition || concurrent execution of P and Q.
A.1 Processes Replicator forall [i:1..N] P(i) is the parallel composition (P(1) ||
forall … || P(N))
A process is defined by a one or more local processes separated by commas. The definition is terminated by Process a:P prefixes each label in the alphabet of P with a.
a full stop. STOP and ERROR are primitive local processes. Labeling :
Process {a1,..,ax}::P replaces every label n in the
Example Sharing :: alphabet of P with the labels a1.n,…,ax.n. Further,
every transition (n->Q) in the definition of P is
Process = (a -> Local), replaced with the transitions ({a1.n,…,ax.n}->Q).
Priority High ||C =(P||Q)<<{a1,…,an} specifies a
Local = (b -> STOP). << composition in which the actions a1,…,an have
higher priority than any other action in the alphabet
Action Prefix - If x is an action and P a process then (x->P) of P||Q including the silent action tau. In any
> describes a process that initially engages in the choice in this system which has one or more of the
action x and then behaves exactly as described by P. actions a1,…,an labeling a transition, the
Choice | If x and y are actions then (x->P|y->Q) transitions labeled with lower priority actions are
describes a process which initially engages in either discarded.
of the actions x or y. After the first action has Priority Low >> ||C=(P||Q)>>{a1,…,an} specifies a
occurred, the subsequent behavior is described by P composition in which the actions a1,…,an have
if the first action was x and Q if the first action was lower priority than any other action in the alphabet
y. of P||Q including the silent action tau. In any
Guarded Action The choice (when B x -> P | y -> Q) choice in this system which has one or more
when means that when the guard B is true then the actions transitions not labeled by a1,…,an, the transitions
x and y are both eligible to be chosen, otherwise if B labeled by a1,…,an are discarded.
is false then the action x cannot be chosen.
Alphabet The alphabet of a process is the set of actions in Table A.2 – Composite Process Operators
Extension + which it can engage. P + S extends the alphabet of
the process P with the actions in the set S.

Table A.1 – Process operators

1/4 2/4
A.3 Common Operators A.5 FLTL – Fluent Linear Temporal Logic
The operators in Table A.3 may be used in the definition of both processes and composite processes. Fluent fluent FL = <{s1,…sn}, {e1..en}>
fluent initially B defines a fluent FL that is
Conditional The process if B then P else Q behaves as the initially true if the expression B is true and initially
if then process P if the condition B is true otherwise it false if the expression B is false. FL becomes true
else behaves as Q. If the else Q is omitted and B is false, immediately any of the initiating actions
then the process behaves as STOP. {s1,…sn}occur and false immediately any of the
Re-labeling / Re-labeling is applied to a process to change the terminating actions {e1..en} occur. If the term
names of action labels. The general form of re- initially B is omitted then FL is initially
labeling is: false.
/{newlabel_1/oldlabel_1,… Assertion assert PF = FLTL_Expression defines an
newlabel_n/oldlabel_n}. assert FLTL property.
Hiding \ When applied to a process P, the hiding operator
\{a1..ax} removes the action names a1..ax from the && conjunction (and)
alphabet of P and makes these concealed actions
"silent". These silent actions are labeled tau. Silent || disjunction (or)
actions in different processes are not shared. ! negation (not)
Interface @ When applied to a process P, the interface operator
@{a1..ax} hides all actions in the alphabet of P not -> implication ((A->B)≡ (!A || B))
labeled in the set a1..ax.
<-> equivalence ((A<->B) ≡(A->B)&&(B->A))

Table A.3 – Common Process Operators next time X F iff F holds in the next instant.

always []F iff F holds now and always in the future.


A.4 Properties eventually <>F iff F holds at some point in the future.

Safety A safety property P defines a deterministic until P U Q iff Q holds at some point in the future and P holds
property process that asserts that any trace including actions until then.
in the alphabet of P, is accepted by P.
Progress progress P = {a1,a2..an} defines a weak until P W iff P holds indefinitely or P U Q
Q
progress progress property P which asserts that in an infinite
execution of a target system, at least one of the forall forall [i:R] FL(i) conjunction of FL(i)
actions a1,a2..an will be executed infinitely often.
exists exists [i:R] FL(i) disjunction of FL(i)
Table A.4 – Safety and Progress Properties

Table A.5 – Fluent Linear Temporal Logic

3/4 4/4

View publication stats

You might also like