Title: Administrivia
1Administrivia
- Last homework will be 9, assigned later this
week - Thus, need to complete 7 of 9 rather than 8 of 10
to receive 5 hw credit. - Exam 3 Next Monday (4/23) from 7-9pm, 1279
Anthony Hall - Topic Architectural design issues
- Includes assessment component on the use of state
diagrams for reasoning about concurrency - This component cannot count against you, but
could help if you score well on it - Extra credit option 1 Next Monday (4/23) during
lecture period
2Software Architecture and Larger System Design
Issues Lecture 6 Advanced state
modeling/analysis
- Topics
- Modeling/analyzing concurrent behaviors using UML
state diagrams - Chapter 6 in Blaha and Rumbaugh
- Additional topics not in the Blaha/Rumbaugh book
3Outline of course topics
- Foundational OO concepts
- Synthetic concepts
- Software architecture and larger design issues
- Strategic design decisions that influence a host
of smaller, more tactical design decisions - E.g., policy for persistence of data in
long-running system - E.g., allocating functionality to a single,
centralized system vs. distributing functionality
among a collection of communicating hosts - Often involve a major capital investment
- Source of both risk and opportunity
- Require lots of a priori modeling and analysis
- Focus Design issues related to concurrent and
distributed systems - Software process issues
4Analytical models of behavior
- Thus far, the models we have employed have proved
useful for - documentation/explanation
- roughing out a design prior to implementation
- Still, they are not very rigorous
- E.g., sequence diagrams depict only one scenario
of interaction among objects - Not good for reasoning about space of possible
behaviors - Such reasoning requires more formal and complete
models of behavior
5State diagrams
- Useful for modeling space of behaviors of an
object or a system of interacting objects - Requires
- Identifying and naming the conceptual states
that an object might be in, and - Conceivable transitions among those states and
the events (and/or conditions) that trigger
(and/or guard) these transitions - Concurrent compositions of state diagrams can be
executed to expose anomalous behaviors
6Communication among concurrent state machines
- More interesting applications involve interaction
(explicit communication) among state machines - Examples
- Active client objects interacting with a shared
queue - Sensor object notifying a software controller
- Perhaps even an object invoking a method on
another - UML provides send actions by which one machine
may signal another
7Simple example Client using a queue
q Queue
c1 Client
System comprises two objects Each object modeled
by a state machine System state at any time is
the pair (state of c1, state of q)
8Exercise
- Develop state models for a simple client and a
queue, assuming - class Client does nothing but repeatedly pull
items off of the queue - class Queue provides an operation pull, which is
implemented by calling empty, back, and pop on a
private data member of type queueltstringgt
9Modeling method invocations
- Given state machines for two objects C and S,
where C is the client and S the supplier of a
method m - Model call and return of m as separate signals
- C sends the call signal to S and then enters a
waiting state, which is exited upon reception of
a return signal from S
10Example
Client
... / send S.mCall(this, ...)
mRet(...)
Waiting
Supplier
mCall(caller, ...)
... / send caller.mRet(...)
Processing Body of M
11Example Client model
Client
/ send q.pullCall(this)
Waiting
Initializing
pullReturn(b,s)
do / processString(b,s)
12Example Shared queue
ProcessingPullCall
Idle
pullCall(caller)
!q.empty()
Checking
q.empty()
/ send caller.pullRet(false,empty)
Empty
/ send caller.pullRet(true,s)
NotEmpty do / s q.back
13Recall Two active clients sharing a queue
q
q
q Queue
14Question
- Do our state diagrams for classes Client and
Queue accurately model the behaviors of active
clients acting on a shared queue?
15Question
- Do our state diagrams for classes Client and
Queue accurately model the behaviors of active
clients acting on a shared queue? - Answer really depends upon the semantics of
event handling among concurrent state machines
16Semantics of parallel composition
- Multiple interpretations
- Concurrent regions execute independently
- What happens if transitions in different regions
are triggered by same event? - Do both execute simultaneously? Does one
consume the event to the exclusion of the
other? Does each get a separate copy of the
event? - Concurrent regions communicate with one another,
synchronizing on common events - Regions can only proceed when all are ready to
proceed - Regions transfer data values during a concurrent
transition - Do we distinguish internal and external events?
17UML 2.0 Interpretation Asynchronous events run
to completion
- Run-to-completion semantics
- State machine processes one event at a time and
finishes all consequences of that event before
processing another event - Events do not interact with one another during
processing - Event pool
- Where new events for an object are stored until
object is ready to process them - No event ordering assumed in the pool
18c1s pool
c2s pool
Client
Client
/ send q.pullCall(this)
/ send q.pullCall(this)
Waiting
Initializing
Waiting
Initializing
pullReturn(b,s)
pullReturn(b,s)
do / processString(b,s)
do / processString(b,s)
qs pool
ProcessingPullCall
pullCall(caller)
!q.empty()
Idle
Checking
q.empty()
/ send caller.pullRet(false,empty)
Empty
/ send caller.pullRet(true,s)
NotEmpty do / s q.back
19c1s pool
c2s pool
Client
Client
/ send q.pullCall(this)
/ send q.pullCall(this)
Waiting
Initializing
Waiting
Initializing
pullReturn(b,s)
pullReturn(b,s)
do / processString(b,s)
do / processString(b,s)
qs pool
ProcessingPullCall
pullCall(caller)
!q.empty()
Idle
Checking
q.empty()
/ send caller.pullRet(false,empty)
Empty
/ send caller.pullRet(true,s)
NotEmpty do / s q.back
20c1s pool
c2s pool
Client
Client
/ send q.pullCall(this)
/ send q.pullCall(this)
Waiting
Initializing
Waiting
Initializing
pullReturn(b,s)
pullReturn(b,s)
do / processString(b,s)
do / processString(b,s)
qs pool
ProcessingPullCall
pullCall(caller)
!q.empty()
Idle
Checking
q.empty()
/ send caller.pullRet(false,empty)
Empty
/ send caller.pullRet(true,s)
NotEmpty do / s q.back
21c1s pool
c2s pool
Client
Client
/ send q.pullCall(this)
/ send q.pullCall(this)
Waiting
Initializing
Waiting
Initializing
pullReturn(b,s)
pullReturn(b,s)
do / processString(b,s)
do / processString(b,s)
qs pool pullCall(c1)
ProcessingPullCall
pullCall(caller)
!q.empty()
Idle
Checking
q.empty()
/ send caller.pullRet(false,empty)
Empty
/ send caller.pullRet(true,s)
NotEmpty do / s q.back
22c2s pool
c1s pool
Client
Client
/ send q.pullCall(this)
/ send q.pullCall(this)
Waiting
Initializing
Waiting
Initializing
pullReturn(b,s)
pullReturn(b,s)
do / processString(b,s)
do / processString(b,s)
qs pool
ProcessingPullCall
pullCall(caller)
!q.empty()
Idle
Checking
q.empty()
/ send caller.pullRet(false,empty)
Empty
/ send caller.pullRet(true,s)
NotEmpty do / s q.back
23c2s pool
c1s pool
Client
Client
/ send q.pullCall(this)
/ send q.pullCall(this)
Waiting
Initializing
Waiting
Initializing
pullReturn(b,s)
pullReturn(b,s)
do / processString(b,s)
do / processString(b,s)
qs pool pullCall(c2)
ProcessingPullCall
pullCall(caller)
!q.empty()
Idle
Checking
q.empty()
/ send caller.pullRet(false,empty)
Empty
/ send caller.pullRet(true,s)
NotEmpty do / s q.back
24c2s pool
c1s pool
Client
Client
/ send q.pullCall(this)
/ send q.pullCall(this)
Waiting
Initializing
Waiting
Initializing
pullReturn(b,s)
pullReturn(b,s)
do / processString(b,s)
do / processString(b,s)
qs pool pullCall(c2)
ProcessingPullCall
pullCall(caller)
!q.empty()
Idle
Checking
q.empty()
/ send caller.pullRet(false,empty)
Empty
/ send caller.pullRet(true,s)
NotEmpty do / s q.back
25c1s pool pullRet(false, empty)
c2s pool
Client
Client
/ send q.pullCall(this)
/ send q.pullCall(this)
Waiting
Initializing
Waiting
Initializing
pullReturn(b,s)
pullReturn(b,s)
do / processString(b,s)
do / processString(b,s)
qs pool pullCall(c2)
ProcessingPullCall
pullCall(caller)
!q.empty()
Idle
Checking
q.empty()
/ send caller.pullRet(false,empty)
Empty
/ send caller.pullRet(true,s)
NotEmpty do / s q.back
26Observations
- Modeling method invocations as asynchronous
events which are placed in a pool - Requests for service on an object
- buffered up on arrival
- dispatched when the object is ready to handle
them - Natural interpretation for how an active object
can be invoked - Makes passive objects appear to execute with
monitor semantics
27Observations (continued)
- In real programs, not every passive object is (or
should be) a monitor - There is some expense associated with acquiring
more locks than are needed to synchronize threads - Se often want to analyze a system to choose which
passive objects should be monitors. - How could we use state-machine models for this
purpose?
28More precisely
- How could we model the shared queue as a state
machine that admits the behaviors on the
following slide?
29Example
q Queue
c2
c1
pull
empty
pull
empty
back
pop
back
pop
30Answer
- Duplicate an objects state model with one copy
for each system thread - Note This will need to be done for each passive
object, and it will potentially cause the number
of states in the system to grow out of control
31Example Shared queue
32Initial state of shared queue
33Client c1 invokes pull
34Queue is not empty
ProcessingPullCall
pullCall(caller)
!q.empty()
Idle
Checking
q.empty()
Empty
/ send caller.pullRet()
NotEmpty do / s q.back
/ send caller.pullRet(true,s)
35At this point, context switch and client c2
invokes pull
36C1 has yet to pop queue so c2s check for empty
fails
37Bad state! If queue contained only one element
38Question
- Assuming this interpretation of passive objects,
how would we model the promotion of shared queue
to a monitor?
39Question
- Assuming this interpretation of passive objects,
how would we model the promotion of shared queue
to a monitor? - Answer Two ways
- Model the lock explicitly as another state
machine - Use only a single state machine model for queue
rather than replicating per thread
40Model checking
- Technique for exhaustively and automatically
analyzing finite-state models to find bad
states - Bad states are specified in a temporal logic or
some other declarative notation - Lots of tools that can be used for this purpose
- FSP, SMV, Spin, etc
- If you are designing concurrent software, want to
learn how to use these tools
41Wrap-up Use of models
- In this course, we have now used models for many
purposes - Documentation and demonstration of
characteristics of a complex design - Means for understanding the requirements of a
system to be built - Analysis for tricky concurrency properties
42Question
- What does it mean to transition out of a
concurrent composite state?
43Question
- What does it mean to transition out of a
concurrent composite state? - Two possible answers
- transition awaits completion of all concurrent
activities - transition acts immediately, terminating all
concurrent activities
44Example Bridge game
PlayingRubber
N-S wins rubber
Not Vulnerable
ns-game
ns-game
Vulnerable
E-W wins rubber
Not Vulnerable
ew-game
ew-game
Vulnerable
Note Transition out of PlayingRubber by one
concurrent activity terminates the other
45Example Cash dispenser
Emitting
do/ dispenseCash
ready
SetUp
Complete
do/ ejectCard
Note Will not transition out of Emitting until
after completion of all concurrent activities
46Recall State explosion problem
- Number of states in a system with multiple,
orthogonal, behaviors grows exponentially
(product of number of states of each feature) - Major impediment to understanding
- Impossible to visualize in any meaningful way
- Requires the use of analysis tools to verify
properties - Managing state explosion
- Concurrent state machines
- Each object in a system modeled as a state
machine - Object state machine runs concurrently with those
of other objects - Concurrent composite states
- Separates one machine can into orthogonal
submachines
47Example Concurrent composite state
Automobile
Temperature control
TempOn
pushAir
Cooling
pushTCOff
TempOff
pushHeat
pushAir
Heating
pushHeat
Rear defroster
Radio control
pushRD
pushRad
RDOff
RDOn
RadOff
RadOn
pushRD
pushRad