免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: zlinux123456
打印 上一主题 下一主题

使用自旋锁的问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-09-02 15:50 |只看该作者
原帖由 folklore 于 2007-9-2 10:07 发表



现在说明为什么错:
1.spin=1。锁有效

spin_lock_irq(&spin);  //这句话,得到spinLock,并使得spin为0,并得到持有cpu,return 1,成功
相当于

asm/
  mov eax,0
  lock xchg eax,spin  //交换e ...

我认为不太对,在我的想法中楼主这样写是应该死锁的。因为从流程上来说最后都应该调用到__raw_spin_lock(),从它的实现上来看的话第二次调用应该陷入自旋。我说一下流程,大家看看有什么地方不对:

  1. static inline void __raw_spin_lock(raw_spinlock_t *lock)
  2. {
  3.         asm volatile("\n1:\t"
  4.                      LOCK_PREFIX " ; decb %0\n\t"
  5.                      "jns 3f\n"
  6.                      "2:\t"
  7.                      "rep;nop\n\t"
  8.                      "cmpb $0,%0\n\t"
  9.                      "jle 2b\n\t"
  10.                      "jmp 1b\n"
  11.                      "3:\n\t"
  12.                      : "+m" (lock->slock) : : "memory");
  13. }
复制代码

这里,传入的lock->slock被 SPIN_LOCK_UNLOCKED初始化为1, 第一次调用的时候:(用c来表示汇编流程)

  1. if ( --lock->slock >= 0 )
  2.     goto get;
  3. while (1)
  4. {
  5.    …… 自旋判断
  6. }

  7. get:
  8.     return;
复制代码

第一次调用后lock->slock的值变为0,第二次调用的时候就应该减为-1陷入自旋成为死锁。其实lz这种写法就是典型的递归调用自旋锁的情况,按理也该死锁。星期一做实验看看。

论坛徽章:
0
12 [报告]
发表于 2007-09-04 21:53 |只看该作者
十分感谢!我明天验证一下了,

如果我访问一个公用的全局变量,在进程上下文:如下操作(我不对spin_lock_irq判断),

spin_lock_irq(&spin);  

.....//将要访问的全局变量
spin_unlock_irq(&spin);  

然后中断例程下半部份中同样要访问这个全局变量:操作如下(我不对spin_lock_irq判断),:

spin_lock_irq(&spin);  

.....//将要访问的全局变量

spin_unlock_irq(&spin);  

这样能够达到在某个时刻只有一个访问这个全局变量吗(也就是获得锁的处理不会被打断,等释放了锁才会执行其它的)?

论坛徽章:
0
13 [报告]
发表于 2007-09-04 22:12 |只看该作者
原帖由 zlinux123456 于 2007-9-4 21:53 发表
十分感谢!我明天验证一下了,

如果我访问一个公用的全局变量,在进程上下文:如下操作(我不对spin_lock_irq判断),

spin_lock_irq(&spin);  

.....//将要访问的全局变量
spin_unlock_irq(&spi ...

在中断处理程序中使用自旋锁应该用
spin_lock_irqsave()和spin_lock_irqrestore()最为安全,它不管中断当前是否关闭都可以在解锁时恢复到加锁前的状态。
而spin_unlock_irq会无条件的打开中断,这是不安全的。
我认为这样使用可以保证对全局变量的独占操作,当然前提是你要保证你的程序中其它地方在访问该全局变量的时候都主动申请锁

论坛徽章:
0
14 [报告]
发表于 2007-09-05 01:45 |只看该作者
在单cpu且关了内核抢占机制的话,spin_lock_irq所做的只是关中断了而已.因为在这种情况下,运行在内核态的进程是不可能被抢占的,所以对临界资源的访问也是安全的。

所以楼主那个是完全正常的。

[ 本帖最后由 罗格纳 于 2007-9-5 01:51 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2007-09-05 12:15 |只看该作者
原帖由 罗格纳 于 2007-9-5 01:45 发表
在单cpu且关了内核抢占机制的话,spin_lock_irq所做的只是关中断了而已.因为在这种情况下,运行在内核态的进程是不可能被抢占的,所以对临界资源的访问也是安全的。

所以楼主那个是完全正常的。

单cpu为什么要使用自旋锁?
事实上在不配置SMP选项编译内核时,自旋锁会从内核中移除。

论坛徽章:
0
16 [报告]
发表于 2007-09-05 15:12 |只看该作者
原帖由 zx_wing 于 2007-9-5 12:15 发表

单cpu为什么要使用自旋锁?
事实上在不配置SMP选项编译内核时,自旋锁会从内核中移除。


这个你要问楼主了。。。。。

论坛徽章:
0
17 [报告]
发表于 2007-09-05 21:09 |只看该作者
你错了,单cup中,如果中断中使用全局变量,也要加锁啊,它会打断进程上下文的啊!!!!

论坛徽章:
0
18 [报告]
发表于 2007-09-05 22:53 |只看该作者
原帖由 zlinux123456 于 2007-9-5 21:09 发表
你错了,单cup中,如果中断中使用全局变量,也要加锁啊,它会打断进程上下文的啊!!!!

所以要用spin_lock_irq,但作用退化为只是开关中断,并没有锁机制。故可以嵌套调用而不会死锁。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP