698 lines
No EOL
53 KiB
HTML
698 lines
No EOL
53 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
|
||
|
||
|
||
<html lang="en">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
||
<title>1.5. State Models in UML — Computer Systems Fundamentals</title>
|
||
|
||
<link rel="stylesheet" href="_static/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
|
||
<link rel="stylesheet" href="_static/css/pygments.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/normalize.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../JSAV/css/JSAV.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../lib/odsaMOD-min.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/jquery-1.11.4-smoothness-ui.css" type="text/css" />
|
||
<link rel="stylesheet" href="../../../lib/odsaStyle-min.css" type="text/css" />
|
||
<link rel="stylesheet" href="_static/css/csf.css" type="text/css" />
|
||
|
||
<style>
|
||
.underline { text-decoration: underline; }
|
||
</style>
|
||
|
||
<script type="text/javascript">
|
||
var DOCUMENTATION_OPTIONS = {
|
||
URL_ROOT: './',
|
||
VERSION: '0.4.1',
|
||
COLLAPSE_INDEX: false,
|
||
FILE_SUFFIX: '.html',
|
||
HAS_SOURCE: true
|
||
};
|
||
</script>
|
||
|
||
<script type="text/x-mathjax-config">
|
||
MathJax.Hub.Config({
|
||
tex2jax: {
|
||
inlineMath: [['$','$'], ['\\(','\\)']],
|
||
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
|
||
processEscapes: true
|
||
},
|
||
"HTML-CSS": {
|
||
scale: "80"
|
||
}
|
||
});
|
||
</script>
|
||
<link rel="shortcut icon" href="_static/favicon.ico"/>
|
||
<link rel="index" title="Index" href="genindex.html" />
|
||
<link rel="search" title="Search" href="search.html" />
|
||
<link rel="index" title="Computer Systems Fundamentals" href="index.html" />
|
||
<link rel="next" title="6. Sequence Models in UML" href="SequenceModels.html" />
|
||
<link rel="prev" title="4. System Architectures" href="Architectures.html" />
|
||
|
||
</head><body>
|
||
|
||
<nav class="navbar navbar-expand-md navbar-dark navbar-custom fixed-top">
|
||
|
||
<a class="navbar-brand py-0" href="index.html"><img src="_static/CSF-Logo-Square-Text.png" alt="OpenCSF Logo" height="40em" class="py-1 px-2 mb-0 align-center rounded-lg bg-white" /></a>
|
||
<!-- Show a navbar toggler on mobile -->
|
||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#defaultNavbars" aria-controls="defaultNavbars" aria-expanded="false" aria-label="Toggle navigation">
|
||
<span class="navbar-toggler-icon"></span>
|
||
</button>
|
||
<div class="collapse navbar-collapse" id="defaultNavbars">
|
||
<ul class="navbar-nav mr-auto">
|
||
<li class="nav-item dropdown">
|
||
<a class="nav-link dropdown-toggle jmu-gold rounded" href="StateModels.html#" id="navbarDropdownChapters" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Contents</a>
|
||
<div class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="navbarDropdownChapters">
|
||
<a class="dropdown-item" tabindex="-1" href="StateModels.html#"><b>Chapter 1</b></a>
|
||
<a class="dropdown-item" href="IntroConcSysOverview.html"> 1.1. Introduction to Concurrent Systems</a>
|
||
<a class="dropdown-item" href="SysAndModels.html"> 1.2. Systems and Models</a>
|
||
<a class="dropdown-item" href="Themes.html"> 1.3. Themes and Guiding Principles</a>
|
||
<a class="dropdown-item" href="Architectures.html"> 1.4. System Architectures</a>
|
||
<a class="dropdown-item" href="StateModels.html"> 1.5. State Models in UML</a>
|
||
<a class="dropdown-item" href="SequenceModels.html"> 1.6. Sequence Models in UML</a>
|
||
<a class="dropdown-item" href="StateModelImplementation.html"> 1.7. Extended Example: State Model Implementation</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 2</b></a>
|
||
<a class="dropdown-item" href="ProcessesOverview.html"> 2.1. Processes and OS Basics</a>
|
||
<a class="dropdown-item" href="Multiprogramming.html"> 2.2. Processes and Multiprogramming</a>
|
||
<a class="dropdown-item" href="KernelMechanics.html"> 2.3. Kernel Mechanics</a>
|
||
<a class="dropdown-item" href="Syscall.html"> 2.4. System Call Interface</a>
|
||
<a class="dropdown-item" href="ProcessCycle.html"> 2.5. Process Life Cycle</a>
|
||
<a class="dropdown-item" href="UnixFile.html"> 2.6. The UNIX File Abstraction</a>
|
||
<a class="dropdown-item" href="EventsSignals.html"> 2.7. Events and Signals</a>
|
||
<a class="dropdown-item" href="Extended2Processes.html"> 2.8. Extended Example: Listing Files with Processes</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 3</b></a>
|
||
<a class="dropdown-item" href="IPCOverview.html"> 3.1. Concurrency with IPC</a>
|
||
<a class="dropdown-item" href="IPCModels.html"> 3.2. IPC Models</a>
|
||
<a class="dropdown-item" href="Pipes.html"> 3.3. Pipes and FIFOs</a>
|
||
<a class="dropdown-item" href="MMap.html"> 3.4. Shared Memory With Memory-mapped Files</a>
|
||
<a class="dropdown-item" href="POSIXvSysV.html"> 3.5. POSIX vs. System V IPC</a>
|
||
<a class="dropdown-item" href="MQueues.html"> 3.6. Message Passing With Message Queues</a>
|
||
<a class="dropdown-item" href="ShMem.html"> 3.7. Shared Memory</a>
|
||
<a class="dropdown-item" href="IPCSems.html"> 3.8. Semaphores</a>
|
||
<a class="dropdown-item" href="Extended3Bash.html"> 3.9. Extended Example: Bash-lite: A Simple Command-line Shell</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 4</b></a>
|
||
<a class="dropdown-item" href="SocketsOverview.html"> 4.1. Networked Concurrency</a>
|
||
<a class="dropdown-item" href="FiveLayer.html"> 4.2. The TCP/IP Internet Model</a>
|
||
<a class="dropdown-item" href="NetApps.html"> 4.3. Network Applications and Protocols</a>
|
||
<a class="dropdown-item" href="Sockets.html"> 4.4. The Socket Interface</a>
|
||
<a class="dropdown-item" href="TCPSockets.html"> 4.5. TCP Socket Programming: HTTP</a>
|
||
<a class="dropdown-item" href="UDPSockets.html"> 4.6. UDP Socket Programming: DNS</a>
|
||
<a class="dropdown-item" href="AppBroadcast.html"> 4.7. Application-Layer Broadcasting: DHCP</a>
|
||
<a class="dropdown-item" href="Extended4CGI.html"> 4.8. Extended Example: CGI Web Server</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 5</b></a>
|
||
<a class="dropdown-item" href="InternetOverview.html"> 5.1. The Internet and Connectivity</a>
|
||
<a class="dropdown-item" href="AppLayer.html"> 5.2. Application Layer: Overlay Networks</a>
|
||
<a class="dropdown-item" href="TransLayer.html"> 5.3. Transport Layer</a>
|
||
<a class="dropdown-item" href="NetSec.html"> 5.4. Network Security Fundamentals</a>
|
||
<a class="dropdown-item" href="NetLayer.html"> 5.5. Network Layer: IP</a>
|
||
<a class="dropdown-item" href="LinkLayer.html"> 5.6. Link Layer</a>
|
||
<a class="dropdown-item" href="Wireless.html"> 5.7. Wireless Connectivity: Wi-Fi, Bluetooth, and Zigbee</a>
|
||
<a class="dropdown-item" href="Extended5DNS.html"> 5.8. Extended Example: DNS client</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 6</b></a>
|
||
<a class="dropdown-item" href="ThreadsOverview.html"> 6.1. Concurrency with Multithreading</a>
|
||
<a class="dropdown-item" href="ProcVThreads.html"> 6.2. Processes vs. Threads</a>
|
||
<a class="dropdown-item" href="RaceConditions.html"> 6.3. Race Conditions and Critical Sections</a>
|
||
<a class="dropdown-item" href="POSIXThreads.html"> 6.4. POSIX Thread Library</a>
|
||
<a class="dropdown-item" href="ThreadArgs.html"> 6.5. Thread Arguments and Return Values</a>
|
||
<a class="dropdown-item" href="ImplicitThreads.html"> 6.6. Implicit Threading and Language-based Threads</a>
|
||
<a class="dropdown-item" href="Extended6Input.html"> 6.7. Extended Example: Keyboard Input Listener</a>
|
||
<a class="dropdown-item" href="Extended6Primes.html"> 6.8. Extended Example: Concurrent Prime Number Search</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 7</b></a>
|
||
<a class="dropdown-item" href="SynchOverview.html"> 7.1. Synchronization Primitives</a>
|
||
<a class="dropdown-item" href="CritSect.html"> 7.2. Critical Sections and Peterson's Solution</a>
|
||
<a class="dropdown-item" href="Locks.html"> 7.3. Locks</a>
|
||
<a class="dropdown-item" href="Semaphores.html"> 7.4. Semaphores</a>
|
||
<a class="dropdown-item" href="Barriers.html"> 7.5. Barriers</a>
|
||
<a class="dropdown-item" href="Condvars.html"> 7.6. Condition Variables</a>
|
||
<a class="dropdown-item" href="Deadlock.html"> 7.7. Deadlock</a>
|
||
<a class="dropdown-item" href="Extended7Events.html"> 7.8. Extended Example: Event Log File</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 8</b></a>
|
||
<a class="dropdown-item" href="SynchProblemsOverview.html"> 8.1. Synchronization Patterns and Problems</a>
|
||
<a class="dropdown-item" href="SynchDesign.html"> 8.2. Basic Synchronization Design Patterns</a>
|
||
<a class="dropdown-item" href="ProdCons.html"> 8.3. Producer-Consumer Problem</a>
|
||
<a class="dropdown-item" href="ReadWrite.html"> 8.4. Readers-Writers Problem</a>
|
||
<a class="dropdown-item" href="DiningPhil.html"> 8.5. Dining Philosophers Problem and Deadlock</a>
|
||
<a class="dropdown-item" href="CigSmokers.html"> 8.6. Cigarette Smokers Problem and the Limits of Semaphores and Locks</a>
|
||
<a class="dropdown-item" href="Extended8ModExp.html"> 8.7. Extended Example: Parallel Modular Exponentiation</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Chapter 9</b></a>
|
||
<a class="dropdown-item" href="ParallelDistributedOverview.html"> 9.1. Parallel and Distributed Systems</a>
|
||
<a class="dropdown-item" href="ParVConc.html"> 9.2. Parallelism vs. Concurrency</a>
|
||
<a class="dropdown-item" href="ParallelDesign.html"> 9.3. Parallel Design Patterns</a>
|
||
<a class="dropdown-item" href="Scaling.html"> 9.4. Limits of Parallelism and Scaling</a>
|
||
<a class="dropdown-item" href="DistTiming.html"> 9.5. Timing in Distributed Environments</a>
|
||
<a class="dropdown-item" href="DistDataStorage.html"> 9.6. Reliable Data Storage and Location</a>
|
||
<a class="dropdown-item" href="DistConsensus.html"> 9.7. Consensus in Distributed Systems</a>
|
||
<a class="dropdown-item" href="Extended9Blockchain.html"> 9.8. Extended Example: Blockchain Proof-of-Work</a>
|
||
<div class="dropdown-divider"></div>
|
||
<a class="dropdown-item disabled"><b>Appendix A</b></a>
|
||
<a class="dropdown-item" href="CLangOverview.html"> A.1. C Language Reintroduction</a>
|
||
<a class="dropdown-item" href="Debugging.html"> A.2. Documentation and Debugging</a>
|
||
<a class="dropdown-item" href="BasicTypes.html"> A.3. Basic Types and Pointers</a>
|
||
<a class="dropdown-item" href="Arrays.html"> A.4. Arrays, Structs, Enums, and Type Definitions</a>
|
||
<a class="dropdown-item" href="Functions.html"> A.5. Functions and Scope</a>
|
||
<a class="dropdown-item" href="Pointers.html"> A.6. Pointers and Dynamic Allocation</a>
|
||
<a class="dropdown-item" href="Strings.html"> A.7. Strings</a>
|
||
<a class="dropdown-item" href="FunctionPointers.html"> A.8. Function Pointers</a>
|
||
<a class="dropdown-item" href="Files.html"> A.9. Files</a>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||
<li class="nav-item"><a class="nav-link jmu-gold" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/source/StateModels.rst"
|
||
target="_blank" rel="nofollow">Show Source</a></li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
|
||
<div class="container center">
|
||
«  <a id="prevmod" href="Architectures.html">1.4. System Architectures</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod" href="SequenceModels.html">1.6. Sequence Models in UML</a>  »
|
||
|
||
</div>
|
||
<br />
|
||
|
||
|
||
|
||
<script type="text/javascript" src="_static/js/jquery-2.1.4.min.js"></script>
|
||
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||
<script type="text/javascript" src="_static/js/jquery-1.11.4-ui.min.js"></script>
|
||
<script type="text/javascript" src="_static/js/forge-0.7.0.min.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/lib/jquery.transit.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/lib/raphael.js"></script>
|
||
<script type="text/javascript" src="../../../JSAV/build/JSAV-min.js"></script>
|
||
<script type="text/javascript" src="_static/js/config.js"></script>
|
||
<script type="text/javascript" src="../../../lib/odsaUtils-min.js"></script>
|
||
<script type="text/javascript" src="../../../lib/odsaMOD-min.js"></script>
|
||
<script type="text/javascript" src="_static/js/d3-4.13.0.min.js"></script>
|
||
<script type="text/javascript" src="_static/js/d3-selection-multi.v1.min.js"></script>
|
||
<script type="text/javascript" src="../../../lib/dataStructures.js"></script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="container">
|
||
|
||
<script>ODSA.SETTINGS.DISP_MOD_COMP = true;ODSA.SETTINGS.MODULE_NAME = "StateModels";ODSA.SETTINGS.MODULE_LONG_NAME = "State Models in UML";ODSA.SETTINGS.MODULE_CHAPTER = "Introduction to Computer Systems"; ODSA.SETTINGS.BUILD_DATE = "2021-06-14 17:15:25"; ODSA.SETTINGS.BUILD_CMAP = false;JSAV_OPTIONS['lang']='en';JSAV_EXERCISE_OPTIONS['code']='java';</script><div class="section" id="state-models-in-uml">
|
||
<h1>1.5. State Models in UML<a class="headerlink" href="StateModels.html#state-models-in-uml" title="Permalink to this headline">¶</a></h1>
|
||
<p><a class="reference internal" href="Glossary.html#term-state"><span class="xref std std-term">States</span></a> are unique and meaningful configurations of the system. In some cases, a
|
||
state may be defined by a particular combination of values assigned to certain variables. In others,
|
||
several sets of possible values are grouped together within a single state. <a class="reference internal" href="Glossary.html#term-transition"><span class="xref std std-term">Transitions</span></a>
|
||
denote changes from one state to another. Transitions are triggered by events and can
|
||
have <a class="reference internal" href="Glossary.html#term-effect"><span class="xref std std-term">effects</span></a> that produce some visible behavior.</p>
|
||
<div class="figure mb-2 align-right" id="id11" style="width: 40%">
|
||
<span id="statemodelsuml"></span><a class="reference internal image-reference" href="_images/CSF-Images.1.10.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="A UML state model for a streaming media player" src="_images/CSF-Images.1.10.png" style="width: 90%;" /></a>
|
||
<p class="caption align-center px-3"><span class="caption-text"> Figure 1.5.1: A UML state model for a streaming media player</span></p>
|
||
</div>
|
||
<p>UML <a class="reference internal" href="Glossary.html#term-state-model"><span class="xref std std-term">state models</span></a> are one way to visualize the behavior of a system from the
|
||
perspective of its states and transitions. <a href="StateModels.html#statemodelsuml">Figure 1.5.1</a> shows an example of
|
||
a state model for a streaming media player. The player has four states: <code class="docutils literal notranslate"><span class="pre">Connecting</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">Buffering</span></code>, <code class="docutils literal notranslate"><span class="pre">Playing</span></code>, and <code class="docutils literal notranslate"><span class="pre">Closing</span></code>. The arrows between states denote transitions, with the
|
||
following events defined: <code class="docutils literal notranslate"><span class="pre">Connected</span></code>, <code class="docutils literal notranslate"><span class="pre">Ready</span></code>, <code class="docutils literal notranslate"><span class="pre">Suspended</span></code>, <code class="docutils literal notranslate"><span class="pre">Cancelled</span></code>, and <code class="docutils literal notranslate"><span class="pre">Finished</span></code>.
|
||
These events correspond to both user input, as well as issues such as running out of buffered data
|
||
(the infamous <em>buffering</em> that frustrates users). Effects of transitions are denoted after the “/”
|
||
in the label, so the <code class="docutils literal notranslate"><span class="pre">Connected</span></code> event causes the effect <code class="docutils literal notranslate"><span class="pre">Start</span></code> Loading to retrieve the first
|
||
bytes to buffer.</p>
|
||
<p>The solid circle at the top indicates an <em>initial state</em> where the system starts, where the
|
||
outlined circle in the bottom right denotes a <em>final state</em>. Some models may have more than
|
||
one initial state or more than one final state. Observe that, in this case, there is no event
|
||
labeled for the transitions from the initial state or into the final state. These are considered to
|
||
be <em>empty transitions</em> and are not associated with any particular event.</p>
|
||
<p>State models are effective tools for illustrating the general flow between states and the overall
|
||
structure of the system. As is true of any model, state models convey some information while
|
||
omitting other details. Specifically, state models omit information relating to the sequence and the
|
||
timing of the states or the events. <a class="footnote-reference" href="StateModels.html#f4" id="id1">[1]</a> For instance, in the case of the <code class="docutils literal notranslate"><span class="pre">Closing</span></code> state, the
|
||
system could remain in that state for 1 ms or 10 hours before proceeding to the final state; both
|
||
interpretations would be valid. Additionally, one execution of the system could completely avoid the
|
||
<code class="docutils literal notranslate"><span class="pre">Playing</span></code> state, while another execution switches between <code class="docutils literal notranslate"><span class="pre">Playing</span></code> and <code class="docutils literal notranslate"><span class="pre">Buffering</span></code> 100 times.
|
||
If more precise information is needed about the timing or the sequence of transitions, then other
|
||
models will need to be used.</p>
|
||
<div class="section" id="state-space-explosion">
|
||
<h2>1.5.1. State Space Explosion<a class="headerlink" href="StateModels.html#state-space-explosion" title="Permalink to this headline">¶</a></h2>
|
||
<p>Interpreting a well-defined state model should be intuitive; the states should be meaningfully
|
||
different, and the transitions between them should be logical. However, constructing state models is
|
||
not a straightforward process and requires a significant amount of practice to do well. One of the
|
||
most intuitive challenges is how to deal with the <a class="reference internal" href="Glossary.html#term-state-space-explosion"><span class="xref std std-term">state space explosion</span></a> problem, which
|
||
arises when the number of states in the model increase so dramatically that the model is no longer useful.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3" id="stspexplosion">
|
||
<div class="figure align-left">
|
||
<a class="reference internal image-reference" href="_images/CSF-Images-Example.png"><img alt="Decorative example icon" src="_images/CSF-Images-Example.png" style="width: 100%;" /></a>
|
||
</div>
|
||
<p class="topic-title first pt-2 mb-1">Example 1.5.1 </p><hr class="mt-1" />
|
||
<p>One technique that can be used to evaluate a program for correctness is known as <em>model
|
||
checking</em>, which analyzes a formal specification of a state model. For instance, based on that
|
||
model, can we determine if the program will ever reach a state where a pointer variable is set to
|
||
<code class="docutils literal notranslate"><span class="pre">NULL</span></code> and the pointer is dereferenced? If so, we can examine the sequence of steps to get to
|
||
that state to debug the program.</p>
|
||
<p>To start this process, we need a model of the software program. Consider a naïve approach that
|
||
creates a unique state for every possible value of every possible variable. If the system contained
|
||
only a single 8-bit <code class="docutils literal notranslate"><span class="pre">char</span></code> (denoted <code class="docutils literal notranslate"><span class="pre">ch1</span></code>) the state model would consist of <span class="math notranslate nohighlight">\(2^8 = 256\)</span>
|
||
states. Add a second <code class="docutils literal notranslate"><span class="pre">char</span></code> (denoted <code class="docutils literal notranslate"><span class="pre">ch2</span></code>) and the model increases to <span class="math notranslate nohighlight">\(2^{16} = 16,536\)</span>
|
||
states. This fact arises from the observation that we must (without further knowledge of the
|
||
program) consider all 256 possible values of <code class="docutils literal notranslate"><span class="pre">ch2</span></code> when <code class="docutils literal notranslate"><span class="pre">ch1</span></code> is 0, then another 256 values
|
||
when <code class="docutils literal notranslate"><span class="pre">ch1</span></code> is 1, and so on. If we convert both variables to the 32-bit <code class="docutils literal notranslate"><span class="pre">int</span></code> type and the model
|
||
has <span class="math notranslate nohighlight">\(2^{64} = 1.84 * 10^{19}\)</span> states, just to represent two variables.</p>
|
||
</div>
|
||
<p>This approach illustrates the dangers of the state space explosion problem. Because every additional
|
||
bit of information doubles the number of possible states, state models can easily become unusably
|
||
large. As such, it is critical to group configurations into meaningful states (such as positive and
|
||
negative values for a key variable. However, determining what is meaningful is inherently
|
||
application-specific and requires the judgment of someone with relevant expertise.</p>
|
||
</div>
|
||
<div class="section" id="implementing-finite-state-machines">
|
||
<h2>1.5.2. Implementing Finite State Machines<a class="headerlink" href="StateModels.html#implementing-finite-state-machines" title="Permalink to this headline">¶</a></h2>
|
||
<p>There are multiple ways to turn a state model into an executable <em>finite state machine (FSM)</em> <a class="footnote-reference" href="StateModels.html#f5" id="id2">[2]</a>
|
||
implementation. In fact, this is such a common practice that there are automated tools that will
|
||
take a state model specification and generate executable code. The disadvantage with these types of
|
||
tools is that the code is not necessarily readable. In this section, we will step through an example
|
||
implementation that illustrates some of the key aspects of how these translations
|
||
work.</p>
|
||
<p><a class="reference external" href="StateModels.html#cl1-1">Code Listing 1.1</a> shows the key declarations of a header file for a generic FSM. Event and state
|
||
types are declared as integer types, while the action type is declared as a function pointer that
|
||
takes a pointer to a FSM as an instance. The action type can be used for transition effects (as used
|
||
in this example), as well as for state entry or exit activities. Lines 15 – 21 declare our FSM
|
||
structure. Within the FSM, we will keep track of the current state, the number of events (used for
|
||
error checking), and a pointer to a <code class="docutils literal notranslate"><span class="pre">transition</span></code> function; this function will take in the current
|
||
state and event as arguments, then return the next state and the associated transition effect (if
|
||
any) to the caller. (Note that many implementations of FSM do not use this kind of <code class="docutils literal notranslate"><span class="pre">struct</span></code>, using
|
||
global variables for the current state and transition lookup tables. Our struct is meant to
|
||
encapsulate this in a way that we support multiple concurrent FSM instances if needed.)</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl1-1"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 1.1:</span>
|
||
<span class="cm"> Header file for a generic FSM handler</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cm">/* States and events should just be integers */</span>
|
||
<span class="k">typedef</span> <span class="kt">int</span> <span class="n">state_t</span><span class="p">;</span>
|
||
<span class="k">typedef</span> <span class="kt">int</span> <span class="n">event_t</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* Dummy struct for circular typedefs */</span>
|
||
<span class="k">struct</span> <span class="n">fsm</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* Function pointer type declaration for effects */</span>
|
||
<span class="k">typedef</span> <span class="nf">void</span> <span class="p">(</span><span class="o">*</span><span class="n">action_t</span><span class="p">)</span> <span class="p">(</span><span class="k">struct</span> <span class="n">fsm</span> <span class="o">*</span><span class="p">);</span>
|
||
|
||
<span class="cm">/* Generic FSM struct that could have other fields, as well */</span>
|
||
<span class="k">typedef</span> <span class="k">struct</span> <span class="n">fsm</span> <span class="p">{</span>
|
||
<span class="n">state_t</span> <span class="n">state</span><span class="p">;</span> <span class="cm">/* current state */</span>
|
||
<span class="kt">size_t</span> <span class="n">nevents</span><span class="p">;</span> <span class="cm">/* number of events for this FSM */</span>
|
||
<span class="cm">/* pointer to the FSM's transition function */</span>
|
||
<span class="n">state_t</span> <span class="p">(</span><span class="o">*</span><span class="n">transition</span><span class="p">)</span> <span class="p">(</span><span class="k">struct</span> <span class="n">fsm</span> <span class="o">*</span><span class="p">,</span> <span class="n">event_t</span><span class="p">,</span> <span class="n">action_t</span> <span class="o">*</span><span class="p">);</span>
|
||
<span class="p">}</span> <span class="n">fsm_t</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* Invoke an event handler for a given FSM */</span>
|
||
<span class="kt">void</span> <span class="nf">handle_event</span> <span class="p">(</span><span class="n">fsm_t</span> <span class="o">*</span><span class="n">fsm</span><span class="p">,</span> <span class="n">event_t</span> <span class="n">event</span><span class="p">);</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Lastly, there is a single <code class="docutils literal notranslate"><span class="pre">handle_event()</span></code> function declared that will serve as the interface
|
||
between the FSM and the entity controlling it. <a class="reference external" href="StateModels.html#cl1-2">Code Listing 1.2</a> shows the structure of this
|
||
function. The function starts by confirming that the event number is valid. If so,
|
||
<code class="docutils literal notranslate"><span class="pre">handle_event()</span></code> will call the FSM’s <code class="docutils literal notranslate"><span class="pre">transition</span></code> function to look up information about the
|
||
current event. This function will return -1 if there is no transition defined for that particular
|
||
state and event combination. I.e., events that invalid in the current state are ignored. Otherwise,
|
||
the effect (if any) will be executed on line 21 and the FSM’s state will be updated (line 22).</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl1-2"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 1.2:</span>
|
||
<span class="cm"> Body of handle_event() for a generic FSM handler</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="kt">void</span>
|
||
<span class="nf">handle_event</span> <span class="p">(</span><span class="n">fsm_t</span> <span class="o">*</span><span class="n">fsm</span><span class="p">,</span> <span class="n">event_t</span> <span class="n">event</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="cm">/* Confirm the event is valid for the given FSM */</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">event</span> <span class="o">>=</span> <span class="n">fsm</span><span class="o">-></span><span class="n">nevents</span><span class="p">)</span>
|
||
<span class="k">return</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* Use the FSM's lookup tables; if next is -1, the event is not</span>
|
||
<span class="cm"> defined for the current state */</span>
|
||
<span class="n">action_t</span> <span class="n">effect</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
|
||
<span class="n">state_t</span> <span class="n">next</span> <span class="o">=</span> <span class="n">fsm</span><span class="o">-></span><span class="n">transition</span> <span class="p">(</span><span class="n">fsm</span><span class="p">,</span> <span class="n">event</span><span class="p">,</span> <span class="o">&</span><span class="n">effect</span><span class="p">);</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">next</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span>
|
||
<span class="k">return</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* Perform the effect (if defined) and change the state */</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">effect</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span>
|
||
<span class="n">effect</span> <span class="p">(</span><span class="n">fsm</span><span class="p">);</span>
|
||
<span class="n">fsm</span><span class="o">-></span><span class="n">state</span> <span class="o">=</span> <span class="n">next</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p><a class="reference external" href="StateModels.html#cl1-1">Code Listing 1.1</a> and <a class="reference external" href="StateModels.html#cl1-2">1.2</a> provided a generic structure for any FSM. We now want to turn our
|
||
attention to the state model that we used in <a href="StateModels.html#statemodelsuml">Figure 1.5.1</a> to model a simple media
|
||
player. The first step is to create a table form of the transitions between states. <a class="reference external" href="StateModels.html#tbl1-1">Table 1.1</a> shows
|
||
the table of the transitions for <a href="StateModels.html#statemodelsuml">Figure 1.5.1</a>. Each row of the table
|
||
corresponds to a possible current state in the model. Each column within that row represents the
|
||
next state based on a particular event, as well as any related transition effect. For instance, if
|
||
the Suspend event occurs while the FSM is in the <code class="docutils literal notranslate"><span class="pre">Playing</span></code> state, the next state would be
|
||
<code class="docutils literal notranslate"><span class="pre">Buffering</span></code> and the <code class="docutils literal notranslate"><span class="pre">pause_play()</span></code> effect would be; if the <code class="docutils literal notranslate"><span class="pre">Finish</span></code> event had occurred
|
||
instead, the next state would be <code class="docutils literal notranslate"><span class="pre">Closing</span></code> and there would be no effect. Any of the boxes in this
|
||
table that do not have entries indicate that there is no valid transition for that state and event combination.</p>
|
||
<center>
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<table class="table table-bordered">
|
||
<thead class="jmu-dark-purple-bg text-light">
|
||
<tr>
|
||
<th class="py-0 center" width="17%"> </th>
|
||
<th class="py-0 center" width="17%"><code>Connect</code></th>
|
||
<th class="py-0 center" width="17%"><code>Suspend</code></th>
|
||
<th class="py-0 center" width="17%"><code>Ready</code></th>
|
||
<th class="py-0 center" width="17%"><code>Finish</code></th>
|
||
<th class="py-0 center"><code>Cancel</code></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="bg-light align-middle"><strong><code>Connecting</code></strong></td>
|
||
<td class="center align-middle"><code>Buffering / start_load</code></td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
</tr>
|
||
<tr>
|
||
<td class="bg-light align-middle"><strong><code>Buffering</code></strong></td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td class="center align-middle"><code>Playing / resume</code></td>
|
||
<td> </td>
|
||
<td><code>Closing</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="bg-light align-middle"><strong><code>Playing</code></strong></td>
|
||
<td> </td>
|
||
<td class="center align-middle"><code>Buffering / pause_play</code></td>
|
||
<td> </td>
|
||
<td class="center align-middle"><code>Closing</code></td>
|
||
<td> </td>
|
||
</tr>
|
||
<tr>
|
||
<td class="bg-light align-middle"><strong><code>Closing</code></strong></td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
<td> </td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>
|
||
Table 1.1: Representing the transitions between states in Figure 1.5.1
|
||
</p>
|
||
</center><p><a class="reference external" href="StateModels.html#cl1-3">Code Listing 1.3</a> documents how to turn <a class="reference external" href="StateModels.html#tbl1-1">Table 1.1</a> into executable code. To start, line 6 defines an
|
||
enum type for the specific states for this FSM instance, and line 7 creates a preprocessor constant
|
||
for the number of states. Recall from <a class="reference external" href="StateModels.html#cl1-1">Code Listing 1.1</a> that states are, ultimately, integer types.
|
||
The advantage of using an <code class="docutils literal notranslate"><span class="pre">enum</span></code> is that it allows us to refer to states by names (e.g., <code class="docutils literal notranslate"><span class="pre">CONN</span></code>
|
||
for the <code class="docutils literal notranslate"><span class="pre">Connecting</span></code> state) instead of integers, which would be otherwise meaningless and likely
|
||
to cause errors. Line 8 defines a constant for the number of events based on similar enum for events
|
||
but defined elsewhere.</p>
|
||
<p>Lines 11 – 17 encode the transitions defined in <a class="reference external" href="StateModels.html#tbl1-1">Table 1.1</a>. In the enum defined on line 6, the last
|
||
value (<code class="docutils literal notranslate"><span class="pre">NST</span></code>) is used to indicate <em>no state</em>, meaning that there is no transition defined. These
|
||
values in this two-dimensional array correspond to the blanks in the table. Lines 20 – 26 define a
|
||
similar lookup table, but for the transition effects. Since effects are actions that do something,
|
||
<a class="reference external" href="StateModels.html#cl1-1">Code Listing 1.1</a> defined the <code class="docutils literal notranslate"><span class="pre">action_t</span></code> type as a function pointer; as a result, the empty values
|
||
in the table are <code class="docutils literal notranslate"><span class="pre">NULL</span></code> pointers.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl1-3"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 1.3:</span>
|
||
<span class="cm"> Internal state and lookup table definitions for Figure 1.5.1</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cm">/* Internal type definition of states */</span>
|
||
<span class="k">typedef</span> <span class="k">enum</span> <span class="p">{</span> <span class="n">CONN</span><span class="p">,</span> <span class="n">BUFF</span><span class="p">,</span> <span class="n">PLAY</span><span class="p">,</span> <span class="n">CLOS</span><span class="p">,</span> <span class="n">NST</span> <span class="p">}</span> <span class="n">ms_t</span><span class="p">;</span>
|
||
<span class="cp">#define NUM_STATES (NST+1)</span>
|
||
<span class="cp">#define NUM_EVENTS (NIL+1)</span>
|
||
|
||
<span class="cm">/* Lookup table for transitions; row=state, column=event */</span>
|
||
<span class="k">static</span> <span class="n">ms_t</span> <span class="k">const</span> <span class="n">_transition</span><span class="p">[</span><span class="n">NUM_STATES</span><span class="p">][</span><span class="n">NUM_EVENTS</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
|
||
<span class="c1">// Connect Suspend Ready Finish Cancel</span>
|
||
<span class="p">{</span> <span class="n">BUFF</span><span class="p">,</span> <span class="n">NST</span><span class="p">,</span> <span class="n">NST</span><span class="p">,</span> <span class="n">NST</span><span class="p">,</span> <span class="n">NST</span> <span class="p">},</span> <span class="c1">// Connecting</span>
|
||
<span class="p">{</span> <span class="n">NST</span><span class="p">,</span> <span class="n">NST</span><span class="p">,</span> <span class="n">PLAY</span><span class="p">,</span> <span class="n">NST</span><span class="p">,</span> <span class="n">CLOS</span> <span class="p">},</span> <span class="c1">// Buffering</span>
|
||
<span class="p">{</span> <span class="n">NST</span><span class="p">,</span> <span class="n">BUFF</span><span class="p">,</span> <span class="n">NST</span><span class="p">,</span> <span class="n">CLOS</span><span class="p">,</span> <span class="n">NST</span> <span class="p">},</span> <span class="c1">// Playing</span>
|
||
<span class="p">{</span> <span class="n">NST</span><span class="p">,</span> <span class="n">NST</span><span class="p">,</span> <span class="n">NST</span><span class="p">,</span> <span class="n">NST</span><span class="p">,</span> <span class="n">NST</span> <span class="p">}</span> <span class="c1">// Closing</span>
|
||
<span class="p">};</span>
|
||
|
||
<span class="cm">/* Lookup table for effects; row=state, column=event */</span>
|
||
<span class="k">static</span> <span class="n">action_t</span> <span class="k">const</span> <span class="n">_effect</span><span class="p">[</span><span class="n">NUM_STATES</span><span class="p">][</span><span class="n">NUM_EVENTS</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
|
||
<span class="c1">// Connect Suspend Ready Finish Cancel</span>
|
||
<span class="p">{</span> <span class="n">start_load</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">},</span> <span class="c1">// Connecting</span>
|
||
<span class="p">{</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">resume</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">},</span> <span class="c1">// Buffering</span>
|
||
<span class="p">{</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">pause_play</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">},</span> <span class="c1">// Playing</span>
|
||
<span class="p">{</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span> <span class="p">}</span> <span class="c1">// Closing</span>
|
||
<span class="p">};</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Note that <a class="reference external" href="StateModels.html#cl1-3">Code Listing 1.3</a> declared both <code class="docutils literal notranslate"><span class="pre">_transition</span></code> (the transition table) and <code class="docutils literal notranslate"><span class="pre">_effect</span></code> (the
|
||
effects table) as <code class="docutils literal notranslate"><span class="pre">static</span></code>. This design choice helps to create a modular approach, as these tables
|
||
will not be accessed directly outside of this file. <a class="reference external" href="StateModels.html#cl1-4">Code Listing 1.4</a> shows how these tables will be
|
||
accessed through the <code class="docutils literal notranslate"><span class="pre">media_transition()</span></code> function, also declared <code class="docutils literal notranslate"><span class="pre">static</span></code> in the same file.
|
||
Given the FSM’s current state, if the entry in the <code class="docutils literal notranslate"><span class="pre">_transition</span></code> table for the specified event is
|
||
not defined, return -1 to indicate no transition should be taken. Otherwise, set the <code class="docutils literal notranslate"><span class="pre">effect</span></code>
|
||
call-by-reference parameter to the appropriate function and return the next state. Note that, just
|
||
like the <code class="docutils literal notranslate"><span class="pre">_transition</span></code> and <code class="docutils literal notranslate"><span class="pre">_effect</span></code> tables, the <code class="docutils literal notranslate"><span class="pre">media_transition()</span></code> function cannot be
|
||
accessed outside the current file. The <code class="docutils literal notranslate"><span class="pre">media_init()</span></code> function provides the link. When a new
|
||
instance of this FSM is needed, the controller can use this function to get a new <code class="docutils literal notranslate"><span class="pre">fsm_t</span></code>, which
|
||
contains a pointer to the <code class="docutils literal notranslate"><span class="pre">media_transition()</span></code> function.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl1-4"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0"> 1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8
|
||
9
|
||
10
|
||
11
|
||
12
|
||
13
|
||
14
|
||
15
|
||
16
|
||
17
|
||
18
|
||
19
|
||
20
|
||
21
|
||
22
|
||
23
|
||
24
|
||
25
|
||
26
|
||
27</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 1.4:</span>
|
||
<span class="cm"> Connecting the specific FSM with the generic interface</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="cm">/* Given FSM instance and event, perform the table lookups */</span>
|
||
<span class="k">static</span> <span class="n">state_t</span>
|
||
<span class="nf">media_transition</span> <span class="p">(</span><span class="n">fsm_t</span> <span class="o">*</span><span class="n">fsm</span><span class="p">,</span> <span class="n">event_t</span> <span class="n">event</span><span class="p">,</span> <span class="n">action_t</span> <span class="o">*</span><span class="n">effect</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="cm">/* If the state/event combination is bad, return -1 */</span>
|
||
<span class="k">if</span> <span class="p">(</span><span class="n">fsm</span><span class="o">-></span><span class="n">state</span> <span class="o">>=</span> <span class="n">NST</span> <span class="o">||</span> <span class="n">event</span> <span class="o">>=</span> <span class="n">NIL</span> <span class="o">||</span> <span class="n">_transition</span><span class="p">[</span><span class="n">fsm</span><span class="o">-></span><span class="n">state</span><span class="p">][</span><span class="n">event</span><span class="p">]</span> <span class="o">==</span> <span class="n">NST</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* Look up the effect and transitions in the tables */</span>
|
||
<span class="o">*</span><span class="n">effect</span> <span class="o">=</span> <span class="n">_effect</span><span class="p">[</span><span class="n">fsm</span><span class="o">-></span><span class="n">state</span><span class="p">][</span><span class="n">event</span><span class="p">];</span>
|
||
<span class="k">return</span> <span class="n">_transition</span><span class="p">[</span><span class="n">fsm</span><span class="o">-></span><span class="n">state</span><span class="p">][</span><span class="n">event</span><span class="p">];</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="cm">/* Return an FSM that links to these internals */</span>
|
||
<span class="n">fsm_t</span> <span class="o">*</span>
|
||
<span class="nf">media_init</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span>
|
||
<span class="p">{</span>
|
||
<span class="n">fsm_t</span> <span class="o">*</span><span class="n">fsm</span> <span class="o">=</span> <span class="n">calloc</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="k">sizeof</span> <span class="p">(</span><span class="n">fsm_t</span><span class="p">));</span>
|
||
<span class="n">fsm</span><span class="o">-></span><span class="n">nevents</span> <span class="o">=</span> <span class="n">NUM_EVENTS</span><span class="p">;</span>
|
||
<span class="n">fsm</span><span class="o">-></span><span class="n">state</span> <span class="o">=</span> <span class="n">CONN</span><span class="p">;</span>
|
||
<span class="n">fsm</span><span class="o">-></span><span class="n">transition</span> <span class="o">=</span> <span class="n">media_transition</span><span class="p">;</span>
|
||
<span class="k">return</span> <span class="n">fsm</span><span class="p">;</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>Finally, <a class="reference external" href="StateModels.html#cl1-5">Code Listing 1.5</a> shows how a controlling program would create a FSM instance and send it
|
||
events. Since all of the information about the transitions and effects is encapsulated inside the
|
||
FSM struct, the controller just needs to focus on the logic of which event to send to the FSM.
|
||
Recall from <a class="reference external" href="StateModels.html#cl1-2">Code Listing 1.2</a> that <code class="docutils literal notranslate"><span class="pre">handle_event()</span></code> passes the event through the FSM’s
|
||
<code class="docutils literal notranslate"><span class="pre">fsm->transition</span></code> function pointer to determine the state change and effect function. Since
|
||
<code class="docutils literal notranslate"><span class="pre">handle_event()</span></code> ignores invalid transitions, sending the wrong event (such as on line 7) cannot
|
||
cause an error in the FSM.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl1-5"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
|
||
2
|
||
3
|
||
4
|
||
5
|
||
6
|
||
7
|
||
8</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 1.5:</span>
|
||
<span class="cm"> Creating an instance of the FSM and sending it events</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="n">fsm_t</span> <span class="o">*</span><span class="n">fsm</span> <span class="o">=</span> <span class="n">media_init</span> <span class="p">();</span>
|
||
<span class="n">handle_event</span> <span class="p">(</span><span class="n">fsm</span><span class="p">,</span> <span class="n">Connect</span><span class="p">);</span>
|
||
<span class="n">handle_event</span> <span class="p">(</span><span class="n">fsm</span><span class="p">,</span> <span class="n">Connect</span><span class="p">);</span> <span class="cm">/* no transition here ! */</span>
|
||
<span class="n">handle_event</span> <span class="p">(</span><span class="n">fsm</span><span class="p">,</span> <span class="n">Ready</span><span class="p">);</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<table class="docutils footnote" frame="void" id="f4" rules="none">
|
||
<colgroup><col class="label" /><col /></colgroup>
|
||
<tbody valign="top">
|
||
<tr><td class="label"><a class="fn-backref" href="StateModels.html#id1">[1]</a></td><td>There are more advanced state models, known as timed automata, that do explicitly
|
||
incorporate time within their representation. However, we will not be using those models in this book.</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<table class="docutils footnote" frame="void" id="f5" rules="none">
|
||
<colgroup><col class="label" /><col /></colgroup>
|
||
<tbody valign="top">
|
||
<tr><td class="label"><a class="fn-backref" href="StateModels.html#id2">[2]</a></td><td>The term state model is often used synonymously with finite-state machine or finite-state
|
||
automata. Here, we are using the terms separately just to distinguish between the non-executable
|
||
model and its executable implementation.</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<div
|
||
id="StateModelSumm"
|
||
class="embedContainer"
|
||
data-exer-name="StateModelSumm"
|
||
data-long-name="State model summary questions"
|
||
data-short-name="StateModelSumm"
|
||
data-frame-src="../../../Exercises/IntroConcSys/StateModelSumm.html?selfLoggingEnabled=false&localMode=true&module=StateModels&JXOP-debug=true&JOP-lang=en&JXOP-code=java"
|
||
data-frame-width="950"
|
||
data-frame-height="550"
|
||
data-external="false"
|
||
data-points="1.0"
|
||
data-required="True"
|
||
data-showhide="show"
|
||
data-threshold="3"
|
||
data-type="ka"
|
||
data-exer-id="">
|
||
|
||
<div class="center">
|
||
<div id="StateModelSumm_iframe"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="container">
|
||
|
||
<div class="mt-4 container center">
|
||
«  <a id="prevmod1" href="Architectures.html">1.4. System Architectures</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod1" href="SequenceModels.html">1.6. Sequence Models in UML</a>  »
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
<br />
|
||
|
||
<div class="row jmu-dark-purple-bg">
|
||
<div class="col-md-12">
|
||
<center>
|
||
<a id="contact_us" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="mailto:webmaster@opencsf.org" role="button">Contact Us</a>
|
||
<a id="license" class="btn button-link-no-blue jmu-gold" rel="nofollow" href="https://w3.cs.jmu.edu/kirkpams/OpenCSF/lib/license.html" target="_blank">License</a>
|
||
</center>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script src="_static/js/popper.js-1.14.7-min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
||
<script src="_static/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
||
</body>
|
||
</html> |