⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux设备驱动程序学习(3)-并发和竞态 - linux设备驱动程序 - tekkaman ninja.htm

📁 Linux设备驱动程序学习(3)-并发和竞态 - Linux设备驱动程序.rar
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                                style="COLOR: rgb(255,153,0)">/* 等待completion 
                                */</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                complete<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                completion <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>c<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/*唤醒一个等待completion的线程*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                complete_all<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                completion <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>c<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/*唤醒所有等待completion的线程*/</SPAN><BR><BR><SPAN 
                                style="COLOR: rgb(255,153,0)">/*如果未使用completion_all,completion可重复使用;否则必须使用以下函数重新初始化completion*/</SPAN><BR>INIT_COMPLETION<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                completion c<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/*快速重新初始化completion*/</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE><BR></DIV>
                              <DIV>&nbsp;completion的典型应用是模块退出时的内核线程终止。在这种远行中,某些驱动程序的内部工作有一个内核线程在while(1)循环中完成。当内核准备清楚该模块时,exit函数会告诉该线程退出并等待completion。为此内核包含了用于这种线程的一个特殊函数:<BR>
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                complete_and_exit<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN><SPAN 
                                style="COLOR: rgb(0,0,255)">struct</SPAN> 
                                completion <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>c<SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN 
                                style="COLOR: rgb(0,0,255)">long</SPAN> 
                                retval<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN></SPAN></CODE></P></TD></TR></TBODY></TABLE><BR></DIV>
                              <DIV>
                              <HR id=null>
                              </DIV>
                              <DIV><FONT color=#0000ff 
                              size=4><STRONG>三、自旋锁</STRONG></FONT></DIV>
                              <DIV><FONT color=#ff0000 
                              size=4>其实上面介绍的几种信号量和互斥机制,其底层源码都是使用自旋锁,可以理解为自旋锁的再包装。</FONT>所以从这里就可以理解为什么自旋锁通常可以提供比信号量更高的性能。<BR>自旋锁是一个互斥设备,他只能会两个值:“锁定”和“解锁”。它通常实现为某个整数之中的单个位。<BR>“测试并设置”的操作必须以原子方式完成。<BR>任何时候,只要内核代码拥有自旋锁,在相关CPU上的抢占就会被禁止。</DIV>
                              <DIV><FONT 
                              color=#0000ff>适用于自旋锁的核心规则:<BR>(1)任何拥有自旋锁的代码都必须使原子的,除服务中断外(某些情况下也不能放弃CPU,如中断服务也要获得自旋锁。为了避免这种锁陷阱,需要在拥有自旋锁时禁止中断),不能放弃CPU(如休眠,休眠可发生在许多无法预期的地方)。否则CPU将有可能永远自旋下去(死机)。<BR>(2)拥有自旋锁的时间越短越好。</FONT></DIV>
                              <DIV>自旋锁原语所需包含的文件是&lt;linux/spinlock.h&gt; 
                              ,以下是自旋锁的内核API:&nbsp; 
                              <TABLE style="BORDER-COLLAPSE: collapse" 
                              borderColor=#999999 cellSpacing=0 cellPadding=0 
                              width="95%" bgColor=#f1f1f1 border=1>
                                <TBODY>
                                <TR>
                                <TD>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><FONT 
                                face=新宋体>spinlock_t my_lock <SPAN 
                                style="COLOR: rgb(0,0,204)">=</SPAN> 
                                SPIN_LOCK_UNLOCKED<SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/* 
                                编译时初始化spinlock*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                spin_lock_init<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/* 
                                运行时初始化spinlock*/</SPAN><BR><BR><SPAN 
                                style="COLOR: rgb(255,153,0)">/* 
                                所有spinlock等待本质上是不可中断的,一旦调用spin_lock,在获得锁之前一直处于自旋状态*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                spin_lock<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/* 
                                获得spinlock*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                spin_lock_irqsave<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN 
                                style="COLOR: rgb(0,0,255)">unsigned</SPAN> 
                                <SPAN style="COLOR: rgb(0,0,255)">long</SPAN> 
                                flags<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/* 
                                获得spinlock,禁止本地cpu中断,保存中断标志于flags*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                spin_lock_irq<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/* 
                                获得spinlock,禁止本地cpu中断*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                spin_lock_bh<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(255,153,0)">/* 
                                获得spinlock,禁止软件中断,保持硬件中断打开*/</SPAN><BR><BR><SPAN 
                                style="COLOR: rgb(255,153,0)">/* 
                                以下是对应的锁释放函数*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                spin_unlock<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                spin_unlock_irqrestore<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">,</SPAN> <SPAN 
                                style="COLOR: rgb(0,0,255)">unsigned</SPAN> 
                                <SPAN style="COLOR: rgb(0,0,255)">long</SPAN> 
                                flags<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                spin_unlock_irq<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">void</SPAN> 
                                spin_unlock_bh<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><BR><SPAN 
                                style="COLOR: rgb(255,153,0)">/* 
                                以下非阻塞自旋锁函数,成功获得,返回非零值;否则返回零*/</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">int</SPAN> 
                                spin_trylock<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN><BR><SPAN 
                                style="COLOR: rgb(0,0,255)">int</SPAN> 
                                spin_trylock_bh<SPAN 
                                style="COLOR: rgb(0,0,204)">(</SPAN>spinlock_t 
                                <SPAN 
                                style="COLOR: rgb(0,0,204)">*</SPAN>lock<SPAN 
                                style="COLOR: rgb(0,0,204)">)</SPAN><SPAN 
                                style="COLOR: rgb(0,0,204)">;</SPAN></FONT></SPAN></CODE></P>
                                <P 
                                style="MARGIN: 5px; LINE-HEIGHT: 150%"><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"><FONT face=新宋体><SPAN 
                                style="COLOR: rgb(0,0,204)"></SPAN><BR><SPAN 
                                style="COLOR: rgb(255,153,0)">/*新内核的&lt;linux/spinlock.h&gt;包含了更多函数*/</SPAN></FONT></SPAN></CODE><CODE><SPAN 
                                style="COLOR: rgb(0,0,0)"></SPAN></CODE></P></TD></TR></TBODY></TABLE></DIV>
                              <DIV>&nbsp;</DIV>
                              <DIV><FONT face=新宋体 color=#0000ff size=4>读取者<SPAN 
                              st

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -