<?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>winJade &#187; Infinite Loop</title>
	<atom:link href="http://winjade.net/tag/infinite-loop/feed/" rel="self" type="application/rss+xml" />
	<link>http://winjade.net</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Sun, 27 Jun 2010 23:47:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A lesson on infinite loops</title>
		<link>http://winjade.net/2009/01/lesson-on-infinite-loops/</link>
		<comments>http://winjade.net/2009/01/lesson-on-infinite-loops/#comments</comments>
		<pubDate>Sat, 03 Jan 2009 20:57:35 +0000</pubDate>
		<dc:creator>Bryant Zadegan</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[dev fail]]></category>
		<category><![CDATA[in depth]]></category>
		<category><![CDATA[Infinite Loop]]></category>
		<category><![CDATA[Zune 30]]></category>

		<guid isPermaLink="false">http://www.aeroxp.org/?p=756</guid>
		<description><![CDATA[
pre {
    font-size: medium;
    }

&#160;
&#160;
Yesterday, I took a look at the varying perspectives taken with regards to the Zune 30 debacle. Today, I’ll take a look at what exactly led the Zune 30s to freeze. If you’d like to see the code for the entire driver, click here.
Below the [...]]]></description>
			<content:encoded><![CDATA[<style  TYPE="text/css">
pre {
    font-size: medium;
    }
</style>
<p>&#160;<img style="border-top-width: 0px; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; display: block; border-right-width: 0px" title="quality assurance baby" border="0" alt="quality assurance baby" src="http://winjade.net/wp-content/uploads/2009/01/qualityassurancebaby1.png" width="640" height="480" /></p>
<p>&#160;</p>
<p>Yesterday, <a href="http://www.aeroxp.org/2009/01/zune-30-bug-overinflated/" target="_blank">I took a look</a> at the varying perspectives taken with regards to the Zune 30 debacle. Today, I’ll take a look at what exactly led the Zune 30s to freeze. If you’d like to see the code for the entire driver, <a href="http://pastie.org/349916">click here</a>.</p>
<p>Below the fold lies a sufficiently sized code sample with everything you’ll need to understand what happened with the Zune 30 bug.</p>
<p><script type="text/javascript">
digg_url = 'http://www.aeroxp.org/2009/01/lesson-on-infinite-loops/';
</script><br />
<script src="http://digg.com/tools/diggthis.js" type="text/javascript"></script> </p>
<p> <span id="more-756"></span>
</p>
<p>Relevant code is non-gray code:</p>
<blockquote><pre><font color="#ff00ff"><font color="#000000">#</font>define</font> <font color="#000080">ORIGINYEAR</font> <font color="#ff0000">1980</font> <font color="#000000">
<font color="#008000">BOOL</font> ConvertDays(<font color="#008000">UINT32</font> days<font color="#808080">, SYSTEMTIME* lpTime</font>)
{
    <font color="#008000">int</font> <font color="#808080">dayofweek, month,</font> year;
    <font color="#808080">UINT8 *month_tab;</font>

    <font color="#808080">//Calculate current day of the week
    dayofweek = GetDayOfWeek(days);</font>

    year = <font color="#000080">ORIGINYEAR</font>;

    <font color="#800000">while</font> (days &gt; <font color="#ff0000">365</font>)
    {
        <font color="#800000">if</font> (IsLeapYear(year))
        {
            <font color="#800000">if</font> (days &gt; <font color="#ff0000">366</font>)
            {
                days -= <font color="#ff0000">366</font>;
                year += <font color="#ff0000">1</font>;
            }
        }
        <font color="#800000">else</font>
        {
            days -= <font color="#ff0000">365</font>;
            year += <font color="#ff0000">1</font>;
        }
    }

<font color="#808080">    // Determine whether it is a leap year
    month_tab = (UINT8 *)((IsLeapYear(year))? monthtable_leap : monthtable);

    for (month=0; month&lt;12; month++)
    {
        if (days &lt;= month_tab[month])
            break;
        days -= month_tab[month];
    }

    month += 1;

    lpTime-&gt;wDay = days;
    lpTime-&gt;wDayOfWeek = dayofweek;
    lpTime-&gt;wMonth = month;
    lpTime-&gt;wYear = year;

    return TRUE;
</font>}</font></pre>
</blockquote>
<p>So what’s the purpose of the while loop? To put it simply, it’s designed to get the number of years from the number of days since 1980 as well as a remainder of days out of the current year. Well, let’s look at how the code plays out in my confusingly simple <em>While Loop in Plain English™</em>. Keep in mind that you’re <em>never </em>supposed to retry the loop without committing some sort of action which will ultimately exit the loop:</p>
<ol>
<li>year is set to ORIGINYEAR. Since ORIGINYEAR is 1980, any addition to year is added on top of 1980. This is fine because the hardware is passing the number of days since January 1, 1980. </li>
<li>Is the number of days greater than 365? If so, proceed. Otherwise, skip to number 6. </li>
<li>Is the current year a leap year? If so, proceed. Otherwise, subtract 365 from the number of days, add 1 to the number of years, and skip to number 5. </li>
<li>Is the number of days greater than 366? If so, subtract 366 from the number of days, add 1 to the number of years, and proceed. </li>
<li>retry number 2. </li>
<li>…</li>
<li>Profit? </li>
</ol>
<p>The problem lies in the fact that there is one case which can never escape the loop. If it’s a leap year, the number 366 will stay within the loop forever because 366 will never be greater than 366, but 366 will also always be greater than 365. 366 days will pass through, in our Plain English While Loop, without having any action committed upon it.</p>
<p>There’s a very quick solution to this: Since 366 is a valid remainder of days in a leap year (December 31 is the 366th day in a leap year), 366 can technically exit the loop without any problems. All we need to do is add a way to exit the loop when the number of days is 366. Let’s see how things go with this new breakpoint:</p>
<ol>
<li>year is set to ORIGINYEAR. Since ORIGINYEAR is 1980, any addition to year is added on top of 1980. This is fine because the hardware is passing the number of days since January 1, 1980. </li>
<li>Is the number of days greater than 365? If so, proceed. Otherwise, skip to number 6. </li>
<li>Is the current year a leap year? If so, proceed. Otherwise, subtract 365 from the number of days, add 1 to the number of years, and skip to number 5. </li>
<li>Is the number of days greater than 366? If so, subtract 366 from the number of days, add 1 to the number of years, and proceed. Otherwise, skip to number 6. </li>
<li>retry number 2. </li>
<li>…</li>
<li>Profit!</li>
</ol>
<p>Thanks to the break (represented by “Otherwise, skip to number 6”), 366 days can escape the loop properly. This would lead to the end result for December 31, 2008 being years == 2008 and days == 366.</p>
<p>This is what the break would look in the while loop:</p>
<blockquote>
<pre><font color="#000000">    <font color="#800000">while</font> (days &gt; <font color="#ff0000">365</font>)
    {
        <font color="#800000">if</font> (IsLeapYear(year))
        {
            <font color="#800000">if</font> (days &gt; <font color="#ff0000">366</font>)
            {
                days -= <font color="#ff0000">366</font>;
                year += <font color="#ff0000">1</font>;
            }
            <font color="#800000">else</font>
            {
                <font color="#800000">break;</font>
            }
        }
        <font color="#800000">else</font>
        {
            days -= <font color="#ff0000">365</font>;
            year += <font color="#ff0000">1</font>;
        }
    }
</font></pre>
</blockquote>
<p>Clarifying one quick thing: A number of people on outlets such as Digg suggested that changing “<font color="#800000">if</font> (days &gt; <font color="#ff0000">366</font>)” to “<font color="#800000">if</font> (days &gt;= <font color="#ff0000">366</font>)”:</p>
<p><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; display: inline; border-right-width: 0px" title="QAdigg" border="0" alt="QAdigg" src="http://winjade.net/wp-content/uploads/2009/01/qadigg.png" width="660" height="158" /></p>
<p>The problem with doing this is that the end result, upon hitting “<font color="#800000">if</font> (days &gt;= <font color="#ff0000">366</font>)” with the value 366, one would end up with the year going up by one and the operation “<font color="#ff0000">366 –</font>= <font color="#ff0000">366</font>” playing out. End result: December 31 of the leap year is suddenly January 0 of the following year.</p>
<p>&#160;</p>
<p><strong>Extra credit:</strong> This loop can be fixed such that the loop’s condition is based on the year’s status as a leap year. The change needed is simple:</p>
<blockquote>
<pre><font color="#000000">    <font color="#800000">while</font> (days &gt; (IsLeapYear(year) ? <font color="#ff0000">366</font> : <font color="#ff0000">365</font>))
    <font color="#008080">//The above line basically says “Is it a leap year? Check days against 366.
    //Otherwise, check it against 365”</font>
    {
        <font color="#800000">if</font> (IsLeapYear(year))
        {
            days -= <font color="#ff0000">366</font>;
            year += <font color="#ff0000">1</font>;
            <font color="#008080">/*You’ll notice we no longer need a break. The loop condition now
             *checks the days properly. Because the loop properly checks
             *whether days is greater than 365 or 366, the second days &gt; 366
             *check is no longer needed. */</font>
        }
        <font color="#800000">else</font>
        {
            days -= <font color="#ff0000">365</font>;
            year += <font color="#ff0000">1</font>;
        }
    }
</font></pre>
</blockquote>
<p>&#160;</p>
<p>However, if this change is made, IsLeapYear() is now being called twice. This is inefficient, especially on small devices (like the devices which would be using this driver). In order to reduce the number of times IsLeapYear() is being called, it would be best to store the value of IsLeapYear() in a variable.</p>
<blockquote>
<pre><font color="#000000">    <font color="#008000">int</font> leap = IsLeapYear(year);
    <font color="#008080">//leap is determined before the loop begins.
    //In this case, it would be true (1980 is a leap year)</font>
    <font color="#800000">while</font> (days &gt; (leap ? <font color="#ff0000">366</font> : <font color="#ff0000">365</font>))
    {
        <font color="#800000">if</font> (leap)
        {
            days -= <font color="#ff0000">366</font>;
            year += <font color="#ff0000">1</font>;
        }
        <font color="#800000">else</font>
        {
            days -= <font color="#ff0000">365</font>;
            year += <font color="#ff0000">1</font>;
        }
        leap = IsLeapYear(year);
        <font color="#008080">//leap is determined again now that the year has changed.</font>
    }
</font></pre>
</blockquote>
<p>This can actually be reduced even further. If you look at how the if/else statement is operating, you can see that it’s basically saying “If it’s a leap year, subtract 366. Otherwise, subtract 365,” which is similar to the while loop’s condition!</p>
<blockquote>
<pre><font color="#000000">    <font color="#008000">int</font> leap = IsLeapYear(year);
    <font color="#800000">while</font> (days &gt; (leap ? <font color="#ff0000">366</font> : <font color="#ff0000">365</font>))
    {
        days -= (leap ? <font color="#ff0000">366</font> : <font color="#ff0000">365</font>);
        <font color="#008080">//days is equal to days - 366 if it's a leap year,
        //                 days - 365 if it isn't.</font>
        year += <font color="#ff0000">1</font>;
        leap = IsLeapYear(year);
    }
</font></pre>
</blockquote>
<p>If you wanted to reduce the number of times (leap ? <font color="#ff0000">366</font> : <font color="#ff0000">365</font>) is checked, you could do this instead:</p>
<blockquote>
<pre><font color="#000000">    <font color="#008000">int</font> daysThisYear = (IsLeapYear(year) ? <font color="#ff0000">366</font> : <font color="#ff0000">365</font>);
    <font color="#008080">//The number of days in the current year is now calculated instead. </font>
    <font color="#800000">while</font> (days &gt; daysThisYear)
    {
        days -= daysThisYear;
        year += <font color="#ff0000">1</font>;
        daysThisYear = (IsLeapYear(year) ? <font color="#ff0000">366</font> : <font color="#ff0000">365</font>);
    }
</font></pre>
</blockquote>
<p>It’s questionable whether or not this code is any better than the original solution with the break, but this would be the “proper” way to do it (instead of using an arbitrary break in your code). It’s also easier to understand if you know C.</p>
<p>The irony in all of this is that this specific driver is used in multiple Windows CE devices, not just the Zune. This is why quality assurance is so necessary.</p>
<p><strong>There are three morals here: </strong></p>
<ol>
<li><strong>Test every condition which could happen in every single loop in your code </strong>(though, as Matt Boehm points out in the comments, this might be a <a href = "http://www.aeroxp.org/2009/01/lesson-on-infinite-loops/#comment-831">tad bit hard</a>). </li>
<li><strong>Don’t visit Digg for programming advice. What you’ll hear is questionable at best</strong> </li>
<li><strong>Make your code easy to read for other developers.</strong> </li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://winjade.net/2009/01/lesson-on-infinite-loops/feed/</wfw:commentRss>
		<slash:comments>157</slash:comments>
		</item>
		<item>
		<title>The Zune 30 bug was overinflated</title>
		<link>http://winjade.net/2009/01/zune-30-bug-overinflated/</link>
		<comments>http://winjade.net/2009/01/zune-30-bug-overinflated/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 23:13:45 +0000</pubDate>
		<dc:creator>Bryant Zadegan</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[dev fail]]></category>
		<category><![CDATA[Infinite Loop]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Press Fail]]></category>
		<category><![CDATA[Zune]]></category>
		<category><![CDATA[Zune 30]]></category>

		<guid isPermaLink="false">http://www.aeroxp.org/2009/01/zune-30-bug-overinflated/</guid>
		<description><![CDATA[(My sincerest apologies; this post was unpublished due to a database error. The issue has since been fixed.
This is a shout-out to all Zune 30 owners who remained patient. 
This is to you, the faithful owner of a Zune 30, who didn&#8217;t buckle under stress and kept a keen eye on Microsoft, waiting for a [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-top-width: 0px; border-left-width: 0px; float: none; border-bottom-width: 0px; margin-left: auto; margin-right: auto; display: block; border-right-width: 0px" title="Zune Logo" border="0" alt="Zune Logo" src="http://winjade.net/wp-content/uploads/2009/01/zunelogo.png" width="446" height="360" /><br /><em>(My sincerest apologies; this post was unpublished due to a database error. The issue has since been fixed.</em></p>
<p>This is a shout-out to all Zune 30 owners who remained patient. </p>
<p>This is to you, the faithful owner of a Zune 30, who didn&#8217;t buckle under stress and kept a keen eye on Microsoft, waiting for a solution. </p>
<p>This is to you, the discount shopper who picked up a Zune 30 and didn&#8217;t want to lose faith in your hardware. </p>
<p>Low and behold, Microsoft dug deep to find out the problem and, within minutes of finding out exactly what it was, pushed out an answer and a solution that <em>didn&#8217;t</em> void your warranty (thanks, Gizmodo). There&#8217;s a reason for why I&#8217;m bringing all of this up. July of 2008 saw <a href="http://www.betanews.com/article/Activation_problems_delay_sales_during_iPhone_3G_premiere/1215779644">cataclysmic</a> <a href="http://blogs.zdnet.com/Apple/?p=1972">server</a> <a href="http://www.engadget.com/2008/07/11/itunes-activation-servers-go-down-iphone-3g-customers-being-sen/">failure</a> when a vast majority of all newly-purchased iPhone 3G units tried activating at nearly the same time, leaving both new iPhone 3Gs and some iPhone Gen 1 units dead in the water until the activation servers came back online. Poor planning led to the creation of a load-intolerant system on AT&amp;T&#8217;s side (though the blame hardly belongs to them, given that Apple mandated this system in the first place). However, people weren&#8217;t infuriated by Apple&#8217;s ineptitude here. They were complacent and merely went with whatever explanation was fed to them. Meanwhile, a sizable majority of people who stuck with their own platforms of choice decided <em>not</em> to point and jeer. </p>
<p>Fast forward to December 31, 2008, and <a href="http://community.winsupersite.com/blogs/paul/archive/2008/12/31/zune-30s-succumb-to-software-glitch.aspx">every</a> <a href="http://blogs.zdnet.com/microsoft/?p=1784">Zune 30</a> <a href="http://www.msnbc.msn.com/id/28449091/">device</a> <a href="http://blog.seattlepi.nwsource.com/microsoft/archives/158313.asp">freezes</a> due to a bug in a driver from Freescale Semiconductor in this while loop (<a href="http://pastie.org/349916">between lines 259 and 274</a>): </p>
<blockquote><pre>    while (days &gt; 365)
    {
        if (IsLeapYear(year))
        {
            if (days &gt; 366)
            {
                days -= 366;
                year += 1;
            }
        }
        else
        {
            days -= 365;
            year += 1;
        }
    }</pre>
</blockquote>
<p><em>(protip: day 366 triggers an infinite loop. To see the context of the code, check out the pastie link above, or just <a href="http://pastie.org/349916">click here</a>. You can see a breakdown of how this could&#8217;ve been handled <a href = "http://www.aeroxp.org/2009/01/lesson-on-infinite-loops/">here</a>)</em>&#160; </p>
<p>What happened? Every Apple-loyal iPhone, iPod, and Mac owner threw a fit even though none of them actually owned a Zune 30 (You can&#8217;t run a Zune 30&#8230; or any Zune, for that matter, on a Mac). Thanks in part to the additional sensationalism promoted by gadget bloggers and, subsequently, news outlets the world over, a problem with a Zune model sold only in North America suddenly became a &quot;Worldwide Zune Outage.&quot; </p>
<p>This is the difference between the Social and the Kingdom of Apple. Those with Zunes held out patiently and were rewarded with verbose output by Microsoft, whereas Apple simply vaguely alluded to some other company being the source of their problems (or were otherwise mute for a long period of time) whenever something on Apple&#8217;s side went wrong. </p>
<p>Thank you, Zune 30 owners, for living up to the hype of the Social. I&#8217;m now quite proud to be an owner of a Zune myself.</p>
]]></content:encoded>
			<wfw:commentRss>http://winjade.net/2009/01/zune-30-bug-overinflated/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
	</channel>
</rss>
