<?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/feed" rel="self" type="application/rss+xml" />
	<link>http://www.alexonlinux.com</link>
	<description></description>
	<lastBuildDate>Wed, 25 Aug 2010 05:58:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>My next programming language</title>
		<link>http://www.alexonlinux.com/my-next-programming-language</link>
		<comments>http://www.alexonlinux.com/my-next-programming-language#comments</comments>
		<pubDate>Sun, 22 Aug 2010 21:04:43 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Opinion]]></category>
		<category><![CDATA[Programming Articles]]></category>
		<category><![CDATA[bazaar]]></category>
		<category><![CDATA[CVS]]></category>
		<category><![CDATA[evolution]]></category>
		<category><![CDATA[future]]></category>
		<category><![CDATA[mercurial]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[programming language]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[version control system]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1819</guid>
		<description><![CDATA[This week-end I&#8217;ve been playing with various version control systems. Until now, I&#8217;ve been doing all my home codings with subversion. I&#8217;ve written


Related posts:<ol><li><a href='http://www.alexonlinux.com/distributed-vs-centralized-version-control-systems' rel='bookmark' title='Permanent Link: Distributed vs. centralized version control systems'>Distributed vs. centralized version control systems</a></li>
<li><a href='http://www.alexonlinux.com/bazaar-for-subversion-users-part-1-the-basics' rel='bookmark' title='Permanent Link: Bazaar for subversion users, part 1 &#8211; the basics'>Bazaar for subversion users, part 1 &#8211; the basics</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>This week-end I&#8217;ve been playing with various version control systems. Until now, I&#8217;ve been doing all my home codings with subversion. I&#8217;ve written <a title="Link to article about bazaar" href="bazaar-for-subversion-users-part-1-the-basics" onclick="return TrackClick('bazaar-for-subversion-users-part-1-the-basics" onclick="return TrackClick('bazaar-for-subversion-users-part-1-the-basics','Link+to+article+about+bazaar')",'Link+to+article+about+bazaar')">about bazaar in the past</a>, but it seems to me that <a href="http://stackoverflow.com/questions/995636/popularity-of-git-mercurial-bazaar-vs-which-to-recommend">bazaar isn&#8217;t going anywhere</a> and it busts any piece of motivation that I have to continue writing about it.</p>
<p>Version control that I did try is git. This is a very popular version control system and for a good reason. Comparing git and subversion brought me to a conclusion that git is really a very consequence of how things work in the world. Thing about git is that it is a distributed version control while subversion is not. You can make a distributed version of subversion, but it won&#8217;t be subversion anymore.</p>
<p>Distributivity is one thing, but there are more. Take the standard trunk/branches/tags layout that you have to create in subversion &#8211; version control could do it for you, as git/bazaar/mercurial do. At first, after working with CVS for some time, having an option to have non-standard layout seemed cool for some time. But then it appeared completely useless.</p>
<p>This brings a notion of evolution into version control systems and I bet there&#8217;s similar process with programming languages. I think we can already starting drawing a programming language that will replace Python.</p>
<p>Yep, Python isn&#8217;t perfect. I thought I&#8217;d compile a list of things that shall be different in ought to be programming language that comes after Python.</p>
<p><span id="more-1819"></span></p>
<ol>
<li>Passing <em>self</em> to methods is counter-productive. Using <em>self</em> to access members is super counter productive. Yet this is how Python works. Without this, it won&#8217;t be Python anymore.</li>
<li>Same thing with <em>global</em>. Every program has this one global variable that every other class and function use. So, every entity that uses that variable has to declare it with <em>global</em> keyword. Utterly counter-productive.</li>
<li>Starting every private method and field with __ (double under-score) is ugly. The way it changes method name prepending it with a class name is even uglier. It is a really hackish way to handle this problem. I understand that this is the Python way of doing things, but it feels wrong.</li>
<li>Another hackish thing are decorators. Make an option to have static methods, class methods and properties and decorators are gone. No one would need them anymore, and it will be one bit easier to master Python.</li>
<li>You name it.</li>
</ol>
<p><em>Disclaimer (can&#8217;t get along without one this time <img src='http://www.alexonlinux.com/wp-content/plugins/smilies-themer/modern/smile.gif' alt=':-)' class='wp-smiley' /> ): This post may seem like one criticizing Python and it does in some ways, but I doubt these can be fixed in something called Python (unless Guido van Rossum brews it and calls it P</em><em>ython 4). In the meantime I love Python and use it on a daily basis. </em></p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/distributed-vs-centralized-version-control-systems' rel='bookmark' title='Permanent Link: Distributed vs. centralized version control systems'>Distributed vs. centralized version control systems</a></li>
<li><a href='http://www.alexonlinux.com/bazaar-for-subversion-users-part-1-the-basics' rel='bookmark' title='Permanent Link: Bazaar for subversion users, part 1 &#8211; the basics'>Bazaar for subversion users, part 1 &#8211; the basics</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/my-next-programming-language/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<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">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 is direct I/O anyway?</title>
		<link>http://www.alexonlinux.com/what-is-direct-io-anyway</link>
		<comments>http://www.alexonlinux.com/what-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/what-is-direct-io-anyway/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Recursively deleting symbolic link and what it points to</title>
		<link>http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to</link>
		<comments>http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to#comments</comments>
		<pubDate>Mon, 01 Feb 2010 08:52:59 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Code library]]></category>
		<category><![CDATA[Programming Articles]]></category>
		<category><![CDATA[Short articles]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1703</guid>
		<description><![CDATA[Recently I looked for a solution to this little problem. how do you, programmatically, delete a symbolic link and a file that it points to? One problem that you should take care of when tackling this problem, is that symbolic link can point to a symbolic link. Then symbolic link should also point to symbolic [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/hex-dump-functions' rel='bookmark' title='Permanent Link: Hex dump functions'>Hex dump functions</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>
<li><a href='http://www.alexonlinux.com/how-less-processes-its-input' rel='bookmark' title='Permanent Link: How less processes its input'>How less processes its input</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Recently I looked for a solution to this little problem. how do you, programmatically, delete a symbolic link and a file that it points to?</p>
<p>One problem that you should take care of when tackling this problem, is that symbolic link can point to a symbolic link. Then symbolic link should also point to symbolic link. And once again, and again and again&#8230;</p>
<p><span id="more-1703"></span>So what can we do about it? First, lets start with <em>lstat</em>() system all. It will tell us is the file we&#8217;re interested in, is actually a symbolic link. To be more precise, <em>st_mode</em> field in <em>struct stat</em> will have flag S_IFLNK if specified file is a symbolic link. Note that it should be <em>lstat</em>() and not <em>stat</em>() &#8211; the later will return information about file the link points to and not about the link.</p>
<p>Next step is to call <em>readlink</em>(). This system call returns name of the file pointed to by specified symbolic link.</p>
<p>Finally, you should repeat the process recursively, for the pointed to file. Here is the code that does it:</p>
<pre class="brush:cpp">int recursive_deleter(const char* filename)
{
  struct stat st;
  char buffer[1024];

  if (lstat(filename, &amp;st)) {
    perror("stat");
    return -1;
  }     

  if (st.st_mode &amp; S_IFLNK == S_IFLNK) {
    memset(buffer, 0, sizeof(buffer));
    if (readlink(filename, buffer, sizeof(buffer)) &lt; 0) {
      perror("readlink");
      return -1;
    }           

    printf("File %s is a symbolic link to %s\n", filename, buffer);

    if (recursive_deleter(buffer))
      return 0;
  }     

  printf("Deleting %s\n", filename);

  if (unlink(filename)) {
    perror("unlink");
    return -1;
  }     

  return 0;
}
</pre>
<p>Have fun!</p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/hex-dump-functions' rel='bookmark' title='Permanent Link: Hex dump functions'>Hex dump functions</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>
<li><a href='http://www.alexonlinux.com/how-less-processes-its-input' rel='bookmark' title='Permanent Link: How less processes its input'>How less processes its input</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.alexonlinux.com/recursively-deleting-symbolic-link-and-what-it-points-to/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Direct IO in Python</title>
		<link>http://www.alexonlinux.com/direct-io-in-python</link>
		<comments>http://www.alexonlinux.com/direct-io-in-python#comments</comments>
		<pubDate>Tue, 12 Jan 2010 07:50:06 +0000</pubDate>
		<dc:creator>Alexander Sandler</dc:creator>
				<category><![CDATA[Programming Articles]]></category>
		<category><![CDATA[Short articles]]></category>

		<guid isPermaLink="false">http://www.alexonlinux.com/?p=1684</guid>
		<description><![CDATA[Doing file I/O of any kind in Python is really easy. You can start with plain open() and friends, working with Python&#8217;s file objects. by the way, Python&#8217;s open() resembles C&#8216;s fopen() so closely that I can&#8217;t stop thinking that open() may be based on fopen(). When its not enough, you can always upgrade to [...]


Related posts:<ol><li><a href='http://www.alexonlinux.com/what-is-direct-io-anyway' rel='bookmark' title='Permanent Link: What is direct I/O anyway?'>What is direct I/O anyway?</a></li>
<li><a href='http://www.alexonlinux.com/call-a-constructor-or-allocate-an-object-in-place-2' rel='bookmark' title='Permanent Link: Call a constructor or allocate an object in-place'>Call a constructor or allocate an object in-place</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>Doing file I/O of any kind in Python is really easy. You can start with plain <em>open()</em> and friends, working with Python&#8217;s file objects. by the way, Python&#8217;s <em>open()</em> resembles <em>C</em>&#8216;s <em>fopen()</em> so closely that I can&#8217;t stop thinking that <em>open()</em> may be based on <em>fopen()</em>.</p>
<p>When its not enough, you can always upgrade to <em>open()</em> and <em>close()</em> from <em>os</em> module. Opening man page on <em>open()</em> (the system call &#8211; open(2)) reveals all those O_something options that you can pass to <em>os.open()</em>. But not all of them can be used in Python. For example, if you open a file with <em>O_DIRECT</em> and then try to write to it, you will end up with some strange error message.</p>
<p><span id="more-1684"></span></p>
<pre class="brush:py">&gt;&gt;&gt; import os
&gt;&gt;&gt; f = os.open('file', os.O_CREAT | os.O_TRUNC | os.O_DIRECT | os.O_RDWR)
&gt;&gt;&gt; s = ' ' * 1024
&gt;&gt;&gt; os.write(f, s)
Traceback (most recent call last):
  File "", line 1, in
OSError: [Errno 22] Invalid argument
&gt;&gt;&gt;
</pre>
<p>Invalid argument?. What invalid argument? Hey there&#8217;s nothing wrong with those arguments&#8230;</p>
<p>Reading open(2) man page further reveals that working with <em>O_DIRECT</em> requires that all buffers used for I/O should be aligned to 512 byte boundary. But how can you have a memory buffer aligned to 512 bytes in Python?</p>
<p>Apparently, there&#8217;s a way. Python comes with a module called <em>mmap</em>. <em>mmap()</em> is a system call that allows one to map portion of file into memory. All writes to memory mapped file, go directly to file despite it looks like you&#8217;re working with plain memory buffer. Same with reads.</p>
<p>There&#8217;s one interesting thing about<em> mmap</em>. It works with granularity of one memory page &#8211; 4kb that is. So every memory mapped buffer is naturally memory aligned to 4kb, thus to 512 byte boundary too. But hey, shouldn&#8217;t <em>mmap</em> map files?</p>
<p>Well, apparently <em>mmap</em> can be used for memory allocations. I.e. specifying -1 as file descriptor does just that &#8211; allocates RAM, as much as you tell it. So, this is what we do:</p>
<pre class="brush:py">&gt;&gt;&gt; import os
&gt;&gt;&gt; import mmap
&gt;&gt;&gt;
&gt;&gt;&gt; f = os.open('file', os.O_CREAT | os.O_DIRECT | os.O_TRUNC | os.O_RDWR)
&gt;&gt;&gt; m = mmap.mmap(-1, 1024 * 1024)
&gt;&gt;&gt; s = ' ' * 1024 * 1024
&gt;&gt;&gt;
&gt;&gt;&gt; m.write(s)
&gt;&gt;&gt; os.write(f, m)
1048576
&gt;&gt;&gt; os.close(f)
&gt;&gt;&gt;</pre>
<p>Note that <em>mmap </em>memory buffer object behaves like a file. I.e. you can write into the buffer and read from it &#8211; like I do in line 8. More on it in <a href="http://docs.python.org/library/mmap.html" onclick="return TrackClick('http%3A%2F%2Fdocs.python.org%2Flibrary%2Fmmap.html','official+documentation')">official documentation</a>.</p>
<p>Have fun! <img src='http://www.alexonlinux.com/wp-content/plugins/smilies-themer/modern/smile.gif' alt=':-)' class='wp-smiley' /> </p>


<p>Related posts:<ol><li><a href='http://www.alexonlinux.com/what-is-direct-io-anyway' rel='bookmark' title='Permanent Link: What is direct I/O anyway?'>What is direct I/O anyway?</a></li>
<li><a href='http://www.alexonlinux.com/call-a-constructor-or-allocate-an-object-in-place-2' rel='bookmark' title='Permanent Link: Call a constructor or allocate an object in-place'>Call a constructor or allocate an object in-place</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/direct-io-in-python/feed</wfw:commentRss>
		<slash:comments>11</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 title="Link to Fabrix.TV" href="http://www.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>
	</channel>
</rss>
