请问大牛: rmb()这个函数是啥意思?

xp4105 2007-11-16 05:43:46
#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)


#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)


原代码里是这么定义的,没有看懂


谢谢拉
...全文
464 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
UltraBejing 2008-05-01
  • 打赏
  • 举报
回复
关注 接分
xp4105 2007-11-27
  • 打赏
  • 举报
回复
谢谢 tb01412 ,呵呵

也许简单的“谢谢”2个字不足以代表对你的感谢,

我只想说:想请你吃饭,呵呵 。
rzsheng 2007-11-23
  • 打赏
  • 举报
回复
人民币呀,()里面写数字,随你写呀,给你一个聚宝盆了,呵呵
tb01412 2007-11-23
  • 打赏
  • 举报
回复
最先实现读屏障的是asm volitale ("lock; addl $0,0(%%esp)":::"memory")这条语句;
对于新的CPU,可以换成asm volitale ("lfence":::)语句;
至于两个段altinstr_replacement与altinstructions,需要结合内核其它部分内容,我这里也只能猜测,估计是动态侦测的X86哪个系列,如果是P4以下的没有XMM2的CPU,就执行altinstructions再结合asm volitale ("lock; addl $0,0(%%esp)":::"memory")这条语句,否则就执行altinstr_replacement段内的内容.
tb01412 2007-11-23
  • 打赏
  • 举报
回复
唉,LZ不晓得去查资料吗???不晓得你是懒呢?还是不晓得如何查资料?

#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */
#define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
#define alternative(oldinstr, newinstr, feature) \
asm volatile ("661:\n\t" oldinstr "\n662:\n" \
".section .altinstructions,\"a\"\n" \
" .align 4\n" \
" .long 661b\n" /* label */ \
" .long 663f\n" /* new instruction */ \
" .byte %c0\n" /* feature bit */ \
" .byte 662b-661b\n" /* sourcelen */ \
" .byte 664f-663f\n" /* replacementlen */ \
".previous\n" \
".section .altinstr_replacement,\"ax\"\n" \
"663:\n\t" newinstr "\n664:\n" /* replacement */\
".previous" :: "i" (feature) : "memory")

==============================================================================
做一下宏替换得到:
asm volatile ("661:\n\t"
"lock; addl $0,0(%%esp)\n"
"662:\n" \
".section .altinstructions,\"a\"\n" \
" .align 4\n" \
" .long 661b\n" /* label */ \
" .long 663f\n" /* new instruction */ \
" .byte %c0\n" /* feature bit */ \
" .byte 662b-661b\n" /* sourcelen */ \
" .byte 664f-663f\n" /* replacementlen */ \
".previous\n" \
".section .altinstr_replacement,\"ax\"\n" \
"663:\n\t"
"lfence\n"
"664:\n" /* replacement */\
".previous" :: "i" (0*32+26) : "memory")
====================================================================
lock:锁住总线,以阻至另外的CPU对内存进行访问
addl $0,0(%%esp):%%esp表示的是在内嵌汇编语句中代表esp寄存器,这一条语句不用我解释了吧?
.section .altinstructions "a":定义段,段属性为a,后面的类似,a表示可重定位,x表示可执行,至于什么是段,什么是可重定位,如果你不懂的话,再去补习一下,一时半会儿也说不清楚的
.align 4:按四字节对齐
.long 661b:存储一个long型的数据,值为661b,后面的类似,不再详述
"663:\n\t" :表示标号,其它的类似
volatile:防止编译器优化
".previous" :: "i" (0*32+26) : "memory"):内联汇编传参数的方式,"i"表示输入立即数,其值为0*32+26,"memory"表示这段汇编会改变内存,让CPU刷新所有的cache
lfence:刷新CPU预取的指令,在lfence指令前的读操作当必须在lfence指令后的读操作前完成
.previous:将.section和.previous中间的代码汇编到各自定义的段中,然后跳回去,将这之后的的代码汇编到上一个section中
" .byte %c0\n":就是将那个立即数(0*32+26)放在这个地方

这里面真正要执行的汇编其实就三句:
lock
addl $0,0(%%esp)
lfence
其它都是辅助性的.说了这么多,LZ自己去理解这段汇编吧......


hkkhyh 2007-11-22
  • 打赏
  • 举报
回复
不让编译器进行优化读操作,至于那几行汇编小弟不懂~~,没人回答吗?
xp4105 2007-11-19
  • 打赏
  • 举报
回复
穷啊


没有分拉 呵呵
tb01412 2007-11-19
  • 打赏
  • 举报
回复
至于barrier,在LINUX设备驱动程序中有讲到,至于那几段汇编,看文档吧,还有就是把这些宏全部写出来才晓得是啥子意思啊,我只知道lock是锁住总线,然后就应该是刷新内存了,也就是让cache失效,前面应该还有阻止编译器优化的作用。
stormful 2007-11-19
  • 打赏
  • 举报
回复
技术论坛,搞什么分。现在每况愈下。
IlikeEnglish 2007-11-19
  • 打赏
  • 举报
回复
人民币
hefuhua 2007-11-19
  • 打赏
  • 举报
回复
bs 0 分贴 ^_^

知道你这小子没分了,哈哈
stormful 2007-11-16
  • 打赏
  • 举报
回复
Linux kernel比较喜欢gcc方言,查下GCC文档吧。没那个爱好的,知道是读barrier就行了。

4,436

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧