<?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>tdistler.com &#187; development</title>
	<atom:link href="http://tdistler.com/tag/development/feed" rel="self" type="application/rss+xml" />
	<link>http://tdistler.com</link>
	<description>&#34;To err is human, but to really foul things up you need a computer.”</description>
	<lastBuildDate>Tue, 06 Dec 2011 20:46:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Inside the .NET CLR Garbage Collector</title>
		<link>http://tdistler.com/2011/09/09/inside-the-net-clr-garbage-collector</link>
		<comments>http://tdistler.com/2011/09/09/inside-the-net-clr-garbage-collector#comments</comments>
		<pubDate>Fri, 09 Sep 2011 15:00:29 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[Tech and Security]]></category>
		<category><![CDATA[architecture]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=1049</guid>
		<description><![CDATA[Here&#8217;s a great interview with Microsoft Technical Fellow and author of the CLR garbage collector, Patrick Dussud. How does GC, work, generally? Why is it important? The GC inside of the CLR is of a specfic type &#8211; ephemeral, concurrent (the server version has always been concuurent and now with Background GC on the client [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a great interview with Microsoft Technical Fellow and author of the CLR garbage collector, <a title="Profile: Patrick Dussud" href="http://www.microsoft.com/presspass/exec/techfellow/dussud/default.mspx" target="_blank">Patrick Dussud</a>.</p>
<blockquote><p>How does GC, work, generally? Why is it important? The GC inside of the CLR is of a specfic type &#8211; ephemeral, concurrent (the server version has always been concuurent and now with Background GC on the client in CLR 4, GC is concurrent on the client as well, but there are differences&#8230;)</p></blockquote>
<p><iframe style="height: 288px; width: 512px;" src="http://channel9.msdn.com/Shows/Going+Deep/E2E-Erik-Meijer-and-Patrick-Dussud-Inside-Garbage-Collection/player?w=512&amp;h=288" frameborder="0" scrolling="no" width="320" height="240"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/09/09/inside-the-net-clr-garbage-collector/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CRC32: A Simple C++ Class</title>
		<link>http://tdistler.com/2011/06/22/crc32-a-simple-c-class</link>
		<comments>http://tdistler.com/2011/06/22/crc32-a-simple-c-class#comments</comments>
		<pubDate>Wed, 22 Jun 2011 17:32:51 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=993</guid>
		<description><![CDATA[A simple C++ class for calculating CRC32.]]></description>
			<content:encoded><![CDATA[<p><a title="Wikipedia: Cyclic Redundancy Check" href="http://en.wikipedia.org/wiki/Cyclic_redundancy_check" target="_blank">Cyclic Redundancy Checks</a> are a quick and convenient way to verify if a data set has changed. They are not meant to be &#8220;secure&#8221; like a MD5 or SHA-1, but they offer a very practical solution to most problems. CRC&#8217;s are also useful for verifying if 2 data sets are equal. Here&#8217;s a simple class I use that&#8217;s efficient. Honestly, I don&#8217;t remember what flavor of CRC32 it implements (sorry), but it has always worked for what I&#8217;ve needed. Cheers!</p>
<pre><code>static const uint32_t kCrc32Table[256] = {
    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
    0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
    0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
    0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
    0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
    0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
    0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
    0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
    0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
    0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,<span id="more-993"></span>
    0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
    0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
    0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
    0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
    0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
    0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
    0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
    0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
    0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
    0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
    0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
    0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
    0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
    0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
    0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
    0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
    0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
    0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
    0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
    0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
    0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
    0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
    0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
    0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
    0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
    0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
}; // kCrc32Table

class Crc32
{
public:
    Crc32() { Reset(); }
    ~Crc32() throw() {}
    void Reset() { _crc = (uint32_t)~0; }
    void AddData(const uint8_t* pData, const uint32_t length)
    {
        uint8_t* pCur = (uint8_t*)pData;
        uint32_t remaining = length;
        for (; remaining--; ++pCur)
            _crc = ( _crc &gt;&gt; 8 ) ^ kCrc32Table[(_crc ^ *pCur) &amp; 0xff];
    }
    const uint32_t GetCrc32() { return ~_crc; }

private:
    uint32_t _crc;
};

</code></pre>
<p><strong>Note</strong>: I always have <code>uint32_t</code> defined in Windows, so you may have to define it yourself or use the Microsoft intrinsic <code>unsigned __int32</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/06/22/crc32-a-simple-c-class/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How To Test An Audio Codec: A Practical Approach</title>
		<link>http://tdistler.com/2011/01/25/how-to-test-an-audio-codec-a-practical-approach</link>
		<comments>http://tdistler.com/2011/01/25/how-to-test-an-audio-codec-a-practical-approach#comments</comments>
		<pubDate>Wed, 26 Jan 2011 01:16:28 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[Did you know?]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=727</guid>
		<description><![CDATA[Recently, I was tasked with picking an AAC audio codec library for one of our products. There were several libraries I had to evaluate, and I needed some quantitative metrics for doing the comparison. I&#8217;m not what professionals call an &#8220;expert listener&#8221;, so I had to do the best with what I had. While creating [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2011/01/audio_waveform.jpg"><img class="alignright size-thumbnail wp-image-732" title="audio_waveform" src="http://tdistler.com/wp-content/uploads/2011/01/audio_waveform-150x150.jpg" alt="" width="150" height="150" /></a>Recently, I was tasked with picking an AAC audio codec library for one of our products. There were several libraries I had to evaluate, and I needed some quantitative metrics for doing the comparison. I&#8217;m not what professionals call an &#8220;expert listener&#8221;, so I had to do the best with what I had. While creating my test plan, I noticed that more people seemed interested in <em>how</em> I was doing testing rather than the actual results. So I decided to share my approach to audio codec testing.</p>
<p><strong>Note</strong>: <em>This is intended to be a pragmatic guide for engineers evaluating codecs. It is not a comprehensive treatment of the subject. The goal is to give readers a solid overview and some practical ideas</em>.</p>
<p><strong>Get Familiar with Psychoacoustics</strong></p>
<p><a title="Wikipedia: Psychoacoustics" href="http://en.wikipedia.org/wiki/Psychoacoustics" target="_blank">Psychoacoustics</a> is the study of how humans <em>perceive</em> sound. As you might expect, we humans don&#8217;t process sound in a perfect, linear fashion. The physical shape of the ear, the transfer function of the Basilar membrane, and the psychological interpretation of the data all affect how we perceive sound (and by extension, how &#8220;good&#8221; an audio codec sounds to us).</p>
<p>I highly recommend you start by reading this excerpt from <a title="EETimes: Psychoacoustics Part 1" href="http://www.eetimes.com/design/audio-design/4015872/Surround-Sound-Psychoacoustics--Part-1" target="_blank">Surround Sound: Psychoacoustics Part 1, by Tomlinson Holman</a> (he created <a title="Wikipedia: THX" href="http://en.wikipedia.org/wiki/THX" target="_blank">THX</a> for Lucasfilm).</p>
<p><strong>Understand the Codec</strong></p>
<p>Make sure you understand the codec you are testing; not necessarily the implementation, but what tools (i.e. methods) the codec uses for compression. Many codecs have different &#8220;profiles&#8221;, which describe what subset of available tools are used (e.g. <a title="MPEG-4 Part 3 Audio Preview" href="http://webstore.iec.ch/preview/info_isoiec14496-3%7Bed4.0%7Den.pdf" target="_blank">AAC</a>). You should also have some idea how each compression tool works and any short-comings it has. This will help guide you in selecting reference audio samples and knowing what artifacts to listen for.</p>
<p>For an introduction to modern audio compression, read <a title="EETimes: Audio Coding: An Introduction to Data Compression Part 1" href="http://www.eetimes.com/design/audio-design/4015827/Audio-Coding-An-Introduction-to-Data-Compression--Part-1" target="_blank">Audio Coding: An Introduction to Data Compression Part 1</a>, and <a title="EETimes: Audio Coding: An Introduction to Data Compression Part 2" href="http://www.eetimes.com/design/audio-design/4015828/Audio-Coding-An-Introduction-to-Data-Compression--Part-2" target="_blank">Part 2</a> (discusses MP3 and AAC). I actually suggest buying the book <a title="Amazon" href="http://www.amazon.com/Introduction-Compression-Kaufmann-Multimedia-Information/dp/012620862X/" target="_blank">&#8220;Introduction to Data Compression&#8221;</a>, by Khalid Sayood.</p>
<p><strong>Understand the API</strong></p>
<p>Make sure you actually read the codec documentation and look at any available code samples. This step has more to do with due-diligence than anything, as I haven&#8217;t seen a codec API we couldn&#8217;t work with, but you need to do this. This will also help you scope the work required to get a working encoder/decoder for future steps (if your lucky, the sample code can be used).</p>
<p><strong>Choose the Reference Audio Samples</strong></p>
<p>An effective test requires multiple audio samples with different characteristics. There are many types of artifacts a codec can introduce, and your choice of audio samples will dictate how easy they are to detect. It&#8217;s also important to pick samples that reflect the actual types of sound the codec to have to deal with. For example, if the final system will primarily be encoding speech, then you should choose more speech-oriented references as opposed to music samples.</p>
<p>Some characteristics you might consider:</p>
<ul>
<li><strong>Transients</strong> (snare drum): Sensitive to pre-echo and noise &#8220;smearing&#8221;.</li>
<li><strong>Tonal structure</strong> (clarinet, saxophone): Sensitive to noise and &#8220;roughness&#8221;.</li>
<li><strong>Natural speech</strong> (male and female voices of various languages): Sensitive to distortion and smearing of &#8220;attacks&#8221;.</li>
<li><strong>Complex sound</strong> (bag pipes): Stresses the codec.</li>
<li><strong>High bandwidth</strong> (bag pipes): Loss of high frequencies and program-modulated high frequency noise.</li>
</ul>
<p>It is also possible to use synthetic sounds and sweeps, but this is only recommended for the automated objective tests below.</p>
<p>As a basic guideline, you need 10-25 second &#8220;raw&#8221; samples recorded at the highest sample rate your system needs to work with. It is vital that the samples you choose have never been compressed with a lossy codec (mp3, AAC, etc)&#8230; that would severally limit the quality of your test. For sample rate and size, I suggest 48kHz 16-bit PCM, but a lower rate/size makes sense if the final system is limited in this area. It also makes sense to use a sample rate of 44.1kHz, since many quality audio samples can be ripped losslessly from CD. Just keep in mind that the objective PEAQ test mentioned below requires 48kHz 16-bit PCM, so up-sampling may be required.</p>
<p>The audio samples can be stored in whatever container format you want (raw, WAV, etc) as long as your codec test application can unpack it. This is important to keep in mind&#8230; <em>you don&#8217;t want to accidentally run the WAV header through the codec</em> (yes, I&#8217;ve done this). The container format is more of a practical issue, but it was worth mentioning.</p>
<p><strong>Generate Various Test Samples and Observe CPU Load</strong></p>
<p>This step is pretty straight-forward: wrap the codec in an application and encode the reference audio samples at different bit rates. You should choose bit rates that represent the full spectrum of bit rates that will be used in the final system. While you&#8217;re encoding, track the CPU usage on the codec and how many cores it&#8217;s using. You may even want to do a separate test running many encodes in parallel (this works nicely if the CPU usage is too low to measure accurately). Make sure to consider application overhead and disk I/O when making measurements.</p>
<p>After encoding, you need to decode back to raw PCM. Clearly label your files so you know what bit rate each one was encoded with. These decoded test samples are what we will be comparing to the original reference samples.</p>
<p><strong>Do a Subjective Test</strong></p>
<p>How you conduct your subjective testing will depend on several factors, such as time constraints, cost, and the required test precision. At the low end, you could simply listen to the test samples in a pair of headphones and judge the quality yourself. For a high precision test, you could do a full <a title="ITU BS.1116" href="http://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1116-1-199710-I!!PDF-E.pdf" target="_blank">ITU BS.1116</a> test using &#8220;expert listeners&#8221; in a controlled environment. While these examples represent the extremes, there are many permutations that can give you the desired quality of results.</p>
<p>The most common subjective test is called a &#8220;double-blind triple-stimulus with hidden reference&#8221; test. The listener hears three samples (commonly labeled A, B, and C) for a period of 10 to 25 seconds. A is always the original reference sample. The next two samples, B and C, are randomly assigned either the test sample from the codec or the original reference sample played again (called the &#8220;hidden reference&#8221;). The listener must then rate the difference between B and A, and C and A, not knowing which one is the test sample. The grading scale is:</p>
<ul>
<li>5.0 Imperceptible</li>
<li>4.0 Perceptible, but not annoying</li>
<li>3.0 Slightly annoying</li>
<li>2.0 Annoying</li>
<li>1.0 Very annoying</li>
</ul>
<p>Ideally, you would conduct several tests and average the results together. If you do the listening test yourself, your results will be limited to your listening skills and understanding of audio codec artifacts. Here&#8217;s a summary of factors that affect the quality of your results:</p>
<ul>
<li>The quality of the listener.</li>
<li>The choice of audio samples.</li>
<li>The number and duration of the testing.</li>
<li>The testing environment, including speaker/headphone quality, room design, and listener placement.</li>
<li>The quality of randomization of sample order to remove any correlation between samples.</li>
<li>Proper statistical analysis of the combined test results.</li>
</ul>
<p>A proper subjective test is both expensive and time consuming. It&#8217;s important to find the right balance for your particular needs.</p>
<p><strong>Do an Objective Test</strong></p>
<p>Evaluating a codec objectively requires testing methods that correlate well to actual human perception. You can&#8217;t simply measure the distortion introduced by the codec using traditional measurements like Signal-to-Noise ratio (S/N) and  Total-Harmonic-Distortion (THD), because they don&#8217;t correlate well to perceived audio  quality. Some distortion is imperceptible to the human ear, and codecs take advantage of this to increase the compression ratio.</p>
<p>Fortunately, the <a title="Wikipedia: International Telecommunications Union" href="http://en.wikipedia.org/wiki/International_Telecommunication_Union" target="_blank">ITU</a> has standardized an objective audio test called <a title="Wikipedia: PEAQ" href="http://en.wikipedia.org/wiki/PEAQ" target="_blank">PEAQ</a> (<a title="ITU: Perceptual Evaluation of Audio Quality" href="http://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.1387-1-200111-I!!PDF-E.pdf" target="_blank">BS.1387</a>). The acronym stands for Perceptual Evaluation of Audio Quality. PEAQ uses software to model the entire human auditory system (including blood flow noise in the inner ear) to generate a set of metrics that are used to give a final &#8220;quality&#8221; score. The original reference signal is compared to a signal run through the codec, and the result is a real number between 0.0 and -4.0. The result is interpreted on the following scale:</p>
<ul>
<li> 0.0 = Imperceptible</li>
<li>-1.0 = Perceptible but not annoying</li>
<li>-2.0 = Slightly annoying</li>
<li>-3 .0= Annoying</li>
<li>-4.0 = Very annoying</li>
</ul>
<p>Obviously, values closer to zero are better.</p>
<p>The test was developed by a similar group of audio experts that developed BS.1116 (mentioned above) and the results have been validated against a long list of subjective tests done using expert listeners.</p>
<p>There are several free and commercial software packages available for doing PEAQ tests. The best free package I&#8217;ve found is <a title="McGill: AFsp PEAQ Software" href="http://www-mmsp.ece.mcgill.ca/Documents/Software/index.html" target="_blank">AFsp</a> from the McGill Telecommunications and Signal Processing Lab. There&#8217;s also <a title="Sourceforge: peaqb" href="http://sourceforge.net/projects/peaqb/" target="_blank">peaqb</a>, but there&#8217;s a comment that it gives incorrect results. AFsp worked great in my tests and included some helpful tools like <a title="AFsp: CompAudio" href="http://www-mmsp.ece.mcgill.ca/Documents/Software/Packages/AFsp/CompAudio.html" target="_blank">CompAudio</a> and <a title="AFsp: InfoAudio" href="http://www-mmsp.ece.mcgill.ca/Documents/Software/Packages/AFsp/InfoAudio.html" target="_blank">InfoAudio</a>.</p>
<p><strong>Summary</strong></p>
<p>Hopefully this post has given you a good starting point and some practical ideas for testing audio codecs. My goal was to provide a pragmatic approach with different options depending on what your actual evaluation needs are. This is in no way a comprehensive treatment of the subject; only an overview. I highly suggest reading some of the books I referenced if you&#8217;d like a deeper treatment of the subject. Either way, I hope you found this post helpful.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2011/01/25/how-to-test-an-audio-codec-a-practical-approach/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CPU Profiling on Windows: Very Sleepy</title>
		<link>http://tdistler.com/2010/12/21/cpu-profiling-on-windows-very-sleepy</link>
		<comments>http://tdistler.com/2010/12/21/cpu-profiling-on-windows-very-sleepy#comments</comments>
		<pubDate>Tue, 21 Dec 2010 19:59:04 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=697</guid>
		<description><![CDATA[A colleague of mine found a pretty cool profiling tool for Windows called Very Sleepy. It&#8217;s simple, straight-forward, free, and it works&#8230; everything I like in a tool (this is why I like the Sysinternals stuff so much). It&#8217;s also got call-graph and 64-bit support. Definitely worth checking out.]]></description>
			<content:encoded><![CDATA[<p>A colleague of mine found a pretty cool profiling tool for Windows called <a title="Coders Notes: Very Sleepy" href="http://www.codersnotes.com/sleepy" target="_blank">Very Sleepy</a>. It&#8217;s simple, straight-forward, free, and it works&#8230; everything I like in a tool (this is why I like the <a title="Mircosoft Sysinternals" href="http://www.sysinternals.com" target="_blank">Sysinternals</a> stuff so much). It&#8217;s also got call-graph and 64-bit support. Definitely worth checking out.</p>
<p><a href="http://tdistler.com/wp-content/uploads/2011/01/very_sleepy_screenshot.jpg"><img class="aligncenter size-medium wp-image-698" title="very_sleepy_screenshot" src="http://tdistler.com/wp-content/uploads/2011/01/very_sleepy_screenshot-300x218.jpg" alt="Very Sleep Screen Shot" width="300" height="218" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/12/21/cpu-profiling-on-windows-very-sleepy/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lua Quick Reference Sheet</title>
		<link>http://tdistler.com/2010/09/27/lua-quick-reference-sheet</link>
		<comments>http://tdistler.com/2010/09/27/lua-quick-reference-sheet#comments</comments>
		<pubDate>Mon, 27 Sep 2010 19:26:15 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=485</guid>
		<description><![CDATA[Here&#8217;s a nice 4 page reference for Lua 5.1. It was created by Thomas Lauer and can be downloaded from his website. I&#8217;ve reposted it here just-in-case&#8230; I&#8217;ve been bitten before. Lua Reference Card (PDF)]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_logo1.gif"><img class="alignright size-full wp-image-489" title="lua_logo" src="http://tdistler.com/wp-content/uploads/2010/09/lua_logo1-e1285616733640.gif" alt="" width="100" height="99" /></a>Here&#8217;s a nice 4 page reference for Lua 5.1. It was created by <a title="Thomas Lauer" href="http://thomaslauer.com/" target="_blank">Thomas Lauer</a> and can be downloaded from his <a title="Lua Short Reference" href="http://thomaslauer.com/comp/Lua_Short_Reference" target="_blank">website</a>. I&#8217;ve reposted it here just-in-case&#8230; I&#8217;ve been bitten before.</p>
<p><a title="Lua Short Reference PDF" href="http://www.tdistler.com/media/docs/luarefv51.pdf">Lua Reference Card (PDF)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/09/27/lua-quick-reference-sheet/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++ Enums in Lua</title>
		<link>http://tdistler.com/2010/09/13/c-enums-in-lua</link>
		<comments>http://tdistler.com/2010/09/13/c-enums-in-lua#comments</comments>
		<pubDate>Mon, 13 Sep 2010 15:28:42 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Lua]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=460</guid>
		<description><![CDATA[I&#8217;ve been working lately on embedding Lua 5.1.4 into a C++ application. I&#8217;m really impressed with Lua, and most things are pretty straight-forward. However, when it comes to mapping typed enumerations into Lua, I just haven&#8217;t found an easy way to do it. For example, let&#8217;s say you want to expose a C++ function into [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_logo.gif"><img class="alignright size-thumbnail wp-image-462" title="lua_logo" src="http://tdistler.com/wp-content/uploads/2010/09/lua_logo-150x150.gif" alt="Lua" width="150" height="150" /></a>I&#8217;ve been working lately on embedding <a title="Lua Programming Language" href="http://www.lua.org/" target="_blank">Lua 5.1.4</a> into a C++ application. I&#8217;m really impressed with Lua, and most things are pretty straight-forward. However, when it comes to mapping typed enumerations into Lua, I just haven&#8217;t found an easy way to do it. For example, let&#8217;s say you want to expose a C++ function into Lua called <code>create()</code>, which takes an enumerated type as a parameter. In C++ this would look like:</p>
<pre><code>typedef enum _TYPE {
    TYPE_FOO = 0,
    TYPE_BAR,
    TYPE_BAZ,
    TYPE_MAX
} TYPE;

bool create(const TYPE type);</code></pre>
<p>To me, it makes the most sense to call <code>create()</code> from Lua with syntax like:</p>
<p><code>&gt; create(type.foo)</code></p>
<p>Ideally, we&#8217;d also like the following:</p>
<ol>
<li>The enumeration is const, and can&#8217;t be altered from Lua code.</li>
<li>The C++ implementation of <code>create()</code> could validate the type passed to it is the expected type.</li>
</ol>
<p>Unfortunately, this isn&#8217;t as straight-forward as everything else I&#8217;ve done with Lua.</p>
<h4>Solution (i.e. cut-to-the-chase and explain later)</h4>
<p>Okay, I&#8217;m a practical guy&#8230; download <strong><a title="lua_typed_enums.h Header File" href="/media/code/lua_typed_enums.h">lua_typed_enums.h</a></strong> and include it in your code. Then you can add the enums shown above to Lua by calling <code>add_enum_to_lua()</code>:</p>
<pre><code>add_enum_to_lua( L, "type",
    "foo", TYPE_FOO,
    "bar", TYPE_BAR,
    "baz", TYPE_BAZ,
    0 );</code></pre>
<p>Your enums are now available in Lua as:</p>
<p><code>type.foo<br />
type.bar<br />
type.baz</code></p>
<p>Now, your C++ code that takes TYPE as an input and returns a boolean would be written as follows:</p>
<pre><code>static int lua_create( lua_State *L )
{
    if( !check_enum_type( L, "type", -1 ) ) {
        /* error */
    }

    int value = get_enum_value( L, -1 );

    /* do something cool */

    lua_pushboolean( L, 1 );
    return (1);
}</code></pre>
<p>You can now call your <code>create()</code> method from Lua how we wanted:</p>
<p><code>&gt; create(type.bar)</code></p>
<p>Look at the comments in the header file if you want more info about using <code>add_enum_to_lua()</code>, <code>check_enum_type()</code>, and <code>get_enum_value()</code>.</p>
<h4>How it Works</h4>
<p>There&#8217;s no direct way to map the expected behavior of C-enums into Lua (const-ness with typing). What I did was to create a read-only Lua table representing the enumerated type and then make each value in that table have a defined type.</p>
<p>Let&#8217;s deal with the first task: making a read-only table. This is pretty well documented on the web, but I&#8217;ve included a drawing below that would have helped me a lot in the beginning. Let&#8217;s assume we want to represent our enum as a Lua table. We could visualize it as follows:</p>
<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_unprotected.jpg"><img class="aligncenter size-full wp-image-472" title="lua_rotables_unprotected" src="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_unprotected.jpg" alt="" width="169" height="97" /></a></p>
<p>We could still use the <code>type.foo</code> syntax with this table, but a user could assign a new value to the enum like:</p>
<p><code>&gt; type.foo = 9</code></p>
<p>To prevent this, we need to deny write access to the table. The trick to doing this is to use a metatable and set the <code>__index</code> and <code>__newindex</code> values.</p>
<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_untyped.jpg"><img class="aligncenter size-full wp-image-473" title="lua_rotables_untyped" src="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_untyped.jpg" alt="" width="361" height="145" /></a></p>
<p>So how does this work? When the user reads a value from the table (i.e. by using <code>type.foo</code>), Lua fails to find &#8220;foo&#8221; in the table. So it looks in the metatable for the <code>__index</code> key. If that is set to point to a table, then it will try to lookup the value in that table. In the case above, it finds the &#8220;foo&#8221; value and returns it like normal. However, if the user attempts to assign to type.foo, Lua follows the <code>__newindex</code> path, which causes a function to get called that does nothing but print an error&#8230; effectively, the write is denied. Here&#8217;s what happens:</p>
<p><code>&gt; type.foo = 9<br />
[string "?"]:1: Attempt to modify read-only table</code></p>
<p>Okay, cool&#8230; we&#8217;ve made read-only enumerations, but what about typing. Glad you asked! We add one more layer of abstraction, of course &lt;groaning&gt;:</p>
<p><a href="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_typed1.jpg"><img class="aligncenter size-full wp-image-475" title="lua_rotables_typed" src="http://tdistler.com/wp-content/uploads/2010/09/lua_rotables_typed1.jpg" alt="" width="553" height="181" /></a></p>
<p>Basically, we make each value a table that includes the <em>actual</em> value and a type (&#8220;type&#8221; in our example above). The <code>check_enum_type()</code> function looks at the &#8220;type&#8221; field in the table to make sure the correct type was passed to your function. The <code>get_enum_value()</code> function gets the &#8220;value&#8221; field&#8230; which is equal to the actual C-enum type you&#8217;d expect. From the Lua side, you can inspect the enums like:</p>
<p><code>&gt; print(type.foo.value)<br />
0<br />
&gt; print(type.foo.type)<br />
type</code></p>
<p>Explicitly, &#8220;type&#8221; is a read-only table with value &#8220;foo&#8221;. The value of &#8220;foo&#8221; is the table <code>{ value=0, type="type" }</code>. I hope this explanation helps. Obviously, I&#8217;ve been geeking out on Lua a little too much lately <img src='http://tdistler.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/09/13/c-enums-in-lua/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux: Parsing IP Address, MAC, and Gateway</title>
		<link>http://tdistler.com/2010/08/17/linux-parsing-ip-address-mac-and-gateway</link>
		<comments>http://tdistler.com/2010/08/17/linux-parsing-ip-address-mac-and-gateway#comments</comments>
		<pubDate>Tue, 17 Aug 2010 18:28:33 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=453</guid>
		<description><![CDATA[Yesterday, I needed to get my server&#8217;s network information for a Bash script I was writing. Here are the commands so I don&#8217;t forget. They were tested using Fedora 12. Get IP address: ifconfig eth0 &#124; awk '/inet / {print $2}' &#124; awk -F: '{print $2}&#8216; Get MAC address: ifconfig eth0 &#124; awk '/HWaddr/ {print [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/08/bash_cmd_prompt.jpg"><img class="alignright size-full wp-image-455" title="bash_cmd_prompt" src="http://tdistler.com/wp-content/uploads/2010/08/bash_cmd_prompt.jpg" alt="" width="102" height="102" /></a>Yesterday, I needed to get my server&#8217;s network information for a Bash script I was writing. Here are the commands so I don&#8217;t forget. They were tested using <a title="Fedora Linux" href="http://fedoraproject.org/" target="_blank">Fedora</a> 12.</p>
<p>Get IP address:<br />
<code>ifconfig eth0 | awk '/inet / {print $2}' | awk -F: '{print $2}</code>&#8216;</p>
<p>Get MAC address:<br />
<code>ifconfig eth0 | awk '/HWaddr/ {print $5}'</code></p>
<p>Get network gateway IP address:<br />
<code>route -n | awk '/^0.0.0.0/ {print $2}'</code></p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/08/17/linux-parsing-ip-address-mac-and-gateway/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Video Tearing, V-Sync, and Triple-Buffering</title>
		<link>http://tdistler.com/2010/07/18/video-tearing-v-sync-and-triple-buffering</link>
		<comments>http://tdistler.com/2010/07/18/video-tearing-v-sync-and-triple-buffering#comments</comments>
		<pubDate>Sun, 18 Jul 2010 20:45:26 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[video]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=416</guid>
		<description><![CDATA[When rendering graphics or video to the screen, it&#8217;s important to understand the display process; in particular, vertical sync (v-sync). A common problem when starting out is an issue called &#8220;tearing&#8221;&#8230; where the video appears to be torn horizontally down the middle (see picture). I&#8217;ve been looking for a good explanation to share about why [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tdistler.com/wp-content/uploads/2010/07/v_sync.jpg"><img class="alignright size-full wp-image-419" title="v_sync" src="http://tdistler.com/wp-content/uploads/2010/07/v_sync.jpg" alt="" width="150" height="113" /></a>When rendering graphics or video to the screen, it&#8217;s important to understand the display process; in particular, vertical sync (v-sync). A common problem when starting out is an issue called &#8220;tearing&#8221;&#8230; where the video appears to be torn horizontally down the middle (see picture). I&#8217;ve been looking for a good explanation to share about why video tearing occurs and how to solve it (from a technical perspective). I found the following thread over at <a title="Hard Forum" href="http://hardforum.com" target="_blank">[H]ard|Forum</a>, which I think does a pretty good job.</p>
<p>For the thread &#8220;<a title="How VSync works, and why people loathe it" href="http://hardforum.com/showthread.php?s=9eb741eaa733ffb028c860e9805c04f5&amp;t=928593" target="_blank">How </a><a title="How VSync works, and why people loathe it" href="http://hardforum.com/showthread.php?s=9eb741eaa733ffb028c860e9805c04f5&amp;t=928593" target="_blank">VSync</a><a title="How VSync works, and why people loathe it" href="http://hardforum.com/showthread.php?s=9eb741eaa733ffb028c860e9805c04f5&amp;t=928593" target="_blank"> works, and why people loathe it</a>&#8220;:</p>
<blockquote><p>There is a technique called triple-buffering that solves this VSync problem. Lets go back to our 50FPS, 75Hz example. Frame 1 is in the frame buffer, and 2/3 of frame 2 are drawn in the back buffer. The refresh happens and frame 1 is grabbed for the first time. The last third of frame 2 are drawn in the back buffer, and the first third of frame 3 is drawn in the second back buffer (hence the term triple-buffering). The refresh happens, frame 1 is grabbed for the second time, and frame 2 is copied into the frame buffer and the first part of frame 3 into the back buffer. The last 2/3 of frame 3 are drawn in the back buffer, the refresh happens, frame 2 is grabbed for the first time, and frame 3 is copied to the frame buffer. The process starts over. This time we still got 2 frames, but in only 3 refresh cycles. That&#8217;s 2/3 of the refresh rate, which is 50FPS, exactly what we would have gotten without it. Triple-buffering essentially gives the video card someplace to keep doing work while it waits to transfer the back buffer to the frame buffer, so it doesn&#8217;t have to waste time. Unfortunately, triple-buffering isn&#8217;t available in every game, and in fact it isn&#8217;t too common. It also can cost a little performance to utilize, as it requires extra VRAM for the buffers, and time spent copying all of them around. However, triplebuffered VSync really is the key to the best experience as you eliminate tearing without the downsides of normal VSync (unless you consider the fact that your FPS is capped a downside&#8230; which is silly because you can&#8217;t see an FPS higher than your refresh anyway).</p></blockquote>
<p>If the thread is ever unavailable, you can download a PDF version <a title="PDF: How VSync works, and why people loathe it" href="http://tdistler.com/wp-content/uploads/2010/07/How-VSync-works-and-why-people-loathe-it.pdf" target="_blank">HERE</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2010/07/18/video-tearing-v-sync-and-triple-buffering/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sed Regular Expression: Find Lines Not Matching A String</title>
		<link>http://tdistler.com/2009/04/17/sed-regular-expression-find-lines-not-matching-a-string</link>
		<comments>http://tdistler.com/2009/04/17/sed-regular-expression-find-lines-not-matching-a-string#comments</comments>
		<pubDate>Fri, 17 Apr 2009 23:39:49 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=218</guid>
		<description><![CDATA[After some digging, I finally found out how to create a regex for Sed (stream editor) that will find a line that does NOT contain a particular string. First, I used &#8216;find&#8217; to list all the *.cpp files in my source tree: find . -name &#8220;*.cpp&#8221; -print Then I piped the files to &#8216;sed&#8217; via [...]]]></description>
			<content:encoded><![CDATA[<p>After some digging, I finally found out how to create a regex for Sed (stream editor) that will find a line that does NOT contain a particular string. First, I used &#8216;find&#8217; to list all the *.cpp files in my source tree:</p>
<p class="codeblock">find . -name &#8220;*.cpp&#8221; -print</p>
<p>Then I piped the files to &#8216;sed&#8217; via &#8216;xargs&#8217; (Note: replace the &#8216;-e&#8217; with &#8216;-i&#8217; to actually modify the files inline):</p>
<p class="codeblock">find . -name &#8220;*.cpp&#8221; -print | xargs sed -e &#8216;/STRING_TO_INGORE/! { d }&#8217;</p>
<p>The trick is adding the &#8216;!&#8217; (exclamation point) after the search expression. Without it, &#8216;sed&#8217; would think you only want lines <em>with</em> the string, not <em>without</em> it.</p>
<p>This is different than another syntax I&#8217;ve seen used: /(?!STRING_TO_IGNORE)/.</p>
<p>Here&#8217;s another example. Say you want to replace STRING1 with STRING2 only if the first characters of the line (ignoring white space)  are NOT &#8220;//&#8221;&#8230; i.e. skip the string replacement in code comments:</p>
<p class="codeblock">sed -i &#8216;/^[ \t]*\/\/.*/! { s/STRING1/STRING2/ }&#8217;</p>
<p>NOTE: &#8216;[ \t]*&#8217; means ignore 0 or more spaces or tabs.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2009/04/17/sed-regular-expression-find-lines-not-matching-a-string/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Find &amp; Replace in Files on Linux</title>
		<link>http://tdistler.com/2009/04/13/find-replace-in-files-on-linux</link>
		<comments>http://tdistler.com/2009/04/13/find-replace-in-files-on-linux#comments</comments>
		<pubDate>Mon, 13 Apr 2009 19:28:59 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=200</guid>
		<description><![CDATA[A lot of solutions I&#8217;ve found for recursively replacing text in files is implemented using shell scripts, perl, php, or some other inconvenient way. Rushi got it right by using the Linux command line. Here it is (slightly modified) from his blog: find . -name &#8220;*.cpp&#8221; -print &#124; xargs sed -i &#8216;s/[find]/[replace]/g&#8217; where &#8220;[find]&#8221; and [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" style="float: right;" src="/media/images/tux.jpg" alt="Tux" />A lot of solutions I&#8217;ve found for recursively replacing text in files is implemented using shell scripts, perl, php, or some other inconvenient way. <a href="http://rushi.vishavadia.com/blog/2008/08/05/find-replace-across-multiple-files-in-linux/" target="_blank">Rushi</a> got it right by using the Linux command line. Here it is (slightly modified) from his blog:</p>
<p class="codeblock">find . -name &#8220;*.cpp&#8221;  -print | xargs sed -i &#8216;s/[find]/[replace]/g&#8217;</p>
<p>where &#8220;[find]&#8221; and &#8220;[replace]&#8221; are the things you are searching for and substituting.</p>
<p>To search files with multiple file extensions, use:</p>
<p class="codeblock">find . -name &#8220;*.cpp&#8221;  -o -name &#8220;*.h&#8221; -o -name &#8220;*.c&#8221; | xargs sed -i &#8216;s/[find]/[replace]/g&#8217;</p>
<p><b>ADDED 4-13-2009:</b> See comments for other variations.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2009/04/13/find-replace-in-files-on-linux/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How To Get An Error Message Describing Why A Library Failed To Load</title>
		<link>http://tdistler.com/2009/04/08/how-to-get-an-error-message-describing-why-a-library-failed-to-load</link>
		<comments>http://tdistler.com/2009/04/08/how-to-get-an-error-message-describing-why-a-library-failed-to-load#comments</comments>
		<pubDate>Wed, 08 Apr 2009 18:01:11 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=163</guid>
		<description><![CDATA[The title&#8217;s kind of a misnomer. This post is really to help me remember how to get a human-readable string from a Windows error code&#8230; I&#8217;m finally tired of always having to look it up . However, my current situation revolves around determining why a DLL (or *.so on Linux) failed to load, so that&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>The title&#8217;s kind of a misnomer. This post is really to help me remember how to get a human-readable string from a Windows error code&#8230; I&#8217;m finally tired of always having to look it up <img src='http://tdistler.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  . However, my current situation revolves around determining why a DLL (or *.so on Linux) failed to load, so that&#8217;s why this post it titled the way it is.</p>
<p>I like to disable the annoying default dialog that pops up in Windows when a library fails to load.</p>
<p><code>SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOOPENFILEERRORBOX);</code></p>
<p>Now, here&#8217;s the code to get a user friendly text string:</p>
<pre><code>#ifdef WIN32
    LPVOID pStr = 0;
    DWORD_PTR args[1] = { (DWORD_PTR)pFilename };
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_ARGUMENT_ARRAY,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&#038;pStr,
        0,
        (va_list*)args);

    /* Do something with the string pStr here */

    LocalFree(pStr);
#else
    /* Call dlerror() and do something with the string */
#endif</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2009/04/08/how-to-get-an-error-message-describing-why-a-library-failed-to-load/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C/C++: Using Bitfields Effectively</title>
		<link>http://tdistler.com/2008/07/21/cc-using-bitfields-effectively</link>
		<comments>http://tdistler.com/2008/07/21/cc-using-bitfields-effectively#comments</comments>
		<pubDate>Mon, 21 Jul 2008 15:00:29 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Code Monkey]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=120</guid>
		<description><![CDATA[Introduction If you&#8217;ve ever done embedded development in C/C++, you are probably familiar with bitfields. They are a handy way to reference individual bits in things like hardware registers. The problem is that bitfields can lead to performance problems and race conditions if not used properly. I hope to highlight some of the issues you [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p>If you&#8217;ve ever done embedded development in C/C++, you are probably familiar with bitfields. They are a handy way to reference individual bits in things like hardware registers. The problem is that bitfields can lead to performance problems and race conditions if not used properly. I hope to highlight some of the issues you should consider when using them.</p>
<p><strong>Usage</strong></p>
<p>First, let&#8217;s assume you need to check various fields in a hardware register with the following layout:</p>
<p style="text-align: center;"><img src="/media/images/BitfieldRegisterEx1.jpg" alt="Bitfield Register Example" width="431" height="52" /></p>
<p>You could define the following bitfield to represent this register:</p>
<p class="codeblock">1: struct HwReg<br />
2: {<br />
3: &nbsp;&nbsp;&nbsp;unsigned int Base : 16;<br />
4: &nbsp;&nbsp;&nbsp;unsigned int Offset : 8;<br />
5: &nbsp;&nbsp;&nbsp;unsigned int Rsvd : 5;<br />
6: &nbsp;&nbsp;&nbsp;unsigned int Flag : 1;<br />
7: &nbsp;&nbsp;&nbsp;unsigned int Type : 2;<br />
8: };</p>
<p>The total size of this data type is sizeof(unsigned int), with each line defining a different region (field) within that type (this looks confusing when you first look at it). The following code uses the HwReg bitfield to access a memory-mapped register:</p>
<p class="codeblock">1: struct HwReg* pReg = (struct HwReg*)0&#215;80001005;<br />
2:<br />
3: if (pReg-&gt;Flag &amp;&amp; pReg-&gt;Type == TYPE_1)<br />
4: {<br />
5: &nbsp;&nbsp;&nbsp;void* address = pReg-&gt;Base + pReg-&gt;Offset;<br />
6: }</p>
<p>Line 1 defines a pointer to the physical hardware register as type HwReg. We can now use this pointer to easily access the register fields. If this isn&#8217;t clear, you can read more about bitfields <a title="Wikipedia: Bit Field" href="http://en.wikipedia.org/wiki/Bit_field" target="_blank">HERE</a>.</p>
<p><strong>Performance Problems</strong></p>
<p>The compiler doesn&#8217;t know how to optimize bitfield accesses (especially because the pointers to memory-mapped hardware registers are almost always declared &#8216;volatile&#8217;). This means that every access to a member of the bitfield will require a read of the physical hardware register. This can be orders of magnitude slower than accessing main memory. In the code example above, the hardware register will be read 4 times; once for each field access.</p>
<p>The way to remedy this is to cache a copy of the register value and then operate on that. Consider the following code:</p>
<p class="codeblock">1: unsigned int* pFullReg = (unsigned int*)0&#215;80001005;<br />
2: unsigned int temp = *pFullReg;<br />
3: struct HwReg* pReg = (struct HwReg*)&amp;temp;<br />
4:<br />
5: if (pReg-&gt;Flag &amp;&amp; pReg-&gt;Type == TYPE_1)<br />
6: {<br />
7: &nbsp;&nbsp;&nbsp;void* address = pReg-&gt;Base + pReg-&gt;Offset;<br />
8: }</p>
<p>Line 1 defines a pointer to the physical hardware register. Line 2 performs the actual read into a local variable (the slowest part). This local copy is now in main memory and the CPU cache. Line 3 casts the cached value to the bitfield for easy access. Finally, all accesses to the register fields is on the cached value, which can be read very fast from L1 cache.</p>
<p>Another advantage to this approach is when the hardware requires locking before the register can be accessed. By caching the value, you can keep all the locking code localized to a single area of the function. Without caching, you would hold the lock for a longer period of time (possibly forcing other operations to block) and have to make sure to release the lock on every return path (more difficult with exceptions).</p>
<p>NOTE: Remember you are only working with a <em>copy</em> of the register value. If you update a value in the bitfield, you must still copy the updated value back to the register.</p>
<p><strong>Race Conditions</strong></p>
<p>As stated above, each access to a field value generates its own read/write operation. Even if the CPU architecture guarantees that an individual operation is atomic, updating multiple fields are not. Thus, in a multi-threaded application you must lock the entire block of code that operates on the bitfield. I again suggest caching the value, as you only need to lock the actual read/write of the entire register.</p>
<p><strong>Conclusion</strong></p>
<p>Bitfields are a nice language construct that can help make it easier to write clean code (as opposed to using macros and bitmasks). Unfortunately, it&#8217;s all too easy to shoot-yourself-in-the-foot with bitfields if you don&#8217;t understand the pitfalls. As always, use caution when writing performance-critical code and make sure you understand how to use the available code constructs.</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2008/07/21/cc-using-bitfields-effectively/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Avoiding Development Disasters</title>
		<link>http://tdistler.com/2007/10/17/avoiding-development-disasters</link>
		<comments>http://tdistler.com/2007/10/17/avoiding-development-disasters#comments</comments>
		<pubDate>Wed, 17 Oct 2007 14:50:42 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Tech and Security]]></category>
		<category><![CDATA[development]]></category>

		<guid isPermaLink="false">http://tdistler.com/?p=32</guid>
		<description><![CDATA[I always enjoy reading Alex Papadimoulis&#8217; blog Worst Than Failure (WTF). It recounts stories of software errors, ridiculous coding solutions, and tales of failed engineering interviews. It&#8217;s a great place to learn from other people&#8217;s mistakes, and have a few laughs along the way. Occasionally, Alex posts a more serious article about the process of [...]]]></description>
			<content:encoded><![CDATA[<p align="center"><img title="Worst Than Failure" src="/media/images/WTF-logo.gif" alt="Worst Than Failure" /></p>
<p>I always enjoy reading Alex Papadimoulis&#8217; blog <a title="Worst Than Failure" href="http://worsethanfailure.com/" target="_blank">Worst Than Failure (WTF)</a>. It recounts stories of software errors, ridiculous coding solutions, and tales of failed engineering interviews. It&#8217;s a great place to learn from other people&#8217;s mistakes, and have a few laughs along the way.</p>
<p>Occasionally, Alex posts a more serious article about the process of software engineering. I enjoyed his latest on <a title="WTF - Avoiding Development Disasters" href="http://worsethanfailure.com/Articles/Avoiding-Development-Disasters.aspx" target="_blank">Avoiding Development Disasters</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tdistler.com/2007/10/17/avoiding-development-disasters/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

