567 lines
No EOL
42 KiB
HTML
567 lines
No EOL
42 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
|
||
|
||
|
||
<html lang="en">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
||
<title>7.2. Critical Sections and Peterson’s Solution — 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="3. Locks" href="Locks.html" />
|
||
<link rel="prev" title="1. Synchronization Primitives" href="SynchOverview.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="CritSect.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="CritSect.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/CritSect.rst"
|
||
target="_blank" rel="nofollow">Show Source</a></li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
|
||
<div class="container center">
|
||
«  <a id="prevmod" href="SynchOverview.html">7.1. Synchronization Primitives</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod" href="Locks.html">7.3. Locks</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 = "CritSect";ODSA.SETTINGS.MODULE_LONG_NAME = "Critical Sections and Peterson's Solution";ODSA.SETTINGS.MODULE_CHAPTER = "Synchronization Primitives"; 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="critical-sections-and-peterson-s-solution">
|
||
<h1>7.2. Critical Sections and Peterson’s Solution<a class="headerlink" href="CritSect.html#critical-sections-and-peterson-s-solution" title="Permalink to this headline">¶</a></h1>
|
||
<p><a class="reference internal" href="Glossary.html#term-critical-section"><span class="xref std std-term">Critical sections</span></a> are sequences of instructions that
|
||
cannot be interleaved among multiple threads. A simple example of a critical
|
||
section arises when two threads share a global variable <code class="docutils literal notranslate"><span class="pre">globalvar</span></code> and both
|
||
try to change its value with <code class="docutils literal notranslate"><span class="pre">globalvar++</span></code>. Recall from the <a class="reference external" href="RaceConditions.html">previous chapter</a>
|
||
that this line of code compiles into three assembly-language instructions to
|
||
load, modify, and store the result.</p>
|
||
<div class="highlight-asm border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><table class="highlighttable"><tr><td class="linenos px-0 mx-0"><div class="linenodiv"><pre class="mb-0">1
|
||
2
|
||
3</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="nf">movq</span> <span class="no">_globalvar</span><span class="p">(</span><span class="nv">%rip</span><span class="p">),</span> <span class="nv">%rsi</span> <span class="c"># copy from memory into %rsi register</span>
|
||
<span class="no">addq</span> <span class="no">$1</span><span class="p">,</span> <span class="nv">%rsi</span> <span class="c"># increment the value in the register</span>
|
||
<span class="no">movq</span> <span class="nv">%rsi</span><span class="p">,</span> <span class="no">_globalvar</span><span class="p">(</span><span class="nv">%rip</span><span class="p">)</span> <span class="c"># store the result back into memory</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>When multiple threads execute this code, a race condition arises since the lines
|
||
can be interleaved. For instance, an interrupt during the second instruction’s
|
||
execution could trigger a switch from one thread to another. <a class="reference external" href="CritSect.html#cl7-1">Code Listing 7.1</a>
|
||
shows the interleaved sequence of instructions (distinct indentation denotes the
|
||
two threads) that would result from this unfortunate timing of the interrupt.</p>
|
||
<div class="highlight-asm border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl7-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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="c"># Code Listing 7.1:</span>
|
||
<span class="c"># A possible sequence of assembly language instructions with a race condition</span>
|
||
|
||
<span class="c"># Thread A copies globalvar (5) into %rsi, adds 1 to it</span>
|
||
<span class="nf">movq</span> <span class="no">_globalvar</span><span class="p">(</span><span class="nv">%rip</span><span class="p">),</span> <span class="nv">%rsi</span>
|
||
<span class="nf">addq</span> <span class="no">$1</span><span class="p">,</span> <span class="nv">%rsi</span>
|
||
|
||
<span class="c"># Interrupt: Kernel switches to start running thread B</span>
|
||
|
||
<span class="c"># Thread B begins same code, also loads value of 5 into %rsi</span>
|
||
<span class="nf">movq</span> <span class="no">_globalvar</span><span class="p">(</span><span class="nv">%rip</span><span class="p">),</span> <span class="nv">%rsi</span>
|
||
<span class="nf">addq</span> <span class="no">$1</span><span class="p">,</span> <span class="nv">%rsi</span>
|
||
<span class="nf">movq</span> <span class="nv">%rsi</span><span class="p">,</span> <span class="no">_globalvar</span><span class="p">(</span><span class="nv">%rip</span><span class="p">)</span>
|
||
<span class="c"># Thread B has copied 6 back into globalvar in memory</span>
|
||
|
||
<span class="c"># Kernel later switches back to thread A</span>
|
||
|
||
<span class="c"># Thread A also copies 6 back into globalvar</span>
|
||
<span class="nf">movq</span> <span class="nv">%rsi</span><span class="p">,</span> <span class="no">_globalvar</span><span class="p">(</span><span class="nv">%rip</span><span class="p">)</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>The result of this interleaving, assuming <code class="docutils literal notranslate"><span class="pre">globalvar</span></code> was originally 5, is
|
||
that the threads (together) performed <code class="docutils literal notranslate"><span class="pre">globalvar++</span></code> twice, but the value only
|
||
gets changed to 6 instead of the correct value of 7. The problem is that an
|
||
interrupt occurred before the first thread was able to update <code class="docutils literal notranslate"><span class="pre">globalvar</span></code>,
|
||
then the kernel switched to a different thread that read the old value. If this
|
||
switch had not occurred until later, then the first thread would have updated
|
||
<code class="docutils literal notranslate"><span class="pre">globalvar</span></code> with the value of 6, which is what the second thread would observe
|
||
instead of the outdated 5.</p>
|
||
<p>It is important to note that the problem isn’t the interrupt, per se. If the
|
||
interrupt occurs and the kernel switches to <em>any other thread</em>, or if the second
|
||
thread were executing a different portion of code that had nothing to do with
|
||
<code class="docutils literal notranslate"><span class="pre">globalvar</span></code>, the correct result would be produced. The error arises because of the
|
||
combination of the interrupt/switch with the fact that both threads are
|
||
accessing the same variable.</p>
|
||
<div class="section" id="peterson-s-solution">
|
||
<h2>7.2.1. Peterson’s Solution<a class="headerlink" href="CritSect.html#peterson-s-solution" title="Permalink to this headline">¶</a></h2>
|
||
<p>One approach to solving the problem of critical sections is to employ Peterson’s
|
||
solution, an algorithmic approach that uses shared memory to declare intentions.
|
||
<a class="reference external" href="CritSect.html#cl7-2">Code Listing 7.2</a> shows the algorithm, which uses a <code class="docutils literal notranslate"><span class="pre">bool</span></code> array
|
||
(<code class="docutils literal notranslate"><span class="pre">flag</span></code>) to signify a thread’s intent to enter and an <code class="docutils literal notranslate"><span class="pre">int</span></code> variable (<code class="docutils literal notranslate"><span class="pre">turn</span></code>)
|
||
to indicate which thread is allowed to enter. <a class="footnote-reference" href="CritSect.html#f42" id="id1">[1]</a></p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl7-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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 7.2:</span>
|
||
<span class="cm"> Peterson's solution to solving the critical section problem</span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="n">flag</span><span class="p">[</span><span class="n">self</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
|
||
<span class="n">turn</span> <span class="o">=</span> <span class="n">other</span><span class="p">;</span>
|
||
|
||
<span class="cm">/* busy wait until it is safe to enter */</span>
|
||
<span class="k">while</span> <span class="p">(</span><span class="n">flag</span><span class="p">[</span><span class="n">other</span><span class="p">]</span> <span class="o">==</span> <span class="nb">true</span> <span class="o">&&</span> <span class="n">turn</span> <span class="o">==</span> <span class="n">other</span><span class="p">)</span> <span class="p">;</span>
|
||
|
||
<span class="cm">/* critical section */</span>
|
||
<span class="n">flag</span><span class="p">[</span><span class="n">self</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>The <code class="docutils literal notranslate"><span class="pre">turn</span></code> variable plays a critical role in ensuring the correct functioning
|
||
of the solution. Specifically, this variable makes threads adopt a <em>polite</em>
|
||
approach to requesting access: when a thread wants to enter the critical
|
||
section, it must declare that the other thread gets to go first. Since this type
|
||
of variable manipulation consists of a single write to memory, it can be
|
||
considered atomic. Consequently, this update does not create a race condition.</p>
|
||
<p><a href="CritSect.html#petersonstate">Figure 7.2.1</a> illustrates all possible states and transitions
|
||
for Peterson’s solution. In this model, there are three basic types of events
|
||
for each thread: <code class="docutils literal notranslate"><span class="pre">WAIT</span></code>, <code class="docutils literal notranslate"><span class="pre">ENTER</span></code>, and <code class="docutils literal notranslate"><span class="pre">EXIT</span></code>. The six states at the top of
|
||
the model show the transitions when there is no contention. For example, from
|
||
the left non-critical state (neither are waiting, <code class="docutils literal notranslate"><span class="pre">turn</span></code> = 1), thread 0 could
|
||
indicate it attempts to enter the critical section with the <code class="docutils literal notranslate"><span class="pre">WAIT</span></code> event and
|
||
immediately enters with the <code class="docutils literal notranslate"><span class="pre">ENTER</span></code> event. The <code class="docutils literal notranslate"><span class="pre">EXIT</span></code> event restores the
|
||
system to the non-critical state.</p>
|
||
<div class="figure mb-2 align-center" id="id2">
|
||
<span id="petersonstate"></span><a class="reference internal image-reference" href="_images/CSF-Images.7.1.png"><img class="p-3 mb-2 align-center border border-dark rounded-lg" alt="State model of Peterson's solution" src="_images/CSF-Images.7.1.png" style="width: 80%;" /></a>
|
||
<p class="caption align-center px-3"><span class="caption-text"> Figure 7.2.1: State model of Peterson’s solution</span></p>
|
||
</div>
|
||
<p>The four states at the bottom illustrate how the algorithm handles contention.
|
||
If neither thread has entered the critical section (states <code class="docutils literal notranslate"><span class="pre">Waiting</span> <span class="pre">0</span></code> and
|
||
<code class="docutils literal notranslate"><span class="pre">Waiting</span> <span class="pre">1</span></code>), then the turn variable determines which thread enters. That is,
|
||
the condition of the while loop can only resolve to true for one of the threads,
|
||
blocking the other from entering. On the other hand, one thread may already be
|
||
in the critical section (states <code class="docutils literal notranslate"><span class="pre">Critical</span> <span class="pre">0</span></code> and <code class="docutils literal notranslate"><span class="pre">Critical</span> <span class="pre">1</span></code>) when the
|
||
other attempts to enter. In that case, the new thread is forced to wait by the
|
||
turn variable. Note that Peterson’s algorithm can be extended to more than two
|
||
threads, as well.</p>
|
||
<div class="topic border border-dark rounded-lg bg-light px-2 mb-3">
|
||
<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 7.2.1 </p><hr class="mt-1" />
|
||
<p>The state model in <a href="CritSect.html#petersonstate">Figure 7.2.1</a> can be difficult to
|
||
trace. Although it would be impractical to provide a full description of all
|
||
possible sequences, we can describe a basic trace that traverses through seven
|
||
of the states. As before, we use indentation to denote the separate threads,
|
||
with thread <code class="docutils literal notranslate"><span class="pre">T0</span></code> unindented and <code class="docutils literal notranslate"><span class="pre">T1</span></code> indented. Comments interspersed
|
||
indicate the state and changes to relevant variables.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate"><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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Initial state: Non-critical with turn=1 */</span>
|
||
<span class="n">flag</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
|
||
<span class="n">turn</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="cm">/* Change to Waiting 0, turn=1 */</span>
|
||
<span class="n">flag</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
|
||
<span class="n">turn</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="cm">/* Change to Both waiting, turn=0 */</span>
|
||
|
||
<span class="cm">/* Both are waiting, so turn is the tie-breaker */</span>
|
||
<span class="k">while</span> <span class="p">(</span><span class="n">flag</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&&</span> <span class="n">turn</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">;</span> <span class="cm">/* FALSE, turn=0 */</span>
|
||
<span class="k">while</span> <span class="p">(</span><span class="n">flag</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&&</span> <span class="n">turn</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">;</span> <span class="cm">/* TRUE, T1 blocked */</span>
|
||
|
||
<span class="cm">/* Enter Critical 0, Waiting 1</span>
|
||
<span class="cm"> Thread 0 does critical work here */</span>
|
||
<span class="n">flag</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="cm">/* Enter Waiting 1, turn=0 */</span>
|
||
|
||
<span class="k">while</span> <span class="p">(</span><span class="n">flag</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&&</span> <span class="n">turn</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">;</span> <span class="cm">/* FALSE, flag[0] now false */</span>
|
||
<span class="cm">/* Enter Critical 1</span>
|
||
<span class="cm"> Thread 1 does critical work here */</span>
|
||
<span class="n">flag</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="cm">/* Enter Non-critical with turn=0 */</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
<p>In this trace, both threads begin in non-critical code with neither attempting
|
||
to enter a critical section until <code class="docutils literal notranslate"><span class="pre">T0</span></code> executes line 2. <code class="docutils literal notranslate"><span class="pre">T1</span></code> then declares
|
||
its intention to enter on line 4. Lines 3 and 5 are the key events to control
|
||
the ordering; whichever thread sets turn last loses the rase. Since <code class="docutils literal notranslate"><span class="pre">T1</span></code>
|
||
changes turn after <code class="docutils literal notranslate"><span class="pre">T0</span></code> does, <code class="docutils literal notranslate"><span class="pre">T0</span></code> will be the thread to enter the critical
|
||
section. To confirm this fact, check the <code class="docutils literal notranslate"><span class="pre">while</span></code>-loop conditions on lines 8
|
||
and 9. On these lines, <code class="docutils literal notranslate"><span class="pre">flag[0]</span></code> and <code class="docutils literal notranslate"><span class="pre">flag[1]</span></code> are both true. The condition
|
||
then rests exclusively on turn. Later, after <code class="docutils literal notranslate"><span class="pre">T0</span></code> leaves the critical section
|
||
(line 13), <code class="docutils literal notranslate"><span class="pre">T1</span></code>’s while-loop condition changes because <code class="docutils literal notranslate"><span class="pre">flag[0]</span></code> is now
|
||
false; this change allows <code class="docutils literal notranslate"><span class="pre">T1</span></code> to break out of the loop and continue into the
|
||
critical section.</p>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="synchronization-properties">
|
||
<h2>7.2.2. Synchronization Properties<a class="headerlink" href="CritSect.html#synchronization-properties" title="Permalink to this headline">¶</a></h2>
|
||
<p>Peterson’s solution provides three desirable properties for solutions to
|
||
synchronization problems:</p>
|
||
<blockquote>
|
||
<div><ul class="simple">
|
||
<li><a class="reference internal" href="Glossary.html#term-safety"><span class="xref std std-term">Safety</span></a> – There is no way for two threads to be in the critical section
|
||
concurrently, so they cannot interfere with each other. This property is also
|
||
called <a class="reference internal" href="Glossary.html#term-mutual-exclusion"><span class="xref std std-term">mutual exclusion</span></a>.</li>
|
||
<li><a class="reference internal" href="Glossary.html#term-liveness"><span class="xref std std-term">Liveness</span></a> – If no thread is in the critical section and at least one tries to
|
||
enter, then one of the threads will be able to enter. This property is also
|
||
called <a class="reference internal" href="Glossary.html#term-progress"><span class="xref std std-term">progress</span></a>.</li>
|
||
<li><a class="reference internal" href="Glossary.html#term-fairness"><span class="xref std std-term">Fairness</span></a> – Assuming neither thread can remain in the critical section
|
||
indefinitely, if a thread attempts to enter the critical section, it will
|
||
eventually do so. This property is also called <a class="reference internal" href="Glossary.html#term-bounded-waiting"><span class="xref std std-term">bounded waiting</span></a>.</li>
|
||
</ul>
|
||
</div></blockquote>
|
||
<p>Examining <a href="CritSect.html#petersonstate">Figure 7.2.1</a> provides informal assurance that
|
||
these properties hold. Safety is achieved, because no state allows both threads
|
||
to be in the critical section at any time. Liveness is supported by the fact
|
||
that all of the waiting states have a transition defined for an <code class="docutils literal notranslate"><span class="pre">ENTER</span></code> event;
|
||
liveness could only be broken if the system could get stuck in a waiting state.
|
||
Fairness is somewhat more difficult to observe, but arises from the <code class="docutils literal notranslate"><span class="pre">Crit</span> <span class="pre">M</span></code>,
|
||
<code class="docutils literal notranslate"><span class="pre">Wait</span> <span class="pre">N</span></code> states in which one thread is in the critical section and the other
|
||
is trying to enter. All possible sequences of events from these states must pass
|
||
through a state in which the waiting thread gets to enter. Thus, no thread that
|
||
tries to enter the critical section can be infinitely blocked from doing so.</p>
|
||
<p>The combination of all three of these properties is very difficult to achieve
|
||
for synchronization problems. Generally speaking, safety is a requirement and no
|
||
approach would be considered a solution without guaranteeing mutually exclusive
|
||
access. Liveness is also a standard requirement; approaches that make it
|
||
possible to enter a <a class="reference internal" href="Glossary.html#term-deadlock"><span class="xref std std-term">deadlock</span></a> state that blocks all threads from entering
|
||
the critical section are also not considered viable solutions.</p>
|
||
<p>In contrast, fairness is quite often difficult to achieve in practice and may
|
||
even be unnecessary. For instance, consider a system that picks randomly between
|
||
threads that are waiting to enter. In addition, assume that each thread will
|
||
immediately try to enter the critical section after leaving it. It is
|
||
theoretically possible that one thread might be extremely unlucky and never gets
|
||
picked. If the choice truly is randomly distributed, this outcome would be as
|
||
likely as flipping a coin and getting the same result every time. It is
|
||
theoretically possible, but unlikely to happen in practice.</p>
|
||
<p>This scenario highlights a key misunderstanding of the liveness property. If
|
||
there are no threads in the critical section and one tries to enter, there is no
|
||
guarantee that thread will actually be the one allowed in. Rather, without the
|
||
fairness property, it may be possible for another thread to come along and enter
|
||
without waiting. To illustrate this point, consider the approach shown in
|
||
<a class="reference external" href="CritSect.html#cl7-3">Code Listing 7.3</a>. This code meets the safety and liveness properties
|
||
by permanently blocking out one of the threads.</p>
|
||
<div class="highlight-c border border-dark rounded-lg bg-light px-0 mb-3 notranslate" id="cl7-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</pre></div></td><td class="code"><div class="highlight bg-light"><pre class="mb-0"><span></span><span class="cm">/* Code Listing 7.3:</span>
|
||
<span class="cm"> An approach that guarantees safety and liveness but not fairness </span>
|
||
<span class="cm"> */</span>
|
||
|
||
<span class="k">if</span> <span class="p">(</span><span class="kr">thread</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
|
||
<span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">;</span> <span class="cm">/* thread 0 waits infinitely */</span>
|
||
|
||
<span class="cm">/* enter critical section */</span>
|
||
</pre></div>
|
||
</td></tr></table></div>
|
||
</div>
|
||
<div class="section" id="peterson-s-solution-and-modern-hardware">
|
||
<h2>7.2.3. Peterson’s Solution and Modern Hardware<a class="headerlink" href="CritSect.html#peterson-s-solution-and-modern-hardware" title="Permalink to this headline">¶</a></h2>
|
||
<p>The elegance of Peterson’s solution makes it an interesting approach that
|
||
provides these three key properties. However, this approach is generally not
|
||
used in modern systems. Peterson’s solution rests on the assumption that the
|
||
instructions are executed in a particular order and memory accesses can be
|
||
achieved atomically. Both of these assumptions can fail with modern hardware.
|
||
Due to complexities in the design of pipelined CPUs, the instructions may be
|
||
executed in a different order. Additionally, if the threads are running on
|
||
different cores that do not guarantee immediate cache coherency, the threads may
|
||
be using different memory values.</p>
|
||
<p>Although there are hardware mechanisms available to overcome these issues,
|
||
Peterson’s solution also suffers from its lack of abstraction. From the systems
|
||
programmer’s perspective, it is more desirable to use abstractions such as
|
||
<em>locking</em> and <em>unlocking</em> a critical section rather than setting memory bits. As
|
||
such, the remainder of this chapter will focus on higher-level abstractions and
|
||
techniques that facilitate more robust and adaptable solutions, called
|
||
synchronization primitives, to these types of problems. In general, these
|
||
primitives fail to guarantee fairness and thus cannot provide the same
|
||
theoretical properties of Peterson’s solution. However, their higher level of
|
||
abstraction provides greater clarity in their practical use.</p>
|
||
<table class="docutils footnote" frame="void" id="f42" rules="none">
|
||
<colgroup><col class="label" /><col /></colgroup>
|
||
<tbody valign="top">
|
||
<tr><td class="label"><a class="fn-backref" href="CritSect.html#id1">[1]</a></td><td>The standard explanation of Peterson’s solution uses 0 and 1 to refer
|
||
to the two threads, respectively. Here, we adopt a higher level of abstraction,
|
||
using <code class="docutils literal notranslate"><span class="pre">self</span></code> and <code class="docutils literal notranslate"><span class="pre">other</span></code> to refer to the two. For thread 0, <code class="docutils literal notranslate"><span class="pre">self</span></code> would
|
||
be 0 and <code class="docutils literal notranslate"><span class="pre">other</span></code> would be 1; the reverse is true for thread 1.</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<div
|
||
id="SynchCritSumm"
|
||
class="embedContainer"
|
||
data-exer-name="SynchCritSumm"
|
||
data-long-name="Critical section questions"
|
||
data-short-name="SynchCritSumm"
|
||
data-frame-src="../../../Exercises/Synch/SynchCritSumm.html?selfLoggingEnabled=false&localMode=true&module=CritSect&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="SynchCritSumm_iframe"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div class="container">
|
||
|
||
<div class="mt-4 container center">
|
||
«  <a id="prevmod1" href="SynchOverview.html">7.1. Synchronization Primitives</a>
|
||
  ::  
|
||
<a class="uplink" href="index.html">Contents</a>
|
||
  ::  
|
||
<a id="nextmod1" href="Locks.html">7.3. Locks</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> |