在阅读linux 2.6.23内核代码中遇到mb()/rmb()/wmb() 这几个宏,不明白如何使用,

在分析其汇编代码后,大概的了解了这和内存屏障有关,代码如下:

#define X86_FEATURE_XMM2 (0*32+26) /* Streaming SIMD Extensions-2 */

......

#define mb() alternative("lock; addl $0,0(%%esp)", "mfence", X86_FEATURE_XMM2)

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

#ifdef CONFIG_X86_OOSTORE

/* Actually there are no OOO store capable CPUs for now that do SSE,

but make it already an possibility. */

#define wmb() alternative("lock; addl $0,0(%%esp)", "sfence", X86_FEATURE_XMM)

#else

#define wmb() __asm__ __volatile__ ("": : :"memory")

#endif

.......

/*

* Alternative instructions for different CPU types or capabilities.

*

* This allows to use optimized instructions even on generic binary

* kernels.

*

* length of oldinstr must be longer or equal the length of newinstr

* It can be padded with nops as needed.

*

* For non barrier like inlines please define new variants

* without volatile and memory clobber.

*/

#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")

内存屏障主要解决的问题是编译器的优化和CPU的乱序执行。

编译器在优化的时候,生成的汇编指令可能和c语言程序的执行顺序不一样,在需要程序严格按照c语言顺序执行时,需要显式的告诉编译不需要优化,这在linux下是通过barrier()宏完成的,它依靠volidate关键字和memory关键字,前者告诉编译barrier()周围的指令不要被优化,后者作用是告诉编译器汇编代码会使内存里面的值更改,编译器应使用内存里的新值而非寄存器里保存的老值。

同样,CPU执行会通过乱序以提高性能。汇编里的指令不一定是按照我们看到的顺序执行的。linux中通过mb()系列宏来保证执行的顺序。具体做法是通过mfence/lfence指令(它们是奔4后引进的,早期x86没有)以及x86指令中带有串行特性的指令(这样的指令很多,例如linux中实现时用到的lock指令,I/O指令,操作控制寄存器、系统寄存器、调试寄存器的指令、iret指令等等)。简单的说,如果在程序某处插入了mb()/rmb()/wmb()宏,则宏之前的程序保证比宏之后的程序先执行,从而实现串行化。wmb的实现和barrier()类似,是因为在x86平台上,写内存的操作不会被乱序执行。

实际上在RSIC平台上,这些串行工作都有专门的指令由程序员显式的完成,比如在需要的地方调用串行指令,而不像x86上有这么多隐性的带有串行特性指令(例如lock指令)。所以在risc平台下工作的朋友通常对串行化操作理解的容易些。

linux与RMB的关系,linux mb()/rmb()/wmb()相关推荐

  1. 安卓与linux内核版本的关系,Linux内核是如何定义版本的?

    我们平时常用到的Linux系统包括CentOS.Ubuntu等,其实这些都是Linux的发行版本,Linux还有一个版本是内核版本. 内核版本的命名规则 在Linux官网(kernel.org)上,我 ...

  2. Linux 基础篇 -- Linux介绍(怎么读、是什么、创始人、吉祥物、发版本、目前存在的操作系统) Linux和Unix的关系 linux和Windows比较

    文章目录 1. Linux介绍 1.1 Linux怎么读: 1.2 Linux是什么: 1.3 Linux创始人: 1.4 Linux 的吉祥物: 1.5 Linux的主要的发行版: 1.6 目前存在 ...

  3. linux发行版衍生关系,linux发行版-Ubuntu的衍生版本UbuntuKylin初体验(伪)

    本文不符合:中立性,准确性,详情点击此处 前言:野兔计划通过使用linux发行版之一的ubuntukylin一个月时间来学习和体会Linux与windows的差异性和优缺点等.本文不会涉及复杂难懂的代 ...

  4. linux查看映射文件关系,Linux磁盘映射DM

    nmon中看到磁盘如dm-0..dm-4.如果分区时使用了LVM,则一般生成dm-N逻辑卷.它类似于普通分区的一个分区sda0.只不过它利用了Mapper Device机制,在Physical Vol ...

  5. 解释Linux进程的父子关系,Linux进程管理

    静态查看进程--ps 首先可以按照我们上图的命令进行操作,执行结果回出现一大片我们没有接触过的东西,我们下面给大家解释清楚. 上面这张图片介绍的是我们命令中的aux的功能. 这张图我们介绍了执行结果中 ...

  6. linux+模块与设备关系,linux内核设计与实现读书笔记——设备和模块

    一.设备类型 1.块设备 blkdev:以块为单位寻址,支持重定位(数据随机访问),通过块设备节点来访问. 2.字符设备cdev:不可寻址,提供数据流访问,通过字符设备节点访问. 3.网络设备:对网络 ...

  7. I/O函数 writel __raw_writel mb()/rmb()/wmb()

    在邮件列表里讨论了一下writel是如何实现的,这个函数实现在操作系统层,有内存保护的情况下,往一个寄存器或者内存地址写一个数据. 在arch/alpha/kernel/io.c中有 188 void ...

  8. linux查看服务依赖关系,服务管理(1)

    原标题:服务管理(1) 服务管理 什么是服务?在linux系统中,有一些特殊程序,启动后就会持续在后台执行,等待用户或者其他软件调用使用,这种程序我们称为服务. systemV与init system ...

  9. 【Linux 内核】Linux 操作系统结构 ( Linux 内核在操作系统中的层级 | Linux 内核子系统及关系 | 进程调度 | 内存管理 | 虚拟文件系统 | 网络管理 | 进程间通信 )

    文章目录 一.Linux 内核在操作系统中的层级 二.Linux 内核子系统 三.Linux 内核子系统之间的关系 一.Linux 内核在操作系统中的层级 Linux 内核 所在层级 : 整个计算机系 ...

最新文章

  1. js 获取鼠标在画布的位置_javascript求鼠标在canvas画布里的坐标
  2. 吴孟达肝癌逝世:肝被透支的全过程曝光!
  3. (15)Node.js 自定义模块
  4. python爬取拉勾网_python爬虫—爬取拉钩网
  5. 文本输入框的两种div+css的写法
  6. WinForm程序利用sqlhelp连接SQLserver数据库
  7. chrome 窗体高度_js获取浏览器高度 窗口高度 元素尺寸 偏移属性的方法
  8. Vue + Spring Boot 项目实战(十三):使用 Shiro 实现用户信息加密与登录认证
  9. python爬虫selenium-前程无忧
  10. Aapache 启动不了,报错信息:suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
  11. [NOIP模拟赛]棋子游戏
  12. 离线语音芯片-开发指南
  13. Android内存泄漏检测工具使用手册
  14. 中兴u31网管服务器,中兴通讯100G光网络网管解决方案——NetNumenTM U31(BN)
  15. 5个APP,4220个数据,回顾Yura的2018年
  16. [sig18]《使命召唤:二战》的材质光照技术
  17. CreateSpecificCulture('zh-cn')和new CultureInfo('zh-cn')的区别
  18. 光学系统-STORM成像系统
  19. 桐桐的计算(第三章第1课)
  20. Buffer Pool介绍

热门文章

  1. 生活随机 - 下雨天的心情有烦恼有感动有确幸
  2. 一夜爆红吸粉千万“四位超级网红”背后的四大真相是什么呢?
  3. 二本跨考985计算机考研,跨专业考研经验谈:从二本到985的飞跃
  4. oracle怎么算时间,Oracle时间计算
  5. nginx+keepalived+tomcat
  6. 《网络安全》课程教案
  7. tomcat 内存配置优化 Xms Xmx
  8. 简要的可行性分析报告(1)
  9. 下一代降维打击黑科技现身中国
  10. Origin单独改变一个柱状图的颜色