<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Process &#8211; Software Sermon</title>
	<atom:link href="https://softwaresermon.com/category/process/feed/" rel="self" type="application/rss+xml" />
	<link>https://softwaresermon.com</link>
	<description>Security, Quality, Process</description>
	<lastBuildDate>Tue, 24 Sep 2024 20:50:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
<site xmlns="com-wordpress:feed-additions:1">87091516</site>	<item>
		<title>The Bicameral Mind</title>
		<link>https://softwaresermon.com/2024/01/20/the-bicameral-mind/</link>
		
		<dc:creator><![CDATA[dayton@ieee.org]]></dc:creator>
		<pubDate>Sat, 20 Jan 2024 18:33:26 +0000</pubDate>
				<category><![CDATA[Process]]></category>
		<guid isPermaLink="false">https://softwaresermon.com/?p=252</guid>

					<description><![CDATA[I remember an English lesson I received in grammar school that serves me well in our current disinformation age. I learned to read news from several sources to decide what was actually true. Through experience I learned which sources were verifiable and trustworthy, but even trustworthy sources could occasionally get it wrong. Reading from several &#8230; <a href="https://softwaresermon.com/2024/01/20/the-bicameral-mind/" class="more-link">Continue reading <span class="screen-reader-text">The Bicameral Mind</span></a>]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large"><a href="https://i0.wp.com/softwaresermon.com/wp-content/uploads/2023/11/STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989.jpg?ssl=1"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="660" height="818" data-attachment-id="261" data-permalink="https://softwaresermon.com/2024/01/20/the-bicameral-mind/sts034-71-000ak_-_sts-34_galileo_spacecraft_ius_deployment_sequence_in_ov-104s_payload_bay_-_1989/" data-orig-file="https://i0.wp.com/softwaresermon.com/wp-content/uploads/2023/11/STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989.jpg?fit=1050%2C1302&amp;ssl=1" data-orig-size="1050,1302" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/softwaresermon.com/wp-content/uploads/2023/11/STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989.jpg?fit=242%2C300&amp;ssl=1" data-large-file="https://i0.wp.com/softwaresermon.com/wp-content/uploads/2023/11/STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989.jpg?fit=660%2C818&amp;ssl=1" src="https://i0.wp.com/softwaresermon.com/wp-content/uploads/2023/11/STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989.jpg?resize=660%2C818&#038;ssl=1" alt="" class="wp-image-261" srcset="https://i0.wp.com/softwaresermon.com/wp-content/uploads/2023/11/STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989.jpg?resize=826%2C1024&amp;ssl=1 826w, https://i0.wp.com/softwaresermon.com/wp-content/uploads/2023/11/STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989.jpg?resize=242%2C300&amp;ssl=1 242w, https://i0.wp.com/softwaresermon.com/wp-content/uploads/2023/11/STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989.jpg?resize=768%2C952&amp;ssl=1 768w, https://i0.wp.com/softwaresermon.com/wp-content/uploads/2023/11/STS034-71-000AK_-_STS-34_Galileo_spacecraft_IUS_deployment_sequence_in_OV-104s_payload_bay_-_1989.jpg?w=1050&amp;ssl=1 1050w" sizes="(max-width: 660px) 100vw, 660px" /></a><figcaption class="wp-element-caption">By NASA/STS-34 &#8211; https://danielmarin.naukas.com/files/2015/09/28_Galileo_deployment.jpg, Public Domain, https://commons.wikimedia.org/w/index.php?curid=6049516<br></figcaption></figure>



<p class="">I remember an English lesson I received in grammar school that serves me well in our current disinformation age. I learned to read news from several sources to decide what was actually true. Through experience I learned which sources were verifiable and trustworthy, but even trustworthy sources could occasionally get it wrong. Reading from several sources, and looking for primary sources of information, allow me at least a slight chance of determining truth.</p>



<p class="">The Internet and social media have not made it easier to determine the truth. I&#8217;m disgusted with the number of people who ask their social media acquaintances for answers that they should be getting from reliable sources, or they should already know. I really don&#8217;t think you should ask the Internet if you should take a child to the doctor if they swallowed a bolt, or has a rash.</p>



<p class="">The Internet lies, and even worse, it changes. We all heard about Edward Welch driving to a D.C. area pizza parlor with an assault rifle to stop a sex trafficing ring being run from the parlor&#8217;s <em>non-existent</em> basement. From my personal experience, I distinctly recall one of the US Air Force&#8217;s first female combat pilots firing an anti-satellite missile at the Solwind satellite. Wikipedia reports that same event as a man shot the satellite. I&#8217;m too lazy to dig up the microfiche of the company newsletter proudly touting that a woman combat pilot fired our missile, so I have no evidence to edit the Wikipedia article.</p>



<p class="">One of the other things I learned from that time was the design protocol to never trust automation to &#8220;fire ordnance&#8221;. If, for timing purposes, we required computers to calculate the firing time, we used an array of electromagnetic relays to take the output of multiple computers to arrive at a consensus. Even then, a human initiated the chain of events leading up to the stage separation. On the Inertial Upper Stage, deployed from the Space Shuttle, there is a lever on the side of the booster that turns the booster on. Its impractical to have an astronaut suit up to flip the lever, so there was the equivalent of a tin can over the lever tied to a string (a &#8220;lanyard&#8221; in NASA-speak) with the other end tied to the Space Shuttle. The atronaut mission specialist would flip the switches to tilt the booster&#8217;s cradle in the Space Shuttle and release the springs to push the booster out. As the booster drifted out the string would tighten and flip the lever turning on the booster. Only then would the booster&#8217;s computers boot up, calculate the booster&#8217;s position, and wait until the booster had drifted far enough away from the Space Shuttle to fire its attitude control jets to turn booster around and fire the first stage.</p>



<p class="">The US military also had us apply this principle to weaponry. Automation could not initiate anything that could kill a human. A human needs to be holding the trigger on anything that could kill another human.</p>



<p class="">Same principles of not trusting automation applied to finances. The first NASDAQ trading islands were required to delay the quote information on stocks by several seconds before it reached the bidding systems. This was to discourage feedback loops in automated trading systems. Since then those limits have been eliminated, or just become ineffective. At least once the stock price of a perfectly good company was driven to <em>zero</em> causing a suspension of trading. After a day, the stock returned to its &#8220;normal&#8221; expected price. The SEC has already commented that high frequency trading, based on nothing but fluctuations of stock prices, is driving out the research driven investors that look at the fundamentals of company like profitability, indebtedness, gross sales.</p>



<p class="">When it comes to AI in the modern world, these experiences suggest some fundamental rules:</p>



<ol class="wp-block-list">
<li class="">A human must initiate any action that can potentially harm another human.<br>
<ul class="wp-block-list">
<li class="">Corollary: Industrial processes that may release toxic materials, even for safety reasons, must be initiated by a human.<br></li>



<li class="">Corollary: Automation cannot directly trade on the financial markets. Markets are for humans. High speed trading is harmful to the economy. <br></li>
</ul>
</li>



<li class="">When automation has indirect control of potentially hazardous processes (such as firing a booster after a human has enabled it), multiple redundant processes must reach a consensus to order an action.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="">Given the malleability of the web I was really surprised that OpenAI released ChatGPT into the wild without close supervision. ChatGPT has no means of checking the information fed to it but it learns from everything, so we should not be be surprised it now helps feed the flood of misinformation. </p>



<p class="">A large language model like ChatGPT is nothing but a bunch of nodes doing matrix multiplies. Modern neural networks add an occasional convolution algorithm. There is nothing in the model to drive inference or intuition. It responds purely from the data it was trained on.</p>



<p class="">A medical DNA testing company recognized the LLM (large language models) were statistical in nature, but they still needed AI to scale up the review of DNA results. Human review of DNA results just wasn&#8217;t able to keep up. They wisely created a system to monitor results and periodically manually check the results to retrain the model as needed.</p>



<p class="">Even now, though, really big LLMs like Bard, ChatGPT, are too big for effective monitoring. We don&#8217;t have a way to untrain a model once it has bogus data in it. One way to help a LLM defend itself is to create another LLM that is only trained from proctored data. That second LLM helps trains the first LLM to recognize bogus sources. The proctored LLM will help the owners determine when they need to throw away the big LLM if it strays.</p>



<p class="">Now the rubber hits the road. A corporation has spent millions training the LLM, so they will be reluctant to just throw it away. Even though the large AI occasionally lies and hallucinates, it is useful most of the time. Legal regulation is doomed to failure, so we must resort to competition where companies with LLM&#8217;s advertise how well they monitor their AI. An industry group or even a government agency could rate the AIs for consumer protection &#8212; just like the U.S. government publishes ontime performance of airlines and their safety record.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Coding Snippet</h2>



<p class="">Probably as part of a job interview, I came up with modifying heap sort to remove duplicates from an array. I haven&#8217;t seen the technique used before, but I have to think lots of undergraduate computer sci majors have come up with the same algorithm, so this exact representation is copyrighted, but feel free to modify it and use it under an MIT style license (shame on you if you attempt to put a more restrictive license on it):</p>



<pre class="wp-block-code"><code>// -*-mode: c++-*-
////
// @copyright 2024 Glen S. Dayton.
// Rights and license enumerated in the included MIT license,
//
// @author Glen S. DaRyton
//
#include &lt;cstdlib&gt;
#include &lt;algorithm&gt;
#include &lt;iterator&gt;

// Delete duplicate entries from an array using C++ heap.
template&lt;typename  random_iterator&gt;
auto deleteDuplicates(random_iterator start, random_iterator stop) -&gt; random_iterator
{
    auto topSortedArray = stop;
    auto theArrayLength = distance(start, stop);
    auto heapEnd = stop;

    if (theArrayLength &gt; 1)
    {
        // Transform the array  into a heap ( O(n) operation (linear) )
        // The range &#91;start, stop) determines the array.
        std::make_heap(start, stop);

        // Perform a heap sort
        // Pop the first element, which is the max element.
        // Shrinks the heap leaving room for the max element at the end.
        // pop_heap is a O(log N)  operation.
        auto prevElement = *start;
        std::pop_heap(start, heapEnd);
        --heapEnd;

        // push the max element onto the sorted area
        // End of the array is the sorted area.
        --topSortedArray;
        *topSortedArray = prevElement;

        // Work our way up. Pop the max element of the top of the heap and write it to the top of the sorted area.
        while (heapEnd != start)
        {
            auto currentElement = *start;
            std::pop_heap(start, heapEnd);
            --heapEnd;

            if (currentElement != prevElement)
            {
                --topSortedArray;
                *topSortedArray = currentElement;
                prevElement = currentElement;
            }
        }
    }

    return topSortedArray;
}

You may find this code and its unit tests at <a href="https://github.com/gsdayton98/deleteduplicates.git" data-type="link" data-id="https://github.com/gsdayton98/deleteduplicates.git">https://github.com/gsdayton98/deleteduplicates.git</a></code></pre>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">252</post-id>	</item>
		<item>
		<title>Woodpecker Apocalypse</title>
		<link>https://softwaresermon.com/2015/03/21/woodpecker-apocalypse/</link>
					<comments>https://softwaresermon.com/2015/03/21/woodpecker-apocalypse/#comments</comments>
		
		<dc:creator><![CDATA[dayton@ieee.org]]></dc:creator>
		<pubDate>Sat, 21 Mar 2015 18:22:51 +0000</pubDate>
				<category><![CDATA[Process]]></category>
		<category><![CDATA[Quality]]></category>
		<guid isPermaLink="false">http://www.softwaresermon.com/?p=17</guid>

					<description><![CDATA[Weinberg’s woodpecker is here, as in the the woodpecker in “If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization” (Gerald M. Weinberg, The Psychology of Computer Programming, 1971). We’ve put our finances, health information, and private thoughts on-line, entrusting them to software written in ignorance.  &#8230; <a href="https://softwaresermon.com/2015/03/21/woodpecker-apocalypse/" class="more-link">Continue reading <span class="screen-reader-text">Woodpecker Apocalypse</span></a>]]></description>
										<content:encoded><![CDATA[<p class="p1"><span class="s1">Weinberg’s woodpecker is here, as in the the woodpecker in “If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization” (Gerald M. Weinberg, <strong>The Psychology of Computer Programming</strong>, 1971)</span><span class="s1">.</span></p>
<p class="p1"><span class="s1">We’ve put our finances, health information, and private thoughts on-line, entrusting them to software written in ignorance.<span class="Apple-converted-space">  </span>Hackers exploit the flaws in that software to get your bank accounts, credit cards, and other personal information.<span class="Apple-converted-space">  </span>We protected it all behind passwords with arbitrary strength rules that we humans must remember.<span class="Apple-converted-space">  </span>Humans write the software that accepts your passwords and other input.<span class="Apple-converted-space">  </span>Now comes the woodpecker part.</span></p>
<p class="p1"><span class="s1">Being trusting souls, we’ve written our applications to not check their inputs, and depend upon the user to not enter too much.<span class="Apple-converted-space">  </span>Being human, we habitually write programs with buffer overruns, accept tainted input, and divide by zero. We write crappy software.<span class="Apple-converted-space">  </span>Heartbleed and Shellshock and a myriad of other exploits use defects in software to work their evil.</span></p>
<p class="p1"><span class="s1">Security “experts”, who make their money by making you feel insecure, tell you its impossible to write perfect software.<span class="Apple-converted-space">  </span>Balderdash.<span class="Apple-converted-space">  </span>You can write small units, and exercise every pathway in small units.<span class="Apple-converted-space">  </span>You have a computer after all.<span class="Apple-converted-space">  </span>Use the computer to elaborate the code pathways and then use the computer to generate test cases.<span class="Apple-converted-space">  </span>It is possible to exercise every path over small units.<span class="Apple-converted-space">  </span>Making the small units robust makes it easier to isolate what’s going wrong in the larger systems.<span class="Apple-converted-space">  </span>If you have two units that are completely tested, so you know they behave reasonably no matter what garbage is thrown at them, then testing the combination is sometimes redundant.<span class="Apple-converted-space">  </span>Testing software doesn’t need to be combinatorially explosive.<span class="Apple-converted-space">  </span>If you test every path in one module A and every path in module B, you don’t need to test the combination — except when the modules share resources (the evilness of promiscuous sharing is another topic).<span class="Apple-converted-space">  </span>Besides, even if we couldn’t write perfect software doesn’t mean we shouldn’t try.</span></p>
<p class="p1"><span class="s1">Barriers to quality are only a matter of imagination rather than fact.<span class="Apple-converted-space">  </span>How many times have you heard a manager say spending the time or buying the tool was too much, even though we’ve known since the 1970s that bugs caught at the developers desk cost ten times less than bugs caught later.<span class="Apple-converted-space">  </span>The interest on the technical debt is usury.<span class="Apple-converted-space">  </span>This suggests we can spend a lot more money up front on quality processes, avoid technical debt, and come out money ahead in the long run.<span class="Apple-converted-space">  </span>Bern and Schieber did their study in the 1970s.<span class="Apple-converted-space">  </span>I found this related NIST report from 2000:</span></p>
<p class="p1"><a href="http://www.nist.gov/director/planning/upload/report02-3.pdf" target="_blank">NIST Report</a></p>
<p class="p1">
<p class="p1"><span class="s1"><b>The Prescription, The Program, The Seven Steps</b></span></p>
<p class="p2"><span class="s1">Programmers cherish their step zeroes.<span class="Apple-converted-space">  </span>In this case,<span class="Apple-converted-space">  </span>step zero is just making the decision to do something about quality. <span class="Apple-converted-space">  </span>You&#8217;re reading this so I hope you&#8217;ve already made the decision, but just in case, though, let’s list the benefits of a quality process:</span></p>
<ul>
<li><span class="s1">Avoid the re-work of bugs.<span class="Apple-converted-space">  </span>A bug means you need to diagnose, test, reverse-engineer, and go over old code.<span class="Apple-converted-space">  </span>A bug is a manifestation of technical debt.<span class="Apple-converted-space">  </span>If you don’t invest in writing and performing the tests up front you are incurring technical debt with 1000% interest.<br />
</span></li>
<li class="p1"><span class="s1">Provide guarantees of security to your customers.<span class="Apple-converted-space">  </span>Maybe you can’t stop all security threats, but at least you can tell your customers what you did to prevent the known ones.</span></li>
<li class="p1"><span class="s1">Writing code with tests is faster than writing code without.<span class="Apple-converted-space">  </span>Beware of studies that largely use college student programmers, but studies show that programmers using test driven development are 15% more productive.<span class="Apple-converted-space">  </span>This doesn’t count the amount of time the organization isn’t spending on bugs.<br />
</span></li>
<li class="p1"><span class="s1">Avoid organizational death.<span class="Apple-converted-space">  </span>I use a rule of thumb about the amount of bug fixing an organization does.  I call it the &#8220;Rule of the Graveyard Spiral&#8221;.<span class="Apple-converted-space">  </span>In my experience any organization spending more than half of its time fixing bugs has less than two years to live, which is about the time the customers, or sponsoring management lose patience and cut-off the organization.<br />
</span></li>
</ul>
<p><span class="s1">So, lets assume you have made the decision to get with the program and do something about quality.<span class="Apple-converted-space">  </span>Its not complicated.  <span class="Apple-converted-space">  </span>A relatively simple series of steps instill quality and forestall installing technical debt into your program.<span class="Apple-converted-space">  </span>Here’s a simple list:</span></p>
<ol>
<li class="p1"><span class="s1">Capture requirement with tests.  Write a little documentation.</span></li>
<li class="p1"><span class="s1">Everyone tests.<span class="Apple-converted-space">  </span>Test everything.<span class="Apple-converted-space">  </span>Use unit tests.</span></li>
<li class="p1"><span class="s1">Use coverage analysis to ensure the tests cover enough.</span></li>
<li class="p1"><span class="s1">Have someone else review your code. Have a coding standard.</span></li>
<li class="p1"><span class="s1">Check your code into a branch with equivalent level of testing.</span></li>
<li class="p1"><span class="s1">When merging branches, run the tests.<span class="Apple-converted-space">  </span>Branch merges are test events.</span></li>
<li class="p1"><span class="s1">Don’t cherish bugs.<span class="Apple-converted-space">  </span>Every bug has a right to a speedy trial.<span class="Apple-converted-space">  </span>Commit to fixing them or close them.</span></li>
</ol>
<p class="p1"><span class="s1">Bear in mind that implementing this process on your own is different than persuading an organization to apply the process.<span class="Apple-converted-space">  </span>Generally, if a process makes a person’s job easier, they will follow it.<span class="Apple-converted-space">  </span>The learning curve on a test driven process can be steeper than you expect because you must design a module, class, or function to be testable.<span class="Apple-converted-space">  </span>More on that later.<span class="Apple-converted-space"> </span></span></p>
<p class="p1"><span class="s1">On top of that, you need to persuade the organization that writing twice as much code (the test and the functional code) is actually faster than writing just the code and testing later.<span class="Apple-converted-space">  </span>In most organizations, though, nothing succeeds like success.<span class="Apple-converted-space">  </span>In my personal experience the developers who learned to write testable code and wrote unit tests never go back to the old way of doing things.<span class="Apple-converted-space">  </span>On multiple occasions putting legacy code that was causing customer escalations under unit test eliminated <i>all </i>customer escalations.<span class="Apple-converted-space">  </span>Zero is a great number for number of bugs.</span></p>
<p class="p2"><span class="s1"><b>Details</b></span></p>
<ol>
<li class="p1"><span class="s1"><b>Capture requirements with tests.</b></span></li>
</ol>
<p class="p3"><span class="s1">Good requirements are quantifiable and testable.<span class="Apple-converted-space">  </span>You know you have a good requirement when<span class="Apple-converted-space">  </span>you can build an automated test for it. Capture your requirements in tests.<span class="Apple-converted-space">  </span>For tests on behavior of a GUI use a tool like Sikuli (<a href="http://www.sikuli.org/"><span class="s2">http://www.sikuli.org/</span></a>).<span class="Apple-converted-space">  </span>If you&#8217;re testing boot time behavior, use a KVM switch and a second machine to capture the boot screens.<span class="Apple-converted-space">  </span>Be very reluctant to accept a manual test.<span class="Apple-converted-space">  </span>Be very sure that the test can’t be automated.<span class="Apple-converted-space">  </span>Remember the next developer that deals with your code may not be as diligent as you so manual tests become less likely to be re-run when the code is modified.</span></p>
<hr />
<p class="p3">Closely related to capturing your requirements in tests, is documenting your code.  Documentation is tough.  Whenever you write two related things in two different places, those two different things will get out of sync and become obsolete in relationship to the other.</p>
<p class="p3"><span class="s1">It might as well be a law of configuration management:<span class="Apple-converted-space">  </span><em>Any collection residing in two or more places will diverge</em>.</span></p>
<p class="p3"><span class="s1">So put the documention and code in the same place.<span class="Apple-converted-space">  </span>Use doxygen (<a href="http://www.stack.nl/~dimitri/doxygen/"><span class="s2">http://www.stack.nl/~dimitri/doxygen/</span></a>) .<span class="Apple-converted-space">  </span>Make your code self documenting.<span class="Apple-converted-space">  </span>Pay attention to the block of documentation at the top of the file where you can describe how the pieces work together.<span class="Apple-converted-space">  </span>On complicated systems, bite the bullet and provide an external file that describes how it all works together. <span class="Apple-converted-space">  </span>The documentation in the code tends to deal with only that code and not its related neighbors, so spend some time describing how it works together.  Relations are important.</span></p>
<p class="p3"><span class="s1">You need just enough external documentation to tell the next developer where to start.<span class="Apple-converted-space">  </span>I like to use a wiki for my projects.<span class="Apple-converted-space">  </span>As each new developer comes into the project I point them to the wiki, and I ask them to update the wiki where they had trouble due to incompleteness or obsolescence.<span class="Apple-converted-space">  </span>I’m rather partial to MediaWiki (<a href="https://www.mediawiki.org/wiki/MediaWiki"><span class="s2">https://www.mediawiki.org/wiki/MediaWiki</span></a>).<span class="Apple-converted-space">  </span>For some reason other people like Confluence (<a href="http://www.atlassian.com/Confluence"><span class="s2">http://www.atlassian.com/Confluence</span></a> ).<span class="Apple-converted-space">  </span>Pick your own wiki at <a href="http://www.wikimatrix.org/"><span class="s2">http://www.wikimatrix.org/</span></a> .</span></p>
<p class="p4"><span class="s1">Don&#8217;t go overboard on documentation. Too much means nobody will read it nor maintain it so it will quickly diverge to having little relation to the original code.<span class="Apple-converted-space">  </span>Documentation is part of the code.<span class="Apple-converted-space">  </span>Change the code or documentation, change the other.</span></p>
<p class="p4">Steps 2 through 7 deserve their own posts.</p>
<blockquote><p>I&#8217;m past due on introducing myself.  I&#8217;m Glen Dayton.  I wrote my first program, in FORTRAN, in 1972.  Thank you Mr. McAfee.   Since then I&#8217;ve largely worked in aerospace, but then I moved to the Silicon Valley to marry my wife and take my turn on the start-up merry-go-around.  Somewhere in the intervening time Saint Wayne V. introduced me to test driven development.  After family and friends, the most important thing I ever worked on was PGP.</p></blockquote>
<hr />
<p>Today&#8217;s coding joke is the Double Check Locking Pattern.  After all these years I still find people writing it.  Read about it and its evils at</p>
<p><a href="http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf" target="_blank">C++ and the Perils of Double-Checked Locking</a></p>
<p>When you see the the following code, software engineers will forgive you if you scream or laugh:</p>
<pre style="color: #000000; background: #ffffff;"><span style="color: #800000; font-weight: bold;">static</span> Widget <span style="color: #808030;">*</span>ptr <span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">static</span> pthread_mutex_t lock <span style="color: #808030;">=</span> PTHREAD_MUTEX_INITIALIZER<span style="color: #800080;">;</span>

<span style="color: #696969;">// ...</span>
<span style="color: #800000; font-weight: bold;">if</span> <span style="color: #808030;">(</span>ptr <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #808030;">)</span>
<span style="color: #800080;">{</span>
  pthread_mutex_lock<span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>lock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #800000; font-weight: bold;">if</span> <span style="color: #808030;">(</span>ptr <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #808030;">)</span>
       ptr <span style="color: #808030;">=</span> <span style="color: #800000; font-weight: bold;">new</span> Widget<span style="color: #800080;">;</span>
    pthread_mutex_unlock<span style="color: #808030;">(</span><span style="color: #808030;">&amp;</span>lock<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
<span style="color: #800080;">}</span>
<span style="color: #800000; font-weight: bold;">return</span> ptr<span style="color: #800080;">;</span>
</pre>
<p>One way to fix the code is to just use the lock.  Most modern operating systems implement a mutex with a spin lock so you don&#8217;t need to be shy about using them:</p>
<pre style="color: #000000; background: #ffffff;"><span style="color: #800000; font-weight: bold;">using</span> boost<span style="color: #800080;">::</span>mutex<span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">using</span> boost<span style="color: #800080;">::</span>lock_guard<span style="color: #800080;">;</span>

<span style="color: #800000; font-weight: bold;">static</span> Widget <span style="color: #808030;">*</span>ptr <span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">static</span> mutex mtx<span style="color: #800080;">;</span>

<span style="color: #696969;">//...</span>

<span style="color: #800080;">{</span>
    lock_guard<span style="color: #800080;">&lt;</span>mutex<span style="color: #800080;">&gt;</span> lock<span style="color: #808030;">(</span>mtx<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #800000; font-weight: bold;">if</span> <span style="color: #808030;">(</span>ptr <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #808030;">)</span>
       ptr <span style="color: #808030;">=</span> <span style="color: #800000; font-weight: bold;">new</span> Widget<span style="color: #800080;">;</span>
<span style="color: #800080;">}</span>
<span style="color: #800000; font-weight: bold;">return</span> ptr<span style="color: #800080;">;</span>
</pre>
<p>Another way, if you&#8217;re still shy about locks, is to use memory ordering primitives.  C++11 offers atomic variables and memory ordering primitives.</p>
<pre style="color: #000000; background: #ffffff;"><span style="color: #004a43;">#</span><span style="color: #004a43;">include </span><span style="color: #800000;">&lt;</span><span style="color: #40015a;">boost/atomic/atomic.hpp</span><span style="color: #800000;">&gt;</span>
<span style="color: #004a43;">#</span><span style="color: #004a43;">include </span><span style="color: #800000;">&lt;</span><span style="color: #40015a;">boost/memory_order.hpp</span><span style="color: #800000;">&gt;</span>
<span style="color: #004a43;">#</span><span style="color: #004a43;">include </span><span style="color: #800000;">&lt;</span><span style="color: #40015a;">boost/thread/mutex.hpp</span><span style="color: #800000;">&gt;</span>
<span style="color: #004a43;">#</span><span style="color: #004a43;">include </span><span style="color: #800000;">&lt;</span><span style="color: #40015a;">boost/thread/locks.hpp</span><span style="color: #800000;">&gt;</span>

<span style="color: #800000; font-weight: bold;">class</span> Widget
<span style="color: #800080;">{</span>
<span style="color: #800000; font-weight: bold;">public</span><span style="color: #e34adc;">:</span>
  Widget<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>

  <span style="color: #800000; font-weight: bold;">static</span> Widget<span style="color: #808030;">*</span> instance<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">private</span><span style="color: #e34adc;">:</span>
<span style="color: #800080;">}</span><span style="color: #800080;">;</span>
Widget<span style="color: #808030;">*</span>
Widget<span style="color: #800080;">::</span>instance<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: #800080;">{</span>
  <span style="color: #800000; font-weight: bold;">static</span> boost<span style="color: #800080;">::</span>atomic<span style="color: #800080;">&lt;</span>Widget <span style="color: #808030;">*</span><span style="color: #800080;">&gt;</span> s_pWidget<span style="color: #808030;">(</span><span style="color: #7d0045;">NULL</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
  <span style="color: #800000; font-weight: bold;">static</span> boost<span style="color: #800080;">::</span>mutex s_mutex<span style="color: #800080;">;</span>

  Widget<span style="color: #808030;">*</span> tmp <span style="color: #808030;">=</span> s_pWidget<span style="color: #808030;">.</span>load<span style="color: #808030;">(</span>boost<span style="color: #800080;">::</span>memory_order_acquire<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
  <span style="color: #800000; font-weight: bold;">if</span> <span style="color: #808030;">(</span>tmp <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #808030;">)</span>
  <span style="color: #800080;">{</span>
    boost<span style="color: #800080;">::</span>lock_guard<span style="color: #800080;">&lt;</span>boost<span style="color: #800080;">::</span>mutex<span style="color: #800080;">&gt;</span> lock<span style="color: #808030;">(</span>s_mutex<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    tmp <span style="color: #808030;">=</span> s_pWidget<span style="color: #808030;">.</span>load<span style="color: #808030;">(</span>boost<span style="color: #800080;">::</span>memory_order_relaxed<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #800000; font-weight: bold;">if</span> <span style="color: #808030;">(</span>tmp <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #808030;">)</span> <span style="color: #800080;">{</span>
      tmp <span style="color: #808030;">=</span> <span style="color: #800000; font-weight: bold;">new</span> Widget<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
      s_pWidget<span style="color: #808030;">.</span>store<span style="color: #808030;">(</span>tmp<span style="color: #808030;">,</span> boost<span style="color: #800080;">::</span>memory_order_release<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
    <span style="color: #800080;">}</span>
  <span style="color: #800080;">}</span>
  <span style="color: #800000; font-weight: bold;">return</span> tmp<span style="color: #800080;">;</span>
<span style="color: #800080;">}</span>
</pre>
<p>If the check for the lock, though, occurs in a high traffic area, you may not want to pay the cost of flushing the data cache for every atomic check, so use a thread local variable for the check:</p>
<pre style="color: #000000; background: #ffffff;"><span style="color: #800000; font-weight: bold;">using</span> boost<span style="color: #800080;">::</span>mutex<span style="color: #800080;">;</span>
<span style="color: #800000; font-weight: bold;">using</span> boost<span style="color: #800080;">::</span>lock_guard<span style="color: #800080;">;</span>

Widget<span style="color: #808030;">*</span>
Widget<span style="color: #800080;">::</span>instance<span style="color: #808030;">(</span><span style="color: #808030;">)</span>
<span style="color: #800080;">{</span>
    <span style="color: #800000; font-weight: bold;">static</span> <span style="color: #800000; font-weight: bold;">__thread</span> Widget <span style="color: #808030;">*</span>tlv_instance <span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #800080;">;</span>
    <span style="color: #800000; font-weight: bold;">static</span> Widget <span style="color: #808030;">*</span>s_instance <span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #800080;">;</span>
    <span style="color: #800000; font-weight: bold;">static</span> mutex s_mutex<span style="color: #800080;">;</span>

    <span style="color: #800000; font-weight: bold;">if</span> <span style="color: #808030;">(</span>tlv_instance <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #808030;">)</span>
    <span style="color: #800080;">{</span>
        lock_guard<span style="color: #800080;">&lt;</span>mutex<span style="color: #800080;">&gt;</span> lock<span style="color: #808030;">(</span>s_mutex<span style="color: #808030;">)</span><span style="color: #800080;">;</span>
        <span style="color: #800000; font-weight: bold;">if</span> <span style="color: #808030;">(</span>s_instance <span style="color: #808030;">=</span><span style="color: #808030;">=</span> <span style="color: #7d0045;">NULL</span><span style="color: #808030;">)</span>
            s_instance <span style="color: #808030;">=</span> <span style="color: #800000; font-weight: bold;">new</span> Widget<span style="color: #808030;">(</span><span style="color: #808030;">)</span><span style="color: #800080;">;</span>
        tlv_instance <span style="color: #808030;">=</span> s_instance<span style="color: #800080;">;</span>
    <span style="color: #800080;">}</span>

    <span style="color: #800000; font-weight: bold;">return</span> tlv_instance<span style="color: #800080;">;</span>
<span style="color: #800080;">}</span>
</pre>
<p>Of course, everything is a trade-off. A thread local variable is sometimes implemented as an index into an array of values allocated for the thread, so it can be expensive.  Your mileage may vary.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://softwaresermon.com/2015/03/21/woodpecker-apocalypse/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">17</post-id>	</item>
	</channel>
</rss>
