﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Sorry-hardest word</title><link>http://www.cppblog.com/xpyzyf/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 14 Apr 2026 23:08:00 GMT</lastBuildDate><pubDate>Tue, 14 Apr 2026 23:08:00 GMT</pubDate><ttl>60</ttl><item><title>bh, softirq</title><link>http://www.cppblog.com/xpyzyf/archive/2008/10/27/65262.html</link><dc:creator>冷疯子</dc:creator><author>冷疯子</author><pubDate>Mon, 27 Oct 2008 15:22:00 GMT</pubDate><guid>http://www.cppblog.com/xpyzyf/archive/2008/10/27/65262.html</guid><wfw:comment>http://www.cppblog.com/xpyzyf/comments/65262.html</wfw:comment><comments>http://www.cppblog.com/xpyzyf/archive/2008/10/27/65262.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xpyzyf/comments/commentRss/65262.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xpyzyf/services/trackbacks/65262.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 18pt; FONT-FAMILY: 微软雅黑">古老的BH、tasklet、softirq</p>
<ol>
    <li style="MARGIN-RIGHT: 0px">古老的BH：作为一种特殊的tasklet<br><br><span style="FONT-SIZE: 18pt">kernel/softirq.c : static void (*bh_base[32])(void);<br></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="FONT-SIZE: 18pt">struct tasklet_struct bh_task_vec[32];</span> </li>
</ol>
<p style="MARGIN-RIGHT: 0px">在softirq_init中，注册32个bh_task_vec的函数指针为 bh_action;&nbsp;<br>TASKLET_SOFTIRQ :&nbsp;tasklet_action;<br>HI_SOFTIRQ :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tasklet_hi_action;<br>NET_RX_SOFTIRQ :&nbsp;&nbsp; net_rx_action;&nbsp; [net_dev_init]<br>NET_TX_SOFTIRQ:&nbsp;&nbsp;&nbsp; net_tx_action;<br><br>在sched_init中注册 TIMER_BH的处理函数指针为 timer_bh;<br>&nbsp;init_bh(TIMER_BH, timer_bh);<br><br><br>对于数据包的接收发送，标志对应的 NET_RX_SOFTIRQ / NET_TX_SOFTIRQ;<br>对于应用的 tasklet ，标志对应的 TASKLET_SOFTIRQ;<br>对于古老的BH，例如时钟中断，在do_IRQ -&gt; timer_interrupt -&gt; do_timer_interrupt -&gt; do_timer :&nbsp;<br>&nbsp; mark_bh(TIMER_BH) -&gt; tasklet_hi_schedule(bh_task_vec+TIMER_BH)<br>&nbsp; 即将 TIMER_BH 所对应的&nbsp;bh_task_vec 结构体挂接到对应的CPU的 tasklet_hi_vec 链表中，并标志HI_SOFTIRQ。<br>&nbsp;&nbsp;do_softirq时，tasklet_hi_action 遍历对应CPU上的 tasklet_hi_vec 链表中的 tasklet_struct，执行其相应的action，也就是 bh_action 函数。<br>&nbsp;&nbsp;bh_action 函数是个包装体，用于实际调用 bh_base 数组中的函数。对于时钟中断也就是 sched_init 中注册的 timer_bh 函数。<br>&nbsp;&nbsp;<br><br><br><br><br>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;__init&nbsp;softirq_init()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tasklet_init(bh_task_vec</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">i,&nbsp;bh_action,&nbsp;i);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;open_softirq(TASKLET_SOFTIRQ,&nbsp;tasklet_action,&nbsp;NULL);<br>&nbsp;&nbsp;&nbsp;&nbsp;open_softirq(HI_SOFTIRQ,&nbsp;tasklet_hi_action,&nbsp;NULL);<br>}</span></div>
<p style="MARGIN-RIGHT: 0px">&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;tasklet_init(</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;tasklet_struct&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">t,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">func)(unsigned&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">),&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;data)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">state&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;atomic_set(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">func&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;func;<br>&nbsp;&nbsp;&nbsp;&nbsp;t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">data&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;data;<br>}<br></span></div>
<p style="MARGIN-RIGHT: 0px"><br>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;open_softirq(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;nr,&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">action)(</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;softirq_action</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">),&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">data)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;softirq_vec[nr].data&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;data;<br>&nbsp;&nbsp;&nbsp;&nbsp;softirq_vec[nr].action&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;action;<br>}</span></div>
<p style="MARGIN-RIGHT: 0px">&nbsp;<br></p>
<p style="MARGIN-RIGHT: 0px"></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;fastcall&nbsp;__tasklet_hi_schedule(</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;tasklet_struct&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">t)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;cpu&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;smp_processor_id();<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;flags;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;local_irq_save(flags);<br>&nbsp;&nbsp;&nbsp;&nbsp;t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;tasklet_hi_vec[cpu].list;<br>&nbsp;&nbsp;&nbsp;&nbsp;tasklet_hi_vec[cpu].list&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;t;<br>&nbsp;&nbsp;&nbsp;&nbsp;cpu_raise_softirq(cpu,&nbsp;HI_SOFTIRQ);<br>&nbsp;&nbsp;&nbsp;&nbsp;local_irq_restore(flags);<br>}</span></div>
<p style="MARGIN-RIGHT: 0px">&nbsp;</p>
<p style="MARGIN-RIGHT: 0px">&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;tasklet_hi_action(</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;softirq_action&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">a)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;cpu&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;smp_processor_id();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;tasklet_struct&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">list;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;local_irq_disable();<br>&nbsp;&nbsp;&nbsp;&nbsp;list&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;tasklet_hi_vec[cpu].list;<br>&nbsp;&nbsp;&nbsp;&nbsp;tasklet_hi_vec[cpu].list&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;local_irq_enable();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;(list)&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000">&nbsp;tasklet_struct&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">t&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;list;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;list</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(tasklet_trylock(t))&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">atomic_read(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">count))&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">test_and_clear_bit(TASKLET_STATE_SCHED,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">state))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BUG();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">func(t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">data);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tasklet_unlock(t);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">continue</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tasklet_unlock(t);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local_irq_disable();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">next&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;tasklet_hi_vec[cpu].list;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tasklet_hi_vec[cpu].list&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;t;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__cpu_raise_softirq(cpu,&nbsp;HI_SOFTIRQ);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local_irq_enable();<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br></span></div>
<p style="MARGIN-RIGHT: 0px"></p>
<p style="MARGIN-RIGHT: 0px"><br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;bh_action(unsigned&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;nr)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;cpu&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;smp_processor_id();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">spin_trylock(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">global_bh_lock))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">goto</span><span style="COLOR: #000000">&nbsp;resched;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">hardirq_trylock(cpu))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">goto</span><span style="COLOR: #000000">&nbsp;resched_unlock;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(bh_base[nr])<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bh_base[nr]();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;hardirq_endlock(cpu);<br>&nbsp;&nbsp;&nbsp;&nbsp;spin_unlock(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">global_bh_lock);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br><br>resched_unlock:<br>&nbsp;&nbsp;&nbsp;&nbsp;spin_unlock(</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">global_bh_lock);<br>resched:<br>&nbsp;&nbsp;&nbsp;&nbsp;mark_bh(nr);<br>}<br></span></div>
<p style="MARGIN-RIGHT: 0px"><br></p>
<img src ="http://www.cppblog.com/xpyzyf/aggbug/65262.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xpyzyf/" target="_blank">冷疯子</a> 2008-10-27 23:22 <a href="http://www.cppblog.com/xpyzyf/archive/2008/10/27/65262.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>kernel kill process</title><link>http://www.cppblog.com/xpyzyf/archive/2008/10/27/65254.html</link><dc:creator>冷疯子</dc:creator><author>冷疯子</author><pubDate>Mon, 27 Oct 2008 14:52:00 GMT</pubDate><guid>http://www.cppblog.com/xpyzyf/archive/2008/10/27/65254.html</guid><wfw:comment>http://www.cppblog.com/xpyzyf/comments/65254.html</wfw:comment><comments>http://www.cppblog.com/xpyzyf/archive/2008/10/27/65254.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xpyzyf/comments/commentRss/65254.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xpyzyf/services/trackbacks/65254.html</trackback:ping><description><![CDATA[内核杀进程的两个可能：<br><br>
<ol>
    <li>&nbsp;mm/oom_kill.c : oom_kill [有待分析]</li>
    <li>&nbsp;arch/i386/mm/fault.c : do_page_fault</li>
</ol>
<div style="margin-left: 40px;">out_of_memory:<br>
<div style="margin-left: 40px;">
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;printk(</span><span style="color: #000000;">"</span><span style="color: #000000;">VM:&nbsp;killing&nbsp;process&nbsp;%s\n</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;tsk</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">comm);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(error_code&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">4</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_exit(SIGKILL);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">goto</span><span style="color: #000000;">&nbsp;no_context;</span></div>
<br></div>
</div><img src ="http://www.cppblog.com/xpyzyf/aggbug/65254.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xpyzyf/" target="_blank">冷疯子</a> 2008-10-27 22:52 <a href="http://www.cppblog.com/xpyzyf/archive/2008/10/27/65254.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不同结构体中指针的处理</title><link>http://www.cppblog.com/xpyzyf/archive/2008/03/15/44561.html</link><dc:creator>冷疯子</dc:creator><author>冷疯子</author><pubDate>Sat, 15 Mar 2008 06:48:00 GMT</pubDate><guid>http://www.cppblog.com/xpyzyf/archive/2008/03/15/44561.html</guid><wfw:comment>http://www.cppblog.com/xpyzyf/comments/44561.html</wfw:comment><comments>http://www.cppblog.com/xpyzyf/archive/2008/03/15/44561.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xpyzyf/comments/commentRss/44561.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xpyzyf/services/trackbacks/44561.html</trackback:ping><description><![CDATA[<p>Linux:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对于定义的一个结构体，有着对应的一套操作函数(eg：遍历、取头节点之类的)，如果将对应的结构体指针直接放在结构体内，则操作函数的使用只能被动的限制于该结构体；<br>&nbsp;&nbsp;&nbsp;eg：struct page{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int a;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char bb;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct page *prev, *next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;int getcount( struct page *head);&nbsp;&nbsp;&nbsp;该函数将通过head头指针中的next变量来遍历所有结构体，该函数也就只限于page结构体；<br><br>---------------------------------------------------------<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将指针提取出来的方式<br>&nbsp;&nbsp;&nbsp;eg：struct list_head{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct list_head *prev, *next;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct page{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int a;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char bb;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct list_head plist;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>int getcount( struct list_head *head);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;则该函数可以通过head头指针来遍历所有结构体中的list_head成员变量(plist)，而通过plist变量地址，可以取得对应的page结构体地址。因此，别的类型的结构体也可以通过内嵌list_head变量来组成链表，而getcout函数就可以用于所有这种类型的结构体操作<br><br><br>首先取出plist在page结构体中的位置偏移：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#define GETOFFSET(type, member)&nbsp;&nbsp;&nbsp;(unsigned long)(&amp;((type*)0)-&gt;member)<br>再由plist的地址&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;&nbsp;&nbsp;该偏移值<br><br><br>windows下，在有关IOCP中有用到类似的地方：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Calculate the address of the base of the structure given its type, and an<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// address of a field within the structure.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#define CONTAINING_RECORD(address, type, field) ((type *)( \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (PCHAR)(address) - \<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (UINT_PTR)(&amp;((type *)0)-&gt;field)))<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Calculate the byte offset of a field in a structure of type type.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#define FIELD_OFFSET(type, field)&nbsp;&nbsp;&nbsp; ((LONG)(INT_PTR)&amp;(((type *)0)-&gt;field))<br></p>
<img src ="http://www.cppblog.com/xpyzyf/aggbug/44561.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xpyzyf/" target="_blank">冷疯子</a> 2008-03-15 14:48 <a href="http://www.cppblog.com/xpyzyf/archive/2008/03/15/44561.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VS Tips</title><link>http://www.cppblog.com/xpyzyf/archive/2008/03/13/44347.html</link><dc:creator>冷疯子</dc:creator><author>冷疯子</author><pubDate>Thu, 13 Mar 2008 03:30:00 GMT</pubDate><guid>http://www.cppblog.com/xpyzyf/archive/2008/03/13/44347.html</guid><wfw:comment>http://www.cppblog.com/xpyzyf/comments/44347.html</wfw:comment><comments>http://www.cppblog.com/xpyzyf/archive/2008/03/13/44347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xpyzyf/comments/commentRss/44347.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xpyzyf/services/trackbacks/44347.html</trackback:ping><description><![CDATA[1.&nbsp;&nbsp;&nbsp;Watch："err,hr " or "$err,hr" ==&nbsp;&nbsp; Error Lookup<br><br>2.&nbsp;&nbsp;&nbsp;VS8\Common7\Tools\Bin\winnt\Dbmon.exe&nbsp;&nbsp;&nbsp;can watch "OutputDebugString"
<img src ="http://www.cppblog.com/xpyzyf/aggbug/44347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xpyzyf/" target="_blank">冷疯子</a> 2008-03-13 11:30 <a href="http://www.cppblog.com/xpyzyf/archive/2008/03/13/44347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>窝</title><link>http://www.cppblog.com/xpyzyf/archive/2008/03/12/44286.html</link><dc:creator>冷疯子</dc:creator><author>冷疯子</author><pubDate>Wed, 12 Mar 2008 10:03:00 GMT</pubDate><guid>http://www.cppblog.com/xpyzyf/archive/2008/03/12/44286.html</guid><wfw:comment>http://www.cppblog.com/xpyzyf/comments/44286.html</wfw:comment><comments>http://www.cppblog.com/xpyzyf/archive/2008/03/12/44286.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/xpyzyf/comments/commentRss/44286.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/xpyzyf/services/trackbacks/44286.html</trackback:ping><description><![CDATA[<p>想了半天，安个窝<br><font face=#ce_temp_font#><br>记录点平时的疑惑与不解<br><br><br>过去的，无法忘却，只能放在心底<br><br>你会过得比我快乐、幸福<br><br><br>08年<br><br>即将毕业<br><br>也是新的开始<br><br></font></p>
<img src ="http://www.cppblog.com/xpyzyf/aggbug/44286.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/xpyzyf/" target="_blank">冷疯子</a> 2008-03-12 18:03 <a href="http://www.cppblog.com/xpyzyf/archive/2008/03/12/44286.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>