免费注册 查看新帖 |

Chinaunix

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

中断atomic操作 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-04-10 22:18 |只看该作者
原帖由 wojiaohesen 于 2008-4-10 22:08 发表
还是我自己弄懂,现在解释如下,首先说一点,任何一条汇编指令都是在一个不可分割的指令周期内完成的,也就是说,只有在指令周期内的最后一个点才回查询是否有中断发生了。现在说说lock_prefix的作用,首先想一想,因为 ...

恩,lock_prefix那么大一堆实际就是个lock指令而已。
关键问题在第二点上,刚才我又想了一下,越想越想不通。
从atomic_inc_and_test()这个函数的解释上看,它应该完成的功能是:原子加1,判断加1后的值是不是0.
以操作的为全局变量为例,考察中断的情况。假设incl执行完后,值为0了,EFLAGS的ZF=1.这个时候中断来了,EFLAGS被保存到栈上,我们在中断处理函数中修改这个值,使它不为0.当中断返回时,保存下来的EFLAGS被恢复。那么现在的情况就成了:该值不为0,但EFLAGS的ZF=1.再执行sete指令,就造成了不一致的情况。

奇怪,没想明白

论坛徽章:
0
12 [报告]
发表于 2008-04-10 23:34 |只看该作者
原帖由 zx_wing 于 2008-4-10 22:18 发表

恩,lock_prefix那么大一堆实际就是个lock指令而已。
关键问题在第二点上,刚才我又想了一下,越想越想不通。
从atomic_inc_and_test()这个函数的解释上看,它应该完成的功能是:原子加1,判断加1后的值是不 ...

晕,栈上的值被改变了的话,说明程序本身就有问,这个只能靠程序设计保证。

论坛徽章:
0
13 [报告]
发表于 2008-04-10 23:37 |只看该作者
原帖由 epegasus 于 2008-4-10 23:34 发表

晕,栈上的值被改变了的话,说明程序本身就有问,这个只能靠程序设计保证。

不是栈上的值变了,是中断程序修改了变量,但之前保存在栈上的EFLAGS值却没变,恢复后变量的值和EFLAGS中的ZF位就不对应了

论坛徽章:
0
14 [报告]
发表于 2008-04-11 08:31 |只看该作者
0F 94 SETE r/m8 Set byte if equal (ZF=1)
This instruction sets the destination operand to 0 or 1 depending on the settings of the status flags(CF, SF, OF, ZF, and PF) in the EFLAGS register. The destination operand points to a byte register or a byte in memory. The condition code suffix (cc) indicates the condition being tested for.
INTEL Processor manual
也就是说,sete指令只关注eflag中zf的值是否被置,而不管ZF的值为什么被置
而当前这个原子操作只保证在inc后的值为0时对目的操作数置位,至于中断之后如果修改
只能当做是后来发生的事情。??
但是这样的话,原子操作的意义在那里呢?

相通了,这个函数的意义就是在保证对操作数加1后检查其结果是否为0(检查且仅检查加1操作后的值),
那么按照这样的思路,不管后面是否有中断改变这个值,跟这里的检测是没有任何逻辑上的关系的,
所以其调用者得到的结果还是正确的。

[ 本帖最后由 DarkBlueSea 于 2008-4-11 08:51 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2008-04-11 09:37 |只看该作者
是不是这样的:

Lock incl 0x0 后, 即使被中断了, 因为中断要保护FLAGS, 所以, 中断返回后SETE也一定得到前面INC 0X0的正确结果.

0x00000044 <test_atomic+0>:     push   %ebp
0x00000045 <test_atomic+1>:     mov    %esp,%ebp
0x00000047 <test_atomic+3>:     lock incl 0x0
0x0000004e <test_atomic+10>:    sete   %al
0x00000051 <test_atomic+13>:    pop    %ebp
0x00000052 <test_atomic+14>:    ret

论坛徽章:
0
16 [报告]
发表于 2008-04-11 09:44 |只看该作者
也可以说:

原子的操作和被打断没有关系:

1) 被打断的指令(们)也可以是原子的操作.
2) 不被打断的指令(们)也不一定是原子的操作.

论坛徽章:
0
17 [报告]
发表于 2008-04-11 09:46 |只看该作者
原帖由 DarkBlueSea 于 2008-4-11 08:31 发表
0F 94 SETE r/m8 Set byte if equal (ZF=1)
This instruction sets the destination operand to 0 or 1 depending on the settings of the status flags(CF, SF, OF, ZF, and PF) in the EFLAGS register. The ...

是这样的,可以看看所有的atomic操作以及自旋锁的实现。

论坛徽章:
0
18 [报告]
发表于 2008-04-11 10:25 |只看该作者
我想是这样atomic_inc_and_test() 和atomic_add()的意义不一样
atomic_inc_and_test保证的是加一后(即incl后)是否为零,不保证最终操作数是否准确完整的执行了加一操作,故此该函数实现选择了incl指令,至于incl和setcc指令之间的中断是否修改了操作数不是该指令关心的

atomic_add保证的是增加这一操作是否原子的完成,所以该函数的实现在lock后仅跟了一个add指令

论坛徽章:
0
19 [报告]
发表于 2008-04-11 10:28 |只看该作者

回复 #11 zx_wing 的帖子

atomic_inc/dec_and_test 应该是只保证返回前面的操作的结果。

参考iput的实现就可以发现,必须使用spinlock来保证正确地free inode.

论坛徽章:
0
20 [报告]
发表于 2008-04-11 13:09 |只看该作者
看来大家都支持“该函数只保证incl执行后的结果”
请教了一下高手,确实是这样的。
不过还是觉得不太舒服,找了很多材料都没说明这点,包括ULK啊,LDD啊,还有内核文档关于atomic函数的说明等等,作者也没在函数上加注释。这很容易让人用错的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP