<?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>Alex on Linux&#187; Blog</title>
	<atom:link href="http://www.alexonlinux.com/category/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://www.alexonlinux.com</link>
	<description></description>
	<lastBuildDate>Sun, 25 Jul 2010 10:00:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Call a constructor or allocate an object in-place</title>
		<link>http://www.alexonlinux.com/call-a-constructor-or-allocate-an-object-in-place-2</link>
		<comments>http://www.alexonlinux.com/call-a-constructor-or-allocate-an-object-in-place-2#comments</comments>
		<pubDate>Sun, 04 Jul 2010 20:40:10 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Howto]]></category>
		<category><![CDATA[Programming Articles]]></category>
		<category><![CDATA[Short articles]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[memory management]]></category>
		<category><![CDATA[new]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1803</guid>
		<description><![CDATA[Since I joined Dell, my main field of research and work has somewhat changed. Now I am mostly working with C++ and file-systems. This world is not entirely new to me, but apparently I have a lot of stuff to learn. Today I&#8217;d like to talk about one nice trick that I learned few days [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/direct-io-in-python' rel='bookmark' title='Permanent Link: Direct IO in Python'>Direct IO in Python</a></li>
<li><a href='http://www.alexonlinux.com/one-sane-voice-in-the-crowd' rel='bookmark' title='Permanent Link: One sane voice in the crowd'>One sane voice in the crowd</a></li>
<li><a href='http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to' rel='bookmark' title='Permanent Link: Recursively deleting symbolic link and what it points to'>Recursively deleting symbolic link and what it points to</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Since I joined Dell, my main field of research and work has somewhat changed. Now I am mostly working with C++ and file-systems. This world is not entirely new to me, but apparently I have a lot of stuff to learn.</p>
<p>Today I&#8217;d like to talk about one nice trick that I learned few days ago.</p>
<p>When working with large software systems, memory management becomes an imperative. In C, you can easily allocate a large chunk of memory and allocate structure right on that buffer. This is by far more difficult in C++, because compiler has to call consturctor.</p>
<p>Apparently, you can, in a way, directly call object&#8217;s constructor . I.e. you can allocate an object, on specified memory region, without actually allocating this region.</p>
<p>This is how you do it.</p>
<pre class="brush:cpp">char* s = new char[1024];

SomeClass* p = new (s) SomeClass;
</pre>
<p>First new operator just allocates 1024 bytes. This is good old allocation as we know it. Note the special syntax of the second new operator. It allocates the new object on memory specified in brackets. Basically, this calls SomeClass&#8217;s constructor using s as storage.</p>
<p><em>One thing that I don&#8217;t know how to do is how to call destructor on the object &#8211; i.e. how to delete an object in place.</em></p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/direct-io-in-python' rel='bookmark' title='Permanent Link: Direct IO in Python'>Direct IO in Python</a></li>
<li><a href='http://www.alexonlinux.com/one-sane-voice-in-the-crowd' rel='bookmark' title='Permanent Link: One sane voice in the crowd'>One sane voice in the crowd</a></li>
<li><a href='http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to' rel='bookmark' title='Permanent Link: Recursively deleting symbolic link and what it points to'>Recursively deleting symbolic link and what it points to</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/call-a-constructor-or-allocate-an-object-in-place-2/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>This is me, couple of weeks ago.</title>
		<link>http://www.alexonlinux.com/this-is-me-couple-of-weeks-ago</link>
		<comments>http://www.alexonlinux.com/this-is-me-couple-of-weeks-ago#comments</comments>
		<pubDate>Tue, 11 May 2010 16:25:29 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1792</guid>
		<description><![CDATA[I think this is going to become my new icon. What do you think? No related posts.


No related posts.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.alexonlinux.com/wp-content/uploads/2010/05/me.jpg" onclick="return TrackClick('http%3A%2F%2Fwww.alexonlinux.com%2Fwp-content%2Fuploads%2F2010%2F05%2Fme.jpg','me')"><img class="aligncenter size-full wp-image-1791" title="me" src="http://www.alexonlinux.com/wp-content/uploads/2010/05/me.jpg" onclick="return TrackClick('http%3A%2F%2Fwww.alexonlinux.com%2Fwp-content%2Fuploads%2F2010%2F05%2Fme.jpg','me')" alt="" width="598" height="398" /></a></p>
<p>I think this is going to become my new icon. What do you think?</p>


<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/this-is-me-couple-of-weeks-ago/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How less processes its input</title>
		<link>http://www.alexonlinux.com/how-less-processes-its-input</link>
		<comments>http://www.alexonlinux.com/how-less-processes-its-input#comments</comments>
		<pubDate>Wed, 28 Apr 2010 13:37:37 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Programming Articles]]></category>
		<category><![CDATA[Short articles]]></category>
		<category><![CDATA[curses]]></category>
		<category><![CDATA[error stream]]></category>
		<category><![CDATA[file descriptor]]></category>
		<category><![CDATA[input]]></category>
		<category><![CDATA[input stream]]></category>
		<category><![CDATA[less]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[more]]></category>
		<category><![CDATA[output stream]]></category>
		<category><![CDATA[tty]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1783</guid>
		<description><![CDATA[Here&#8217;s an interesting bit I ran into few days ago. I got curious how is that less (or more) can read file contents from standard input and yet it is able to process input that comes from user. Both of them come from standard input, yet these are quiet heterogeneous streams of information. So, how [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/creating-new-application-on-top-of-ssh' rel='bookmark' title='Permanent Link: Creating new application on top of SSH'>Creating new application on top of SSH</a></li>
<li><a href='http://www.alexonlinux.com/sed-the-missing-manual' rel='bookmark' title='Permanent Link: sed &#8211; the missing manual'>sed &#8211; the missing manual</a></li>
<li><a href='http://www.alexonlinux.com/direct-io-in-python' rel='bookmark' title='Permanent Link: Direct IO in Python'>Direct IO in Python</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s an interesting bit I ran into few days ago. I got curious how is that <em>less</em> (or <em>more</em>) can read file contents from standard input and yet it is able to process input that comes from user. Both of them come from standard input, yet these are quiet heterogeneous streams of information. So, how can it be?</p>
<p><span id="more-1783"></span>At first, I thought <em>less</em> reads entire input first. This would make standard input stream free to process key presses from the user. So I decided to check this out. I created a 1Gb long text file and ran <em>less</em> on it. I expected <em>less</em> to take some time to show file contents, but it showed first lines of the file instantly. Also, it didn&#8217;t consume 1Gb of RAM as I expected.</p>
<p>The conclusion is obvious. <em>less</em> does not read entire input buffer before letting user to interact with itself. Then how?</p>
<p>Here&#8217;s what <em>less</em> does. It separates input file stream from user input stream. Both inputs initially come via standard input stream, so <em>less</em> separates between them. First it duplicates the standard input stream. This allocates a new file descriptor. Then it closes old file descriptor, freeing file descriptor 0 for use. Then it opens /dev/tty. When opening a file, Linux uses next available file descriptor. File descriptor used as standard input is 0, so when <em>less</em> opens /dev/tty again, file descriptor of the newly opened file has value 0.</p>
<p>Eventually, it ends up with the new input coming via standard input stream file descriptor (0), and old input still available via file descriptor that it duplicated in the beginning. It reads the input file from the duplicated file descriptor, and uses curses on standard input stream.</p>
<p>You may be wondering what is /dev/tty and what it has to do with standard input streams. This is really fascinating stuff.</p>
<p>As you know, in Linux, everything is a file. So is terminal. Linux uses device files to represent various system devices. /dev/tty is a file that represents terminal of the current process. When process reads from /dev/tty it becomes its input. When program writes to /dev/tty it becomes its standard output or standard error stream.</p>
<p>So, when <em>less </em>reopens /dev/tty, it actually recreates standard input. Older descriptor, one that has been duplicated, can no longer accept new input, but <em>less</em> still can use it to read what it has been written into it already.</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/creating-new-application-on-top-of-ssh' rel='bookmark' title='Permanent Link: Creating new application on top of SSH'>Creating new application on top of SSH</a></li>
<li><a href='http://www.alexonlinux.com/sed-the-missing-manual' rel='bookmark' title='Permanent Link: sed &#8211; the missing manual'>sed &#8211; the missing manual</a></li>
<li><a href='http://www.alexonlinux.com/direct-io-in-python' rel='bookmark' title='Permanent Link: Direct IO in Python'>Direct IO in Python</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/how-less-processes-its-input/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I got a new job, take 3</title>
		<link>http://www.alexonlinux.com/i-got-a-new-job-take-3</link>
		<comments>http://www.alexonlinux.com/i-got-a-new-job-take-3#comments</comments>
		<pubDate>Tue, 02 Mar 2010 11:51:36 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1740</guid>
		<description><![CDATA[I got a new job, again. Dell decided to obtain what have left of Exanet LTD, a company I worked for in the past. They kindly decided to offer a job to majority of ex-Exanet engineers, me included. So, I decided to leave Fabrix and as of last week I am software engineer and senior [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/resume' rel='bookmark' title='Permanent Link: Resume'>Resume</a></li>
<li><a href='http://www.alexonlinux.com/i-am-looking-for-a-new-job' rel='bookmark' title='Permanent Link: I am looking for a new job'>I am looking for a new job</a></li>
<li><a href='http://www.alexonlinux.com/what-it-takes-to-be-a-qa-engineer' rel='bookmark' title='Permanent Link: What it takes to be a QA engineer'>What it takes to be a QA engineer</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I got a new job, again. Dell decided to obtain what have left of Exanet LTD, <a href="i-got-a-new-job" rel="nofollow" >a company I worked for in the past</a>. They kindly decided to offer a job to majority of ex-Exanet engineers, me included.</p>
<p>So, I decided to leave Fabrix and as of last week I am software engineer and senior consultant at Dell IDC (Israel Developer Center).</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/resume' rel='bookmark' title='Permanent Link: Resume'>Resume</a></li>
<li><a href='http://www.alexonlinux.com/i-am-looking-for-a-new-job' rel='bookmark' title='Permanent Link: I am looking for a new job'>I am looking for a new job</a></li>
<li><a href='http://www.alexonlinux.com/what-it-takes-to-be-a-qa-engineer' rel='bookmark' title='Permanent Link: What it takes to be a QA engineer'>What it takes to be a QA engineer</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/i-got-a-new-job-take-3/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>What&#8217;s is direct I/O anyway?</title>
		<link>http://www.alexonlinux.com/whats-is-direct-io-anyway</link>
		<comments>http://www.alexonlinux.com/whats-is-direct-io-anyway#comments</comments>
		<pubDate>Mon, 15 Feb 2010 10:03:57 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[direct]]></category>
		<category><![CDATA[direct I/O]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[page cache]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1713</guid>
		<description><![CDATA[Few days ago I&#8217;ve written a post explaining how to do a direct I/O in Python. But then I thought that it might be a good idea to explain what direct I/O is. So, here we go. As surprising as it is, when you write some information to the disk, it doesn&#8217;t get there immediately. [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/swap-vs-no-swap' rel='bookmark' title='Permanent Link: Swap vs. no swap'>Swap vs. no swap</a></li>
<li><a href='http://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux' rel='bookmark' title='Permanent Link: SMP affinity and proper interrupt handling in Linux'>SMP affinity and proper interrupt handling in Linux</a></li>
<li><a href='http://www.alexonlinux.com/aligned-vs-unaligned-memory-access' rel='bookmark' title='Permanent Link: Aligned vs. unaligned memory access'>Aligned vs. unaligned memory access</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Few days ago I&#8217;ve written <a href="http://www.alexonlinux.com/direct-io-in-python" onclick="return TrackClick('http%3A%2F%2Fwww.alexonlinux.com%2Fdirect-io-in-python','a+post+explaining+how+to+do+a+direct+I%2FO+in+Python')">a post explaining how to do a direct I/O in Python</a>. But then I thought that it might be a good idea to explain what direct I/O is. So, here we go.</p>
<p>As surprising as it is, when you write some information to the disk, it doesn&#8217;t get there immediately. In Linux especially, the kernel tries to cache write requests in memory as much as it can. This means that in addition to writing the data to the disk, kernel keeps it in memory. Consecutive read request to the same place on the disk will be much faster because there&#8217;s no need to read the information from slow disk &#8211; it is already in memory. On the other hand, the information goes to the hard-disk only after some period of time (short though) or when the system runs out of memory. In the meantime, Linux reports that data has been written, despite it is not yet on the disk.<span id="more-1713"></span></p>
<p>This causes several interesting phenomena that you may have noticed. For example Linux machines with little memory, even though not all memory is in use, do use disk much more than machines with more memory. There are several reasons for it. One of them is because kernel doesn&#8217;t have enough memory to cache information from the disks and as a result read requests rarely hit the cache and more often go to the disk.</p>
<blockquote><p>Want to see exactly how Linux reports successful write requests before data actually lands on the disk? Try writing some information to floppy disk and see how fast it is in Linux. The truth is that it&#8217;s still frustratingly slow. Linux just makes it look like a fast device.</p></blockquote>
<p>Sheer thought that Linux doesn&#8217;t write the data to the disk, despite it says it did, may be pretty scary. But it shouldn&#8217;t really. First of all, if its not very busy it does write the data to the disk as soon as possible. Second, Linux does excellent job avoiding various problems and even if something bad happens, it is pretty good at recovering lost data. The way Linux works is excellent for 99% of users. This approach improves performance in various ways and makes the system more healthy and stable.</p>
<p>However, some folks out there are not happy with this situation. Some software systems cannot work the way Linux works. One of the examples are so called clustered file-systems &#8211; file-systems that are spread among multiple servers for redundancy purposes. Such systems need a way to know that data has been written to the disk for real, not just being cached. Also, such systems want to make sure that reads hit disk and not OS cache.</p>
<p>This is where direct I/O becomes handy. Direct I/O is a way to avoid entire caching layer in the kernel and send the I/O directly to the disk. Overall, this makes I/O slower and does not let Linux do various optimizations that it usually does. Also, it introduces some constraints on memory buffer that being used for the I/O. Yet sometimes it is inevitable.</p>
<p>Want to try it yourself? <em>dd</em>, I/O Swiss army knife, has an option called <em>direct</em>. It tells <em>dd</em> to do direct I/O instead of regular I/O. Another option for doing direct I/O is writing your own program that opens files with O_DIRECT flag (see <em>open</em>(2) for details).</p>
<p><em>Update Feb. 12: Thanks to Ivan for noting the difference between synchronous I/O and direct I/O. I updated the post to reflect the difference.<br />
</em></p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/swap-vs-no-swap' rel='bookmark' title='Permanent Link: Swap vs. no swap'>Swap vs. no swap</a></li>
<li><a href='http://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux' rel='bookmark' title='Permanent Link: SMP affinity and proper interrupt handling in Linux'>SMP affinity and proper interrupt handling in Linux</a></li>
<li><a href='http://www.alexonlinux.com/aligned-vs-unaligned-memory-access' rel='bookmark' title='Permanent Link: Aligned vs. unaligned memory access'>Aligned vs. unaligned memory access</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/whats-is-direct-io-anyway/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>I got a new job, take 2</title>
		<link>http://www.alexonlinux.com/i-got-a-new-job-take-2</link>
		<comments>http://www.alexonlinux.com/i-got-a-new-job-take-2#comments</comments>
		<pubDate>Mon, 21 Dec 2009 13:59:54 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1677</guid>
		<description><![CDATA[I got a new job, again Today I signed a contract with a company named Fabrix.TV. Fabrix is developing a new generation of video content delivery platform. I am joining as a chief video content consumer senior software engineer. Related posts:Resume About


Related posts:<ol><li><a href='http://www.alexonlinux.com/resume' rel='bookmark' title='Permanent Link: Resume'>Resume</a></li>
<li><a href='http://www.alexonlinux.com/about' rel='bookmark' title='Permanent Link: About'>About</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I got a new job, again <img src='http://www.alexonlinux.com/wp-content/plugins/smilies-themer/modern/smile.gif' alt=':-)' class='wp-smiley' /> Today I signed a contract with a company named <a href="http://www.fabrix.tv" rel="nofollow" title="Link to Fabrix.TV"  onclick="return TrackClick('http%3A%2F%2Fwww.fabrix.tv','Link+to+Fabrix.TV')">Fabrix.TV</a>. Fabrix is developing a new generation of video content delivery platform.</p>
<p>I am joining as a <span style="text-decoration: line-through;">chief video content consumer</span> senior software engineer.</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/resume' rel='bookmark' title='Permanent Link: Resume'>Resume</a></li>
<li><a href='http://www.alexonlinux.com/about' rel='bookmark' title='Permanent Link: About'>About</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/i-got-a-new-job-take-2/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Rethinking linked list insertion</title>
		<link>http://www.alexonlinux.com/rethinking-linked-list-insertion</link>
		<comments>http://www.alexonlinux.com/rethinking-linked-list-insertion#comments</comments>
		<pubDate>Sat, 19 Dec 2009 12:24:36 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code library]]></category>
		<category><![CDATA[Short articles]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1658</guid>
		<description><![CDATA[There is one nice thing in looking for a new job. That is, you meet lots of new people and have a chance to learn from them. For example in one of the companies I was asked about something called anti-debugging. I didn&#8217;t have a clue what that is and had to ask for an [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/pthread-mutex-vs-pthread-spinlock' rel='bookmark' title='Permanent Link: pthread mutex vs pthread spinlock'>pthread mutex vs pthread spinlock</a></li>
<li><a href='http://www.alexonlinux.com/todo-list' rel='bookmark' title='Permanent Link: Todo list'>Todo list</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>There is one nice thing in looking for a new job. That is, you meet lots of new people and have a chance to learn from them. For example in one of the companies I was asked about something called anti-debugging. I didn&#8217;t have a clue what that is and had to ask for an explanation. Apparently, this is a set of techniques used to fool a debugger and make the code undebuggable.</p>
<p>Anyway, here&#8217;s something else that I learned during one of the interviews.</p>
<p><span id="more-1658"></span>I was asked to implement insertion into a linked list in <em>C</em>. Each list node has a number (<em>num</em>). Numbers in the list should be sorted in ascending order &#8211; node with lowest number should be first. Here is my naive implementation.</p>
<pre class="brush:cpp">void list_insert(int num)
{
        list_node_t *n, *tmp, *prev;

        n = allocate_node();
        n-&gt;num = num;

        if (!head) {
                head = n;
                n-&gt;next = NULL;
        } else {
                tmp = head;
                prev = NULL;
                while (tmp) {
                        if (tmp-&gt;num &gt;= n-&gt;num) {
                                if (prev == NULL) {
                                        head-&gt;next = n;
                                        n-&gt;next = NULL;
                                } else {
                                        n-&gt;next = tmp;
                                        prev-&gt;next = n;
                                }

                                break;
                        }

                        prev = tmp;
                        tmp = tmp-&gt;next;
                }

                if (!tmp) {
                        n-&gt;next = NULL;
                        prev-&gt;next = n;
                }
        }
}</pre>
<p>Yeah, well it is pretty long, but that&#8217;s how you do it, right? You have to make sure that the list is not empty (line 8 ) &#8211; if it is empty, then new node should be placed at the head of the list. Then we have to find right place for the new node and insert it into its position (lines 14-29). Finally, if we didn&#8217;t find a good position for the new node, we should put the node at the end of the list (lines 31-34).</p>
<p>When I showed this to the examiner he asked me to rethink the routine. In particular he didn&#8217;t like number of <em>if</em> statements. After an hour of discussing various optimizations, this is what we came up with.</p>
<pre class="brush:cpp">void list_insert(int num)
{
        list_node_t **tmp, *n;

        n = allocate_node();
        n-&gt;num = num;

        tmp = &amp;head;
        while (*tmp) {
                if ((*tmp)-&gt;num &gt;= n-&gt;num)
                        break;
                tmp = &amp;(*tmp)-&gt;next;
        }

/*
        (*tmp) = n;
       n-&gt;next = (*tmp)-&gt;next;
*/

/*
        The code in the comment above is broken. Thanks to jagan
        for pointing this out. Here's the right code.
*/
        n->next = *tmp;
        *tmp = n;
}</pre>
<p>There are several things that make this version better.</p>
<p>First of all, instead of having a pointer to current node (<em>tmp</em>) and previous node (<em>prev</em>), we have one pointer that corresponds to pointer to previous node. This way we can always get to the current node via <em>next</em> field in the previous node. Thus we don&#8217;t need two pointers anymore.</p>
<p>Also, this version uses pointer to pointer to node to traverse through the list. We don&#8217;t insert the node in the while loop anymore. Purpose of the while loop is to find right place for the new node. This spares <em>if</em> statement that tests if the list is empty and <em>if </em>statement in the loop.</p>
<p>Finally, once <em>tmp</em> points to the right place, we insert the node.</p>
<p>Second version runs faster too. I did a small program that tests both versions and it appears that the later version is something like 5% faster.</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/pthread-mutex-vs-pthread-spinlock' rel='bookmark' title='Permanent Link: pthread mutex vs pthread spinlock'>pthread mutex vs pthread spinlock</a></li>
<li><a href='http://www.alexonlinux.com/todo-list' rel='bookmark' title='Permanent Link: Todo list'>Todo list</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/rethinking-linked-list-insertion/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>I am looking for a new job</title>
		<link>http://www.alexonlinux.com/i-am-looking-for-a-new-job</link>
		<comments>http://www.alexonlinux.com/i-am-looking-for-a-new-job#comments</comments>
		<pubDate>Mon, 07 Dec 2009 13:52:03 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1651</guid>
		<description><![CDATA[I am sorry to say that, but Exanet, a company that I joined less than a month ago, has been closed. This means that I am looking for a new job. The good thing is that now your or your friend&#8217;s company has  a chance to hire a programmer with ten years of experience in [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/about' rel='bookmark' title='Permanent Link: About'>About</a></li>
<li><a href='http://www.alexonlinux.com/i-got-a-new-job-take-3' rel='bookmark' title='Permanent Link: I got a new job, take 3'>I got a new job, take 3</a></li>
<li><a href='http://www.alexonlinux.com/resume' rel='bookmark' title='Permanent Link: Resume'>Resume</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I am sorry to say that, but Exanet, a company that I joined less than a month ago, has been closed.</p>
<p>This means that I am looking for a new job. The good thing is that now your or your friend&#8217;s company has  a chance to hire a programmer with ten years of experience in writing application for Linux and Linux kernel. So, if you can help, please pass my resume. <a href="http://www.alexonlinux.com/resume"title="Link to my resume"  onclick="return TrackClick('http%3A%2F%2Fwww.alexonlinux.com%2Fresume','Link+to+my+resume')">You can find it here.</a></p>
<p>Thanks.</p>
<p>Alex.</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/about' rel='bookmark' title='Permanent Link: About'>About</a></li>
<li><a href='http://www.alexonlinux.com/i-got-a-new-job-take-3' rel='bookmark' title='Permanent Link: I got a new job, take 3'>I got a new job, take 3</a></li>
<li><a href='http://www.alexonlinux.com/resume' rel='bookmark' title='Permanent Link: Resume'>Resume</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/i-am-looking-for-a-new-job/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>I got a new job</title>
		<link>http://www.alexonlinux.com/i-got-a-new-job</link>
		<comments>http://www.alexonlinux.com/i-got-a-new-job#comments</comments>
		<pubDate>Wed, 18 Nov 2009 07:51:09 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1647</guid>
		<description><![CDATA[You probably noticed that I didn&#8217;t write anything new for awhile. Well, I was looking for a new job and didn&#8217;t have much time to write. Luckily, this is over. I am now a senior software engineer at Exanet LTD. Exanet is developing storage solutions for large organisations. ExaStore, main product of the company, is [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/i-am-looking-for-a-new-job' rel='bookmark' title='Permanent Link: I am looking for a new job'>I am looking for a new job</a></li>
<li><a href='http://www.alexonlinux.com/a-new-kind-of-virtualization' rel='bookmark' title='Permanent Link: A new kind of virtualization'>A new kind of virtualization</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>You probably noticed that I didn&#8217;t write anything new for awhile. Well, I was looking for a new job and didn&#8217;t have much time to write. Luckily, this is over. I am now a senior software engineer at <a href="http://www.exanet.com" rel="nofollow"  onclick="return TrackClick('http%3A%2F%2Fwww.exanet.com','Exanet+LTD')">Exanet LTD</a>.</p>
<p>Exanet is developing storage solutions for large organisations. ExaStore, main product of the company, is a clustered NAS gateway solution providing highly available and distributed data storage.</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/i-am-looking-for-a-new-job' rel='bookmark' title='Permanent Link: I am looking for a new job'>I am looking for a new job</a></li>
<li><a href='http://www.alexonlinux.com/a-new-kind-of-virtualization' rel='bookmark' title='Permanent Link: A new kind of virtualization'>A new kind of virtualization</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/i-got-a-new-job/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MSI-X &#8211; the right way to spread interrupt load</title>
		<link>http://www.alexonlinux.com/msi-x-the-right-way-to-spread-interrupt-load</link>
		<comments>http://www.alexonlinux.com/msi-x-the-right-way-to-spread-interrupt-load#comments</comments>
		<pubDate>Wed, 18 Nov 2009 07:46:11 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Programming Articles]]></category>
		<category><![CDATA[System Administrator Articles]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1632</guid>
		<description><![CDATA[When considering ways to spread interrupts from one device among multiple cores, I can&#8217;t not to mention MSI-X. The thing is that MSI-X is actually the right way to do the job. Interrupt affinity, which I discussed here and here, has a fundamental problem. That is inevitable CPU cache misses. To emphasise this, think about [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/why-interrupt-affinity-with-multiple-cores-is-not-such-a-good-thing' rel='bookmark' title='Permanent Link: Why interrupt affinity with multiple cores is not such a good thing'>Why interrupt affinity with multiple cores is not such a good thing</a></li>
<li><a href='http://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux' rel='bookmark' title='Permanent Link: SMP affinity and proper interrupt handling in Linux'>SMP affinity and proper interrupt handling in Linux</a></li>
<li><a href='http://www.alexonlinux.com/whats-is-direct-io-anyway' rel='bookmark' title='Permanent Link: What&#8217;s is direct I/O anyway?'>What&#8217;s is direct I/O anyway?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>When considering ways to spread interrupts from one device among multiple cores, I can&#8217;t not to mention MSI-X. The thing is that MSI-X is actually the right way to do the job.</p>
<p>Interrupt affinity, which I discussed <a href="why-interrupt-affinity-with-multiple-cores-is-not-such-a-good-thing" rel="nofollow" >here</a> and <a href="smp-affinity-and-proper-interrupt-handling-in-linux" rel="nofollow" >here</a>, has a fundamental problem. That is inevitable CPU cache misses. To emphasise this, think about what happens when your computer receives a packet from the network. Packet belongs to some connection. With interrupt affinity the packet would land on core X, while the chances are that previous packet on the same TCP connection has landed on core Y (X ≠ Y).</p>
<p>Handing the packet would require kernel to load TCP connection object into X&#8217;s cache. But, this is so ineffective. After all, the TCP connection object is already in Y&#8217;s cache. Wouldn&#8217;t it be better to handle second packet on core Y as well?</p>
<p><span id="more-1632"></span>This is the  problem with interrupt affinity. From one point of view we want to spread interrupts to even the load on cores. From another point of view, doing simple round robin isn&#8217;t enough. The little fella that decides where each interrupt goes, should be able to look into the packet and depending on what TCP connection it belongs to, send the interrupt to core that handles all packets that belong to this connection.</p>
<p>Ideally, NICs should be able to:</p>
<ol>
<li>Look into packets and identify connections.</li>
<li>Direct interrupt to core that handles the connection.</li>
</ol>
<p>Apparently, this functionality already here. Devices that support MSI-X do exactly this.</p>
<h2>Meet MSI-X</h2>
<p>MSI-X is an extension to MSI. MSI replaces good old pin based interrupt delivery mechanism.</p>
<blockquote><p>Each IO-APIC chip (x86 permits up to 5) has 24 legs, each connected to one or more devices. When IO-APIC receives an interrupt, it redirects the interrupt to one of the local-APICs. Each local-APIC connected to a core that receives an interrupt.</p></blockquote>
<p>MSI provides a kind of protocol for interrupt delivery. Instead of raising signal on pins, PCI cards send a message over MSI and IO-APIC translates the message into right interrupt. Theoretically this means that each device can have number of interrupt vectors. In reality, plain MSI does not support this, but MSI-X does.</p>
<p>Modern high-end network cards that support MSI-X, implement multiple tx-rx queues. Each queue tied up to an interrupt vector and each NIC has plenty of them. I checked Intel&#8217;s 82575 chipset. With igb driver compiled properly, it has up to eight queues, four rx and four tx. Broadcom&#8217;s 5709 chipset provides eight queues (and eight interrupt vectors), each handling both rx and tx.</p>
<p>In kernel 2.6.24, kernel developers introduced new member of struct sk_buff called queue_mapping. This member tells incoming NIC driver what queue to use when transmitting the packet.</p>
<p>Before transmitting the packet, kernel decides what queue to use for this packet (net/core/dev.c:dev_queue_xmit()). It uses two techniques to do so. First, kernel can ask NIC driver to provide a queue number for the packet. This functionality, however, is optional in NIC drivers and at the moment both Intel and Broadcom drivers don&#8217;t provide it. Otherwise, kernel uses a simple hashing algorithm that produces 16 bit number from two ip addresses and (in case of TCP or UDP) two port numbers. All this happens in function named simple_tx_hash() in net/core/dev.c.</p>
<p>When receiving packets, things are even easier because NIC firmware and the driver decide what queue to use to introduce the packet to the kernel.</p>
<p>Using this simple technique kernel and modern NIC&#8217;s can verify that packets that belong to certain connection land on certain queue. Using interrupt affinity binding techniques you can bind certain interrupt vector to certain core (writing to smp_affinity, etc). Thus you can spread interrupts among multiple cores and yet make sure there are no cache misses.</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/why-interrupt-affinity-with-multiple-cores-is-not-such-a-good-thing' rel='bookmark' title='Permanent Link: Why interrupt affinity with multiple cores is not such a good thing'>Why interrupt affinity with multiple cores is not such a good thing</a></li>
<li><a href='http://www.alexonlinux.com/smp-affinity-and-proper-interrupt-handling-in-linux' rel='bookmark' title='Permanent Link: SMP affinity and proper interrupt handling in Linux'>SMP affinity and proper interrupt handling in Linux</a></li>
<li><a href='http://www.alexonlinux.com/whats-is-direct-io-anyway' rel='bookmark' title='Permanent Link: What&#8217;s is direct I/O anyway?'>What&#8217;s is direct I/O anyway?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/msi-x-the-right-way-to-spread-interrupt-load/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
