忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT HPC论坛 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
12
最近访问板块 发新帖
楼主: biger410

preempt_disable的问题 [复制链接]

论坛徽章:
0
发表于 2013-04-14 10:43 |显示全部楼层
回复 10# chishanmingshen
应该说我原来的理解有误,barrier函数本身只实现了编译器内存屏障,rmb、wmb 、mb函数则既保证了cpu指令顺序执行也保证了编译器不优化,是barrier函数的超集
其实现在各个架构对这几个函数都已经做了实现,如x86使用的是mfence、lfence、sfence指令
  1. #ifdef CONFIG_X86_32
  2. /*
  3. * Some non-Intel clones support out of order store. wmb() ceases to be a
  4. * nop for these.
  5. */
  6. #define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)
  7. #define rmb() alternative("lock; addl $0,0(%%esp)", "lfence", X86_FEATURE_XMM2)
  8. #define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)
  9. #else
  10. #define mb()         asm volatile("mfence":::"memory")
  11. #define rmb()        asm volatile("lfence":::"memory")
  12. #define wmb()        asm volatile("sfence" ::: "memory")
  13. #endif
复制代码
arm使用的是isb、dsb、dmb指令

  1. #ifdef CONFIG_ARCH_HAS_BARRIERS
  2. #include <mach/barriers.h>
  3. #elif __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
  4. #define mb()                do { dsb(); outer_sync(); } while (0)
  5. #define rmb()                dmb()
  6. #define wmb()                mb()
  7. #else
  8. #define mb()        do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
  9. #define rmb()        do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
  10. #define wmb()        do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
  11. #endif
复制代码
  1. #if __LINUX_ARM_ARCH__ >= 7
  2. #define isb() __asm__ __volatile__ ("isb" : : : "memory")
  3. #define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
  4. #define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
复制代码
楼主的原意应该是为什么不在preempt_enable时使用mb()函数,而使用只保证了编译器不优化的函数barrier()函数,对于这一点,我现在也没想明白。。。
   

论坛徽章:
0
发表于 2013-04-26 10:56 |显示全部楼层
回复 9# junnyg

我说的是硬件中断唤醒一个高级任务,不是你所理解的中断处理。
把我的分析再多看几遍,你的疑问也会解决。
   

论坛徽章:
17
水瓶座
日期:2013-08-29 12:09:27子鼠
日期:2014-10-13 11:21:18丑牛
日期:2014-07-24 12:44:41寅虎
日期:2014-04-16 16:15:33寅虎
日期:2014-03-12 09:28:43摩羯座
日期:2014-03-06 13:22:04技术图书徽章
日期:2014-03-06 11:34:50天蝎座
日期:2014-01-09 11:31:44寅虎
日期:2013-12-27 17:01:44双子座
日期:2013-12-27 12:32:29双子座
日期:2013-12-25 09:03:33丑牛
日期:2013-12-24 16:18:44
发表于 2013-04-26 12:52 |显示全部楼层
本帖最后由 asuka2001 于 2013-04-26 12:53 编辑

回复 11# junnyg
楼主的原意应该是为什么不在preempt_enable时使用mb()函数,而使用只保证了编译器不优化的函数barrier()函数,对于这一点,我现在也没想明白。。。


mb()系列的用途是保证多CPU访问数据时的数据一致性,这个preempt_count的访问只发生在本地CPU,所以只需要防止编译器指令重排。


   

论坛徽章:
0
发表于 2013-04-26 22:49 |显示全部楼层
回复 1# biger410

单处理器,即使有乱序执行,也必须保证在软件看来是program order的。否则,c语言教程上的绝大多数代码示例都不正确了。
对于多处理器,没有这个保证,所有有时需要mb。

preempt_disable修改的preempt_count, 一般放在thread_info结构里,但逻辑上是一个per cpu的变量,只有: 下一次schedule成功发生之前,本cpu的中断,软中断,或当前线程才会访问它。软件是看不到本处理器上乱序的效果的。无须额外处理。
   
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP