linux内核--mb代码学习总结

69 篇文章 1 订阅
32 篇文章 1 订阅

#define set_current_state(state_value) /  
set_mb(current->state, (state_value))  
 
#define set_mb(var, value) do { var = value; mb(); } while (0)  
#define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory") 

语句解释:
1.set_mb(),mb(),barrier()函数追踪到底,就是__asm__ __volatile__("lock; addl $0,0(%%esp)":::"memory"),而这行代码就是内存屏障。
2.__asm__:用于指示编译器在此插入汇编语句
3.volatile/__volatile__:基本可以做到两件事情:
  (1).阻止编译器为了提高速度将一个变量缓存到寄存器内而不写回内存。
  (2).阻止编译器调整操作volatile变量的指令顺序。 
4.memory强制gcc编译器假设RAM所有内存单元均被汇编指令修改,这样cpu中的registers和cache中已缓存的内存单元中的数据将作废。cpu将不得不在需要的时候重新读取内存中的数据。这就阻止了cpu又将registers,cache中的数据用于去优化指令,而避免去访问内存。 
5.lock前缀表示将后面这句汇编语句:"addl $0,0(%%esp)"作为cpu的一个内存屏障。 
6.addl $0,0(%%esp)表示将数值0加到esp寄存器中,而该寄存器指向栈顶的内存单元。加上一个0,esp寄存器的数值依然不变。即这是一条无用的汇编指令。在此利用这条无价值的汇编指令来配合lock指令,在__asm__,__volatile__,memory的作用下,用作cpu的内存屏障。

个人思考:
    volatile关键字来让编译器保证变量计算结果写回到内存之中,而没有用volatile关键字约束的变量的计算结果可能保存在寄存器之中,这种限制完全在我们的代码之中控制;语句中的memory强制gcc编译器假设RAM所有内存单元均被汇编指令修改,cpu将不得不在需要的时候重新读取内存中的数据。这两条关键字保证在多线程的环境下数据的一致性。

遗留问题:
    void aaa()
    {
     int a = 1; //没有使用volatile,
     a++;       //a的计算结果保存在寄存器中的话
     mb();      //寄存器失效
     
     printf("%d/n", a); (问题:a等于几呢)
    }

解决办法:
 把汇编看看,然后编译,看看gcc编译处理的汇编代码。   

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux内核链表是一个非常基础的数据结构,在Linux内核中被广泛使用。Linux内核链表通过指针连接节点,每个节点都包含下一个节点的指针,从而形成链表。 在多核处理器架构下,由于不同核心的缓存可能不一致,当多个核心同时对链表进行修改时,可能会出现数据不一致的情况。为了解决这个问题,Linux内核采用了一种叫做“cache一致性”的技术,即每次修改链表节点时,都需要将该节点所在的缓存行标记为无效,这样其他核心访问该节点时,就会重新从内存中读取数据,保证数据一致性。 而内存屏障则是保证代码执行顺序的关键技术。在多核处理器架构下,由于不同核心的指令可能乱序执行,因此需要内存屏障来确保指令的执行顺序。内存屏障分为读屏障、写屏障和全屏障三种。 读屏障(rmb)用于确保所有先于读屏障的读操作都完成后,才能执行读屏障之后的操作;写屏障(wmb)用于确保所有先于写屏障的写操作都完成后,才能执行写屏障之后的操作;全屏障(mb)则是同时执行读屏障和写屏障的作用。 在Linux内核链表中,内存屏障被广泛应用。例如,在向链表中添加节点时,需要先将新节点的指针指向下一个节点,再将上一个节点的指针指向新节点。此时就需要使用内存屏障来确保指针的修改顺序正确。具体来说,需要在修改新节点指针之后、修改上一个节点指针之前,加入写屏障;在读取新节点指针之前、读取上一个节点指针之后,加入读屏障。这样就可以确保指针的修改顺序正确,从而避免了数据不一致的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值