<?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>A Geek&#039;s Page</title>
	<atom:link href="http://wangcong.org/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://wangcong.org/blog</link>
	<description>Stay Hungry, Stay Foolish</description>
	<lastBuildDate>Fri, 27 Apr 2012 14:40:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>中华民族到了最坑爹的时候</title>
		<link>http://wangcong.org/blog/archives/1952</link>
		<comments>http://wangcong.org/blog/archives/1952#comments</comments>
		<pubDate>Wed, 25 Apr 2012 06:35:23 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1952</guid>
		<description><![CDATA[牛奶不能喝了！
奶粉不能吃了！
馒头不能吃了！
食用油不能用了！
胶囊不能吃了！
果冻酸奶不能吃了！
蜜饯不能吃了！
沙琪玛不能吃了！
牛肉拉面不能吃了！
砂锅粥不能吃了！
可乐不能... ]]></description>
			<content:encoded><![CDATA[<p>牛奶不能喝了！</p>
<p>奶粉不能吃了！</p>
<p>馒头不能吃了！</p>
<p>食用油不能用了！</p>
<p>胶囊不能吃了！</p>
<p>果冻酸奶不能吃了！</p>
<p>蜜饯不能吃了！</p>
<p>沙琪玛不能吃了！</p>
<p>牛肉拉面不能吃了！</p>
<p>砂锅粥不能吃了！</p>
<p>可乐不能喝了！</p>
<p>纯净水不能喝了！</p>
<p>果粒橙不能喝了！</p>
<p>雪碧不能喝了！</p>
<p>绿茶不能喝了！</p>
<p>……</p>
<p>起来！不愿做奴隶的人们！把我们的食物铸成我们新的生化武器！中华民族到了，最坑爹的时候！每个人被迫着发出最后的吼声！起来！起来！起来！我们东亚病夫，吃着最毒的食物，前进！吃着最毒的食物， 前进！前进！前进！进！</p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1952/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分享视频：从一维空间到十二维空间</title>
		<link>http://wangcong.org/blog/archives/1947</link>
		<comments>http://wangcong.org/blog/archives/1947#comments</comments>
		<pubDate>Fri, 20 Apr 2012 07:50:34 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1947</guid>
		<description><![CDATA[刚看到一个很有趣的讲多维空间的科普视频：

后悔当年物理没有学好，看到四维后面就不懂了。... ]]></description>
			<content:encoded><![CDATA[<p>刚看到一个很有趣的讲多维空间的科普视频：</p>
<p><embed src="http://www.tudou.com/v/P5Xf_5BXhFY/&#038;resourceId=0_05_05_99/v.swf" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="opaque" width="480" height="400"></embed></p>
<p>后悔当年物理没有学好，看到四维后面就不懂了。</p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1947/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>perfbook 读书笔记：ACCESS_ONCE()</title>
		<link>http://wangcong.org/blog/archives/1941</link>
		<comments>http://wangcong.org/blog/archives/1941#comments</comments>
		<pubDate>Tue, 03 Apr 2012 15:44:29 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1941</guid>
		<description><![CDATA[如果你看过 Linux 内核中的 RCU 的实现，你应该注意到了这个叫做 ACCESS_ONCE() 宏，但是并没有很多人真正理解它的含义。网上有的地方甚至对此有错误的解释，所以特写此文来澄清一下。
虽然我... ]]></description>
			<content:encoded><![CDATA[<p>如果你看过 Linux 内核中的 RCU 的实现，你应该注意到了这个叫做 ACCESS_ONCE() 宏，但是并没有很多人真正理解它的含义。网上<a href="http://blog.163.com/seven_7_one/blog/static/1626064122011513103514672/" target="_blank">有的地方</a>甚至对此有错误的解释，所以特写此文来澄清一下。</p>
<p>虽然我早在读 perfbook 之前就了解了 ACCESS_ONCE() 的含义（通过询问大牛 Paul），但这本书中正好也没有很详细地介绍这个宏，所以就当是此书的读书笔记了。</p>
<p><strong>定义</strong></p>
<p>它的定义很简单，在 include/linux/compiler.h 的底部：</p>
<div class="igBar"><span id="lc-14"><a href="#" onclick="javascript:showPlainTxt('c-14'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-14">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #339933;">#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&amp;(x))</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>仅从语法上讲，这似乎毫无意义，先取其地址，在通过指针取其值。而实际上不然，多了一个关键词 volatile，所以它的含义就是强制编译器每次使用 x 都从内存中获取。</p>
<p><strong>原因</strong><br />
仅仅从定义来看基本上看不大出来为什么要引入这么一个东西。可以通过几个例子（均来自 Paul，我做了小的修改）看一下。</p>
<p>1. 循环中有每次都要读取的全局变量：</p>
<div class="igBar"><span id="lc-15"><a href="#" onclick="javascript:showPlainTxt('c-15'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-15">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">...</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #993333;">static</span> <span style="color: #993333;">int</span> should_continue;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #993333;">static</span> <span style="color: #993333;">void</span> do_something<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">...</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>should_continue<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;do_something<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>假设 do_something() 函数中并没有对变量 should_continue 做任何修改，那么，编译器完全有可能把它优化成：</p>
<div class="igBar"><span id="lc-16"><a href="#" onclick="javascript:showPlainTxt('c-16'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-16">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">...</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>should_continue<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>;;<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;do_something<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>这很好理解，不是吗？对于单线程的程序，这么做完全没问题，可是对于多线程，问题就出来了：如果这个线程在执行do_something() 的期间，另外一个线程改变了 should_continue 的值，那么上面的优化就是完全错误的了！更严重的问题是，编译器根本就没有办法知道这段代码是不是并发的，也就无从决定进行的优化是不是正确的！</p>
<p>这里有两种解决办法：1) 给 should_continue 加锁，毕竟多个进程访问和修改全局变量需要锁是很自然的；2) 禁止编译器做此优化。加锁的方法有些过了，毕竟 should_continue 只是一个布尔，而且退一步讲，就算每次读到的值不是最新的 should_continue 的值也可能是无所谓的，大不了多循环几次，所以禁止编译器做优化是一个更简单也更容易的解决办法。我们使用 ACCESS_ONCE() 来访问 should_continue：</p>
<div class="igBar"><span id="lc-17"><a href="#" onclick="javascript:showPlainTxt('c-17'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-17">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">...</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>ACCESS_ONCE<span style="color: #009900;">&#40;</span>should_continue<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;do_something<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>2. 指针读取一次，但要dereference多次：</p>
<div class="igBar"><span id="lc-18"><a href="#" onclick="javascript:showPlainTxt('c-18'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-18">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">...</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #202020;">p</span> <span style="color: #339933;">=</span> global_ptr;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>p <span style="color: #339933;">&amp;&amp;</span> p<span style="color: #339933;">-</span>&gt;s <span style="color: #339933;">&amp;&amp;</span> p<span style="color: #339933;">-</span>&gt;s<span style="color: #339933;">-</span>&gt;func<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; p<span style="color: #339933;">-</span>&gt;s<span style="color: #339933;">-</span>&gt;func<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>那么编译器也有可能把它编译成：</p>
<div class="igBar"><span id="lc-19"><a href="#" onclick="javascript:showPlainTxt('c-19'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-19">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">...</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>global_ptr <span style="color: #339933;">&amp;&amp;</span> global_ptr<span style="color: #339933;">-</span>&gt;s <span style="color: #339933;">&amp;&amp;</span> global_ptr<span style="color: #339933;">-</span>&gt;s<span style="color: #339933;">-</span>&gt;func<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; global_ptr<span style="color: #339933;">-</span>&gt;s<span style="color: #339933;">-</span>&gt;func<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>你可以谴责编译器有些笨了，但事实上这是C标准允许的。这种情况下，另外的进程做了 global_ptr = NULL; 就会导致后一段代码 segfault，而前一段代码没问题。同上，所以这时候也要用 ACCESS_ONCE()：</p>
<div class="igBar"><span id="lc-20"><a href="#" onclick="javascript:showPlainTxt('c-20'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-20">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">...</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #202020;">p</span> <span style="color: #339933;">=</span> ACCESS_ONCE<span style="color: #009900;">&#40;</span>global_ptr<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>p <span style="color: #339933;">&amp;&amp;</span> p<span style="color: #339933;">-</span>&gt;s <span style="color: #339933;">&amp;&amp;</span> p<span style="color: #339933;">-</span>&gt;s<span style="color: #339933;">-</span>&gt;func<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; p<span style="color: #339933;">-</span>&gt;s<span style="color: #339933;">-</span>&gt;func<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>3. watchdog 中的变量：</p>
<div class="igBar"><span id="lc-21"><a href="#" onclick="javascript:showPlainTxt('c-21'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-21">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>;;<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;still_working <span style="color: #339933;">=</span> <span style="color: #cc66cc;color:#800000;">1</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;do_something<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>假设 do_something() 定义是可见的，而且没有修改 still_working 的值，那么，编译器可能会把它优化成：</p>
<div class="igBar"><span id="lc-22"><a href="#" onclick="javascript:showPlainTxt('c-22'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-22">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">still_working <span style="color: #339933;">=</span> <span style="color: #cc66cc;color:#800000;">1</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>;;<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;do_something<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>如果其它进程同时执行了：</p>
<div class="igBar"><span id="lc-23"><a href="#" onclick="javascript:showPlainTxt('c-23'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-23">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>;;<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;still_working <span style="color: #339933;">=</span> <span style="color: #cc66cc;color:#800000;">0</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sleep<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;color:#800000;">10</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>still_working<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;panic<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>通过 still_working 变量来检测 wathcdog 是否停止了，并且等待10秒后，它确实停止了，panic()！经过编译器优化后，就算它没有停止也会 panic！！所以也应该加上 ACCESS_ONCE()：</p>
<div class="igBar"><span id="lc-24"><a href="#" onclick="javascript:showPlainTxt('c-24'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-24">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>;;<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ACCESS_ONCE<span style="color: #009900;">&#40;</span>still_working<span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;color:#800000;">1</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;do_something<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>综上，我们不难看出，需要使用 ACCESS_ONCE() 的两个条件是：</p>
<p>1. 在<strong>无锁</strong>的情况下访问全局变量；<br />
2. 对该变量的访问可能被编译器优化成合并成一次（上面第1、3个例子）或者拆分成多次（上面第2个例子）。</p>
<p><strong>例子</strong></p>
<p>Linus <a href="http://yarchive.net/comp/linux/ACCESS_ONCE.html">在邮件中</a>给出的另外一个例子是：</p>
<p>编译器有可能把下面的代码：</p>
<div class="igBar"><span id="lc-25"><a href="#" onclick="javascript:showPlainTxt('c-25'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-25">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>a&gt; MEMORY<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; do1;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; do2;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; do3;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; do2;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>优化成：</p>
<div class="igBar"><span id="lc-26"><a href="#" onclick="javascript:showPlainTxt('c-26'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-26">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>a&gt; MEMORY<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; do1;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; do2;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>a&gt; MEMORY<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; do3;</div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>这里完全符合上面我总结出来的两个条件，所以也应该使用 ACCESS_ONCE()。正如 Linus 所说，不是编译器一定会这么优化，而是你无法证明它不会做这样的优化。</p>
<blockquote><p>So the rule is: if you access unlocked values, you use ACCESS_ONCE(). You<br />
don't say "but it can't matter". Because you simply don't know.</p></blockquote>
<p>再看实际中的例子：</p>
<pre>
commit 0ad92ad03aa444b312bd318b0341011a8be09d13
Author: Eric Dumazet
Date:   Tue Nov 1 12:56:59 2011 +0000

    udp: fix a race in encap_rcv handling

    udp_queue_rcv_skb() has a possible race in encap_rcv handling, since
    this pointer can be changed anytime.

    We should use ACCESS_ONCE() to close the race.

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 131d8a7..ab0966d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1397,6 +1397,8 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 	nf_reset(skb);

 	if (up->encap_type) {
+		int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
+
 		/*
 		 * This is an encapsulation socket so pass the skb to
 		 * the socket's udp_encap_rcv() hook. Otherwise, just
@@ -1409,11 +1411,11 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
 		 */

 		/* if we're overly short, let UDP handle it */
-		if (skb->len > sizeof(struct udphdr) &#038;&
-		    up->encap_rcv != NULL) {
+		encap_rcv = ACCESS_ONCE(up->encap_rcv);
+		if (skb->len > sizeof(struct udphdr) &#038;& encap_rcv != NULL) {
 			int ret;

-			ret = (*up->encap_rcv)(sk, skb);
+			ret = encap_rcv(sk, skb);
 			if (ret <= 0) {
 				UDP_INC_STATS_BH(sock_net(sk),
 						 UDP_MIB_INDATAGRAMS,
</pre>
<p><strong>更多</strong></p>
<p>或许看了上面的会让你有一种错觉，volatile 可以解决同步的问题，<a href="http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/">其实不然</a>，它只解决其中一个方面。而且上面所有的例子有一个共同的特点：所有的写操作都是简单的赋值（相对于大于CPU字宽的结构体赋值），简单赋值操作在所有平台上都是原子性的，而如果是做加法操作，原子性未必可以保证，更不用说需要 memory barrier 的时候了。所以，不要滥用 volatile。</p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1941/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>perfbook 读书笔记：SLAB_DESTROY_BY_RCU</title>
		<link>http://wangcong.org/blog/archives/1934</link>
		<comments>http://wangcong.org/blog/archives/1934#comments</comments>
		<pubDate>Thu, 29 Mar 2012 14:15:50 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1934</guid>
		<description><![CDATA[perfbook 书中第8.3.3.6节讲到了类型安全，提到了Linux内核中的 SLAB_DESTROY_BY_RCU。但是书中并没有更详细的介绍这个特性。这里更详细地说一下。
要理解 SLAB_DESTROY_BY_RCU，最重要的是看 kmem_cache_destro... ]]></description>
			<content:encoded><![CDATA[<p>perfbook 书中第8.3.3.6节讲到了类型安全，提到了Linux内核中的 SLAB_DESTROY_BY_RCU。但是书中并没有更详细的介绍这个特性。这里更详细地说一下。</p>
<p>要理解 SLAB_DESTROY_BY_RCU，最重要的是看 kmem_cache_destroy()，以 slub 为例，</p>
<div class="igBar"><span id="lc-29"><a href="#" onclick="javascript:showPlainTxt('c-29'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-29">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #993333;">void</span> kmem_cache_destroy<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> kmem_cache <span style="color: #339933;">*</span>s<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; down_write<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>slub_lock<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; s<span style="color: #339933;">-</span>&gt;refcount<span style="color: #339933;">--</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>s<span style="color: #339933;">-</span>&gt;refcount<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; list_del<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>s<span style="color: #339933;">-</span>&gt;list<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; up_write<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>slub_lock<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>kmem_cache_close<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printk<span style="color: #009900;">&#40;</span>KERN_ERR <span style="color: #ff0000;">&quot;SLUB %s: %s called for cache that &quot;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&quot;still has objects.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, s<span style="color: #339933;">-</span>&gt;name, __func__<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dump_stack<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>s<span style="color: #339933;">-</span>&gt;flags <span style="color: #339933;">&amp;</span> SLAB_DESTROY_BY_RCU<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rcu_barrier<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sysfs_slab_remove<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; up_write<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>slub_lock<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>看那两行就足够了，rcu_barrier(); 是用来等待所有的 call_rcu() 回调函数结束，那么，kmem_cache_destroy() 在 SLAB_DESTROY_BY_RCU 的情况很明显就是等待所有 kmem_cache_free() 完成。</p>
<p>和普通的用 kmem_cache_alloc() 分配出来的对象相比，这种内存分配方式提供了更弱的保证，普通的分配可以保证对象不会被释放回 cache 中，而这个仅仅保证它不会被彻底释放，但不保证它会被放回 cache 重新利用，也就是说类型是不变的，即所谓的类型安全。实际上，在此期间它很有可能已经被放回 cache 重新利用了。</p>
<p>正是因为这种保证更弱了，所以在 rcu_read_lock() 并发区内就要多一个检查，检查是否还是之前的那个对象，因为这是类型安全的，所以对它进行同类型的检查是完全合法的。一个很好的例子是 __lock_task_sighand()：</p>
<div class="igBar"><span id="lc-30"><a href="#" onclick="javascript:showPlainTxt('c-30'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-30">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #993333;">struct</span> sighand_struct <span style="color: #339933;">*</span>__lock_task_sighand<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> task_struct <span style="color: #339933;">*</span>tsk,</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> <span style="color: #339933;">*</span>flags<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #009900;">&#123;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333;">struct</span> sighand_struct <span style="color: #339933;">*</span>sighand;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>;;<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local_irq_save<span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>flags<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rcu_read_lock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sighand <span style="color: #339933;">=</span> rcu_dereference<span style="color: #009900;">&#40;</span>tsk<span style="color: #339933;">-</span>&gt;sighand<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>unlikely<span style="color: #009900;">&#40;</span>sighand <span style="color: #339933;">==</span> <span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rcu_read_unlock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local_irq_restore<span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>flags<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">break</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spin_lock<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>sighand<span style="color: #339933;">-</span>&gt;siglock<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>likely<span style="color: #009900;">&#40;</span>sighand <span style="color: #339933;">==</span> tsk<span style="color: #339933;">-</span>&gt;sighand<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rcu_read_unlock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">break</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spin_unlock<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>sighand<span style="color: #339933;">-</span>&gt;siglock<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; rcu_read_unlock<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local_irq_restore<span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span>flags<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> sighand;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>注意，->siglock 是在 ->ctor() 中初始化的，所以刚分配出来的 sighand 的 ->siglock 也是已初始化的。</p>
<p>在此基础上，Linux 内核中还衍生出一个新的哈希链表，hlist_nulls，具体可以参考 Documentation/RCU/rculist_nulls.txt。</p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1934/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>perfbook 读书笔记：livelock</title>
		<link>http://wangcong.org/blog/archives/1930</link>
		<comments>http://wangcong.org/blog/archives/1930#comments</comments>
		<pubDate>Sat, 24 Mar 2012 07:44:17 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1930</guid>
		<description><![CDATA[注：本文以及后面的文章中提到的 perfbook 均是指大牛 Paul E. McKenney 的书，《Is Parallel Programming Hard, And, If So, What Can You Do About It?》，书名太长，故简写之。
最近一直在读这本 perfbook，它算是少... ]]></description>
			<content:encoded><![CDATA[<p>注：本文以及后面的文章中提到的 perfbook 均是指大牛 Paul E. McKenney 的书，《Is Parallel Programming Hard, And, If So, What Can You Do About It?》，书名太长，故简写之。</p>
<p>最近一直在读这本 perfbook，它算是少有的全面而专门介绍 locking 的书，值得每个系统程序员去读。在读的过程中发现有的地方它介绍的并不是很详细，所以就写几篇读书笔记也算是对它的小小补充。</p>
<p>书中 6.1.2 节讲到了 livelock，即所谓的“活锁”，相对于死锁（deadlock）而言。因为上过操作系统课的原因，我估计很多人对 deadlock 并不陌生，但是 livelock 相对不那么熟悉。livelock 无非是饥饿（starvation）的极端情况。饥饿是由竞争引起，所谓竞争（contention）是指尝试获取一个已经被锁住的锁，长时间竞争会导致这些得不到锁的进程饥饿，所以饥饿的极端情况就是多个进程一直在尝试获取某一（几）把锁，但一直都得不到满足。</p>
<p>书中给出的例子很简单，解决方法是给两个进程加上不同延迟，也同时增加了 overhead，所以这个例子并不是很好。我们看一个现实中的例子，Linux 内核中的一个 livelock 的 bug：</p>
<blockquote><p>
commit eaf5f9073533cde21c7121c136f1c3f072d9cf59<br />
Author: Miklos Szeredi<br />
Date:   Tue Jan 10 18:22:25 2012 +0100</p>
<p>fix shrink_dcache_parent() livelock
</p></blockquote>
<p>发生 livelock 的地方是 shrink_dcache_parent()，看其定义：</p>
<div class="igBar"><span id="lc-33"><a href="#" onclick="javascript:showPlainTxt('c-33'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-33">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #993333;">void</span> shrink_dcache_parent<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> dentry <span style="color: #339933;">*</span> parent<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; LIST_HEAD<span style="color: #009900;">&#40;</span>dispose<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333;">int</span> found;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>found <span style="color: #339933;">=</span> select_parent<span style="color: #009900;">&#40;</span>parent, <span style="color: #339933;">&amp;</span>dispose<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #cc66cc;color:#800000;">0</span><span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shrink_dentry_list<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>dispose<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>根据这个 commit 的描述，我们可以发现存在下面这种情况：</p>
<p>1. CPU0 上的进程调用 select_parent(P) 找到了 dentry C，并把它放入 dispose 链表中，返回1；</p>
<p>2. 与此同时，CPU1 上的另一个进程也调用了select_parent(P)，获取了 dentry P 的 ->d_lock；</p>
<p>3. CPU0 上的进程继续调用 shrink_dentry_list()，获取了 dentry C 的 ->d_lock，然后又调用 try_prune_one_dentry(C)，dentry_kill(C)：</p>
<div class="igBar"><span id="lc-34"><a href="#" onclick="javascript:showPlainTxt('c-34'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-34">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">...</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>inode <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>spin_trylock<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>inode<span style="color: #339933;">-</span>&gt;i_lock<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">relock<span style="color: #339933;">:</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spin_unlock<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>dentry<span style="color: #339933;">-</span>&gt;d_lock<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cpu_relax<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">return</span> dentry; <span style="color: #808080; font-style: italic;">/* try again with same dentry */</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>IS_ROOT<span style="color: #009900;">&#40;</span>dentry<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parent <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">NULL</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">else</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parent <span style="color: #339933;">=</span> dentry<span style="color: #339933;">-</span>&gt;d_parent;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>parent <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>spin_trylock<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>parent<span style="color: #339933;">-</span>&gt;d_lock<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>inode<span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spin_unlock<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>inode<span style="color: #339933;">-</span>&gt;i_lock<span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">goto</span> relock;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p></p>
<p>因为另一个进程持有dentry P的->d_lock，所以 dentry_kill() 中 spin_trylock(&#038;parent->d_lock) 失败，转而 spin_unlock(&#038;dentry->d_lock) 并返回；</p>
<p>4. CPU1 上的进程此时仍在调用 select_parent(P)，并找到了 dentry C，锁住了它的->d_lock，放入 dispose 链表并返回1（其实就是重复步骤(1)）；</p>
<p>5. CPU0 上的进程继续 shrink_dentry_list() 中的循环，发现 dispose 链表已经为空，退出循环并返回；</p>
<p>6. CPU1 的进程开始重复步骤(3)；</p>
<p>7. CPU0 的进程开始重复步骤(2)。</p>
<p>Livelock 产生了！</p>
<p>这里问题的关键在于那个 dispose list，如果 dentry C被某个进程加入到 dispose list 中，另外的进程不应该再找到它，所以修复就是加一个标志位 DCACHE_SHRINK_LIST，来标示这个 dentry 有没有被加入。</p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1930/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用宏实现 alignof</title>
		<link>http://wangcong.org/blog/archives/1924</link>
		<comments>http://wangcong.org/blog/archives/1924#comments</comments>
		<pubDate>Tue, 20 Mar 2012 13:29:14 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1924</guid>
		<description><![CDATA[我们知道在C2011标准中引入了 alignof 操作符，但是在 gcc 和 glibc 完全支持 C2011 之前，我们仍然不能使用它。其实我们可以自己用宏实现一个（出自c.l.c）：
#define AlignOf(type_) (offsetof(struct { char c; ... ]]></description>
			<content:encoded><![CDATA[<p>我们知道在C2011标准中引入了 alignof 操作符，但是在 gcc 和 glibc 完全支持 C2011 之前，我们仍然不能使用它。其实我们可以自己用宏实现一个（<a href="https://groups.google.com/forum/?fromgroups#!topic/comp.lang.c/g3f3CHgX864" target="_blank">出自c.l.c</a>）：</p>
<p>#define AlignOf(type_) (offsetof(struct { char c; type_ t; }, t))</p>
<p>它巧妙地把参数指定的类型放入一个结构体中，在此结构体的最前面镶入一个 char 类型，这样该成员在结构体中的偏移就是它对齐的位置。看例子：</p>
<div class="igBar"><span id="lc-36"><a href="#" onclick="javascript:showPlainTxt('c-36'); return false;">PLAIN TEXT</a></span></div>
<div class="syntax_hilite"><span class="langName">C:</span>
<div id="c-36">
<div class="c" style="font-family: monospace;">
<ol>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #339933;">#include &lt;stdlib.h&gt;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #339933;">#include &lt;stdio.h&gt;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #339933;">#include &lt;stddef.h&gt;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #339933;">#define AlignOf(type_) (offsetof(struct { char c; type_ t; }, t)) </span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span></div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #009900;">&#123;</span></div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #993333;">struct</span> foo <span style="color: #009900;">&#123;</span> <span style="color: #993333;">char</span> a; <span style="color: #993333;">int</span> b; <span style="color: #993333;">long</span> c; <span style="color: #009900;">&#125;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #993333;">typedef</span> <span style="color: #993333;">struct</span> foo bar<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;color:#800000;">128</span><span style="color: #009900;">&#93;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sizeof foo: %lu<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> foo<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;AlignOf foo: %lu<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, AlignOf<span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> foo<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sizeof bar: %lu<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>bar<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span style="color: #000066;">printf</span></a><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;AlignOf bar: %lu<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, AlignOf<span style="color: #009900;">&#40;</span>bar<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>;</div>
</li>
<li style="font-weight: normal;color:#3A6A8B;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;">&nbsp; &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;color:#800000;">0</span>;</div>
</li>
<li style="font-weight: bold;color:#26536A;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-style: normal;"><span style="color: #009900;">&#125;</span></div>
</li>
</ol>
</div>
</div>
</div>
<p>
输出：<br />
sizeof foo: 16<br />
AlignOf foo: 8<br />
sizeof bar: 2048<br />
AlignOf bar: 8</p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1924/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>再见，大理！</title>
		<link>http://wangcong.org/blog/archives/1918</link>
		<comments>http://wangcong.org/blog/archives/1918#comments</comments>
		<pubDate>Fri, 16 Mar 2012 14:32:24 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1918</guid>
		<description><![CDATA[
从去年7月初开始，在大理待了半年多了。明天一早就要离开大理了，各种舍不得……这期间因为去新疆离开过一次，可这次不同，下次再回来不知道是何时。
大理是我在国内能找到的最适宜... ]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://wangcong.org/blog/wp-content/uploads/2012/03/IMG_5152.jpg"><img class="size-full wp-image-1921  aligncenter" title="一只叫豆沙的狗，by 太郎" src="http://wangcong.org/blog/wp-content/uploads/2012/03/IMG_5152.jpg" alt="" width="360" height="482" /></a></p>
<p>从去年7月初开始，在大理待了半年多了。明天一早就要离开大理了，各种舍不得……这期间因为去新疆离开过一次，可这次不同，下次再回来不知道是何时。</p>
<p>大理是我在国内能找到的最适宜居住和生活的地方了，没有之一。我理想中的生活有两种：一种是在路上，四处漂泊浪迹天涯；另一种是像在大理这样，白天晒晒太阳，晚上和朋友喝喝茶，打打牌，聊聊天，日子就这么无忧无虑地过着……</p>
<p>希望以后你们哪一位去往大理转，路过人民路超人蔬菜馆，给鸟哥打声招呼；路过人民路养生粥，买碗粥，顺便给老板小月打声招呼；若住在叶榆路阿弟家客栈给老板杨姐问声好！</p>
<p>再见，大理！不知道下次再回来你会变成什么样子！就算是真变成了“失败者乐园，老少边穷文艺中青年扎堆，街上十个人九个神经病，五个飞叶子，三个修禅的，一个摆地摊的”也千万不要变成丽江那样搞一夜情的圣地！不要！</p>
<p>（相册：<a href="http://www.douban.com/photos/album/53193348/">在大理的日子</a>）</p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1918/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>不同人眼中的我</title>
		<link>http://wangcong.org/blog/archives/1901</link>
		<comments>http://wangcong.org/blog/archives/1901#comments</comments>
		<pubDate>Thu, 01 Mar 2012 13:21:07 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1901</guid>
		<description><![CDATA[在别人眼中我是


在我朋友眼中我是

在同行眼中我是

在我女朋友眼中我是

在我父母眼中我是

我以为我是


而实际上我是

终有一天我会是
... ]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>在别人眼中我是</strong></p>
<p style="text-align: center;"><strong><a href="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_1.png"><img class="aligncenter size-full wp-image-1902" title="IT民工" src="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_1.png" alt="" width="287" height="182" /></a><br />
</strong></p>
<p style="text-align: center;"><strong>在我朋友眼中我是</strong></p>
<p style="text-align: center;"><a href="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_5.jpg"><img class="aligncenter size-full wp-image-1910" src="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_5.jpg" alt="" width="357" height="272" /></a></p>
<p style="text-align: center;"><strong>在同行眼中我是</strong></p>
<p style="text-align: center;"><a href="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_3.jpg"><img class="aligncenter size-full wp-image-1903" title="程序猿" src="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_3.jpg" alt="" width="277" height="300" /></a></p>
<p style="text-align: center;"><strong>在我女朋友眼中我是</strong></p>
<p style="text-align: center;"><a href="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_2.jpg"><img class="aligncenter size-full wp-image-1904" title="修电脑的" src="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_2.jpg" alt="" width="323" height="325" /></a></p>
<p style="text-align: center;"><strong>在我父母眼中我是</strong></p>
<p style="text-align: center;"><a href="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_7.jpg"><img class="aligncenter size-full wp-image-1905" src="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_7.jpg" alt="" width="305" height="430" /></a></p>
<p style="text-align: center;"><strong>我以为我是</strong></p>
<p style="text-align: center;"><strong><a href="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_6.jpg"><img class="aligncenter size-full wp-image-1911" src="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_6.jpg" alt="" width="383" height="307" /></a><br />
</strong></p>
<p style="text-align: center;"><strong>而实际上我是</strong></p>
<p style="text-align: center;"><a href="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_8.jpg"><img class="aligncenter size-full wp-image-1907" src="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_8.jpg" alt="" width="363" height="272" /></a></p>
<p style="text-align: center;"><strong>终有一天我会是</strong></p>
<p style="text-align: center;"><a href="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_9.jpg"><img class="aligncenter size-full wp-image-1915" src="http://wangcong.org/blog/wp-content/uploads/2012/03/programmer_9.jpg" alt="" width="378" height="253" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1901/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>怀念适之</title>
		<link>http://wangcong.org/blog/archives/1892</link>
		<comments>http://wangcong.org/blog/archives/1892#comments</comments>
		<pubDate>Fri, 24 Feb 2012 09:06:05 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1892</guid>
		<description><![CDATA[
先生过世已经整整50周年了，可先生充满智慧的话至今仍振聋发聩。无怪乎有人说“二十世纪是鲁迅的世纪，二十一世纪是胡适的世纪”！
1. “容忍比自由更重要 。”
我常常用来自勉。
2. “... ]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><a href="http://wangcong.org/blog/wp-content/uploads/2012/02/hushi.jpg"><img class="aligncenter size-large wp-image-1897" title="胡适之" src="http://wangcong.org/blog/wp-content/uploads/2012/02/hushi-792x1024.jpg" alt="" width="380" height="491" /></a></p>
<p>先生过世已经整整50周年了，可先生充满智慧的话至今仍振聋发聩。无怪乎有人说“二十世纪是鲁迅的世纪，二十一世纪是胡适的世纪”！</p>
<p>1. “<strong>容忍比自由更重要 。</strong>”</p>
<p>我常常用来自勉。</p>
<p>2. “<strong>宁鸣而死，不默而生。</strong>”</p>
<p>适用于沉默的大多数。</p>
<p>3. “<strong>做学问要在不疑处有疑，待人时要在有疑处不疑。</strong>”</p>
<p>适用于方舟子。</p>
<p>4. “<strong>有人告诉你‘牺牲你个人的自由去争取国家的自由’可是我要告诉你‘为个人争自由就是为国家争自由，争取个人的人格就是为社会争人格。真正自由平等的国家不是一群奴才建立起来的。’</strong>”</p>
<p>适用于司马南、胡锡进这种奴才。</p>
<p>5. “<strong>一个肮脏的国家，如果人人讲规则而不是谈道德，最终会变成一个有人味儿正常国家，道德自然逐渐回归；一个干净的国家，如果人人都不讲规则而大谈道德、高尚，天天没事儿就谈道德规范，人人大公无私，最终会堕落成为一个伪君子遍布的肮脏国家。</strong>”</p>
<p>适用于那些天天号召别人学习雷锋的人。</p>
<p>6. “<strong>美国人来了，既有面包也有自由；苏俄来了，只有面包没有自由；他们来了，既没有面包也没有自由。</strong>”</p>
<p>原来先生几十年前就看破了……</p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1892/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>关于 tmpfs</title>
		<link>http://wangcong.org/blog/archives/1887</link>
		<comments>http://wangcong.org/blog/archives/1887#comments</comments>
		<pubDate>Fri, 17 Feb 2012 02:34:12 +0000</pubDate>
		<dc:creator>王 聪</dc:creator>
				<category><![CDATA[Linux Kernel]]></category>

		<guid isPermaLink="false">http://wangcong.org/blog/?p=1887</guid>
		<description><![CDATA["tmpfs" 是 Linux 内核中另一个让人困惑的名字，它的实现是在 mm/shmem.c，"shmem" 猛一看和 "tmpfs" 根本不沾边，虽然我们知道 tmpfs 是基于内存的！我们可以通过看一下 tmpfs 都被用到哪些地方来了解... ]]></description>
			<content:encoded><![CDATA[<p>"tmpfs" 是 Linux 内核中另一个让人困惑的名字，它的实现是在 mm/shmem.c，"shmem" 猛一看和 "tmpfs" 根本不沾边，虽然我们知道 tmpfs 是基于内存的！我们可以通过看一下 tmpfs 都被用到哪些地方来了解它到底为什么叫这个名字。</p>
<p>你的桌面 Linux 系统中基本上都会挂载了 tmpfs：</p>
<p>% grep tmpfs /proc/mounts<br />
devtmpfs /dev devtmpfs rw,seclabel,nosuid,relatime,size=1958956k,nr_inodes=489739,mode=755 0 0<br />
<strong>tmpfs /dev/shm tmpfs rw,seclabel,nosuid,nodev,relatime 0 0</strong><br />
tmpfs /run tmpfs rw,seclabel,nosuid,nodev,relatime,mode=755 0 0<br />
tmpfs /sys/fs/cgroup tmpfs rw,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0<br />
tmpfs /media tmpfs rw,rootcontext=system_u:object_r:mnt_t:s0,seclabel,nosuid,nodev,noexec,relatime,mode=755 0 0</p>
<p>正如<a href="http://wangcong.org/blog/archives/591">这篇文章</a>中提到的，/dev/shm 是 POSIX IPC 用到的，用来实现进程间通信。除了 sem_open(3) 的中 oflag 参数，基本上看不出来和文件有什么相关。</p>
<p>除此之外，另一个用到它的地方是 anonymous shared mapping！</p>
<pre>
mmap_region():

        if (file) {
        //...
        } else if (vm_flags &#038; VM_SHARED) {
                error = shmem_zero_setup(vma);
                if (error)
                        goto free_vma;
        }
</pre>
<p>shmem_zero_setup() 在内核通过 kern_mount() 挂载的（用户不可见的） tmpfs 的根目录中创建了一个"dev/zero"的文件，注意，这里可以重复创建哦，因为内核跳过了类似 may_create() 的检查，而且这个文件本身很特殊，它一开始就是 unlinked 的。所以内核实际上是通过 tmpfs 中的一个文件来实现了匿名的共享映射！到此，你可以看出，tmpfs 这个名字其实名副其实了。</p>
<p>另外，tmpfs 本身可以随意挂载，通过 mount -t tmpfs，你可以在上面进行任意文件操作。所以，内核通过 tmpfs 一套代码把下面三个东西给统一起来了：1. 匿名共享映射；2. POSIX IPC；3. tmpfs 文件操作。Mel Gorman <a href="http://kernel.org/doc/gorman/html/understand/understand015.html">这样解释</a>到：</p>
<blockquote><p>This is a very clean interface that is conceptually easy to understand but it does not help anonymous pages as there is no file backing. To keep this nice interface, Linux creates an artifical file-backing for anonymous pages using a RAM-based filesystem where each VMA is backed by a “file” in this filesystem. Every inode in the filesystem is placed on a linked list called shmem_inodes so that they may always be easily located. This allows the same file-based interface to be used without treating anonymous pages as a special case.</p></blockquote>
<p>之所以用 tmpfs 而不是同样基于内存的 ramfs 是因为：1) tmpfs 文件是可以 swap 的；2) tmpfs 是有大小限制的，不会允许用户无限制使用内存从而导致 OOM。（注：只有当 CONFIG_SHMEM=n 时，tmpfs 才会调用 ramfs 代码。）</p>
]]></content:encoded>
			<wfw:commentRss>http://wangcong.org/blog/archives/1887/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.627 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-05-18 15:34:09 -->

