View
215
Download
1
Embed Size (px)
Citation preview
CSE 335: Software Design K. Stirewalt
Administrivia
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
CSE 335: Software Design K. Stirewalt
Software 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
CSE 335: Software Design K. Stirewalt
Outline 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
CSE 335: Software Design K. Stirewalt
Analytical 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
CSE 335: Software Design K. Stirewalt
State 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
CSE 335: Software Design K. Stirewalt
Communication 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
CSE 335: Software Design K. Stirewalt
Simple example: Client using a queue
q : Queuec1 : Client
System comprises two objectsEach object modeled by a state machineSystem state at any time is the pair (state of c1, state of q)
CSE 335: Software Design K. Stirewalt
Exercise
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 queue<string>
CSE 335: Software Design K. Stirewalt
Modeling 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
CSE 335: Software Design K. Stirewalt
Example
Waiting... / send S.mCall(this, ...) mRet(...)
ProcessingBody of M
... / send caller.mRet(...)mCall(caller, ...)
Client
Supplier
CSE 335: Software Design K. Stirewalt
Example: Client model
do / processString(b,s)
/ send q.pullCall(this)WaitingInitializing
pullReturn(b,s)
Client
CSE 335: Software Design K. Stirewalt
Example: Shared queue
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(false,empty)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmpty do / s := q.back
[q.empty()]
[!q.empty()]
CSE 335: Software Design K. Stirewalt
Recall: Two active clients sharing a queue
q : Queue
c1 : Client c2 : Client
q q
CSE 335: Software Design K. Stirewalt
Question
Do our state diagrams for classes Client and Queue accurately model the behaviors of active clients acting on a shared queue?
CSE 335: Software Design K. Stirewalt
Question
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
CSE 335: Software Design K. Stirewalt
Semantics 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?
CSE 335: Software Design K. Stirewalt
UML 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
CSE 335: Software Design K. Stirewalt
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(false,empty)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmpty do / s := q.back
[q.empty()]
[!q.empty()]
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
c1’s pool: c2’s pool:
q’s pool:
CSE 335: Software Design K. Stirewalt
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(false,empty)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmpty do / s := q.back
[q.empty()]
[!q.empty()]
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
c1’s pool: c2’s pool:
q’s pool:
CSE 335: Software Design K. Stirewalt
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(false,empty)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmpty do / s := q.back
[q.empty()]
[!q.empty()]
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
c1’s pool: c2’s pool:
q’s pool:
CSE 335: Software Design K. Stirewalt
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(false,empty)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmpty do / s := q.back
[q.empty()]
[!q.empty()]
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
q’s pool: pullCall(c1)
c1’s pool: c2’s pool:
CSE 335: Software Design K. Stirewalt
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(false,empty)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmpty do / s := q.back
[q.empty()]
[!q.empty()]
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
q’s pool:
c2’s pool:c1’s pool:
CSE 335: Software Design K. Stirewalt
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(false,empty)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmpty do / s := q.back
[q.empty()]
[!q.empty()]
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
q’s pool: pullCall(c2)
c2’s pool:c1’s pool:
CSE 335: Software Design K. Stirewalt
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(false,empty)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmpty do / s := q.back
[q.empty()]
[!q.empty()]
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
q’s pool: pullCall(c2)
c2’s pool:c1’s pool:
CSE 335: Software Design K. Stirewalt
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(false,empty)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmpty do / s := q.back
[q.empty()]
[!q.empty()]
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
do / processString(b,s)
/ send q.pullCall(this)
WaitingInitializing
pullReturn(b,s)
Client
c1’s pool: pullRet(false, empty)
q’s pool: pullCall(c2)
c2’s pool:
CSE 335: Software Design K. Stirewalt
Observations
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”
CSE 335: Software Design K. Stirewalt
Observations (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?
CSE 335: Software Design K. Stirewalt
More precisely…
How could we model the shared queue as a state machine that admits the behaviors on the following slide?
CSE 335: Software Design K. Stirewalt
Example
q :Queue c2 : …c1 : …
pull
empty
back
pop
pull
empty
back
pop
CSE 335: Software Design K. Stirewalt
Answer
Duplicate an object’s 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
CSE 335: Software Design K. Stirewalt
Example: Shared queue
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
CSE 335: Software Design K. Stirewalt
Initial state of shared queue
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
CSE 335: Software Design K. Stirewalt
Client c1 invokes pull…
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
CSE 335: Software Design K. Stirewalt
Queue is not empty…
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
CSE 335: Software Design K. Stirewalt
At this point, context switch and client c2 invokes pull…
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
CSE 335: Software Design K. Stirewalt
C1 has yet to pop queue; so c2’s check for empty fails
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
CSE 335: Software Design K. Stirewalt
Bad state! If queue contained only one element…
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
Idle
ProcessingPullCall
Checking
/ send caller.pullRet(…)
/ send caller.pullRet(true,s)
pullCall(caller)
Empty
NotEmptydo / s := q.back
[q.empty()]
[!q.empty()]
CSE 335: Software Design K. Stirewalt
Question
Assuming this interpretation of passive objects, how would we model the promotion of shared queue to a monitor?
CSE 335: Software Design K. Stirewalt
Question
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
CSE 335: Software Design K. Stirewalt
Model 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
CSE 335: Software Design K. Stirewalt
Wrap-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
CSE 335: Software Design K. Stirewalt
Question
What does it mean to transition out of a concurrent composite state?
CSE 335: Software Design K. Stirewalt
Question
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
CSE 335: Software Design K. Stirewalt
Example: Bridge game
E-W winsrubber
N-S winsrubber
Vulnerable
VulnerableNot
Vulnerable
NotVulnerable
ns-game ns-game
ew-game ew-game
PlayingRubber
Note: Transition out of PlayingRubber by one concurrent activity terminates the other
CSE 335: Software Design K. Stirewalt
Example: Cash dispenser
SetUp Completedo/ dispenseCash
do/ ejectCard
ready
Emitting
Note: Will not transition out of Emitting until after completion of all concurrent activities
CSE 335: Software Design K. Stirewalt
Recall: 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
CSE 335: Software Design K. Stirewalt
Example: Concurrent composite state
TempOff
Automobile
Cooling
Heating
pushHeat pushAir
TempOn
pushHeat
pushAir
pushTCOff
Temperature control
Rear defroster
RDOff RDOnpushRD
pushRDRadOff RadOn
pushRad
pushRad
Radio control