文章目录



一、禁止 / 开启内核抢占 与 方法保护临界区



如果要使用 " 内存屏障 " , 如 : 禁止 内核 抢占 " 方法保护临界区 " :

首先 , 声明 ​​preempt_disable();​​ 宏 , 表示下面的代码就是 " 方法保护临界区 " 内的代码 , 这些代码禁止 内核 抢占 ;

然后 , 编写 " 方法保护临界区 " 代码 ;

最后 , 使用 ​​preempt_enable();​​ 宏 , 表示之后的代码允许 内核 抢占 ;



​preempt_disable();​​​ 与 ​​preempt_enable();​​​ 之间的代码 , 就是 " 方法保护临界区 " 代码 , 这样可以 阻止编译器重排指令 , 在 禁止 内核抢占 ​​preempt_disable​​​ 与 开启内核抢占 ​​preempt_enable​​ 之间的 " 方法保护临界区 " 代码中 , 添加 " 编译器优化屏障 " ;


声明 " 方法保护临界区 " 代码示例 :

preempt_disable();

// 方法保护临界区

preempt_enable();



二、编译器优化屏障



gcc 编译器优化屏障 参考 ​​【Linux 内核 内存管理】优化内存屏障 ① ( barrier 优化屏障 | 编译器优化 | CPU 执行优化 | 优化屏障源码 barrier 宏 )​​​ 博客 ; " 编译器优化屏障 " 是通过 ​​barrier()​​​ 宏定义 实现的 , gcc 编译器 的 " 优化屏障 " 定义在 ​​linux-5.6.18\include\linux\compiler-gcc.h​​ 源码中 ;

/* Optimization barrier */

/* The "volatile" is due to gcc bugs */
#define barrier() __asm__ __volatile__("": : :"memory")

【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )_Linux内核

源码路径 : linux-5.6.18\include\linux\compiler-gcc.h#20




三、preempt_disable 禁止内核抢占 源码



在 Linux 内核源码 ​​linux-5.6.18\include\linux\preempt.h​​​ 中 , 定义了 ​​preempt_disable​​ 宏 ;



preempt_disable() 宏源码如下 :

#define preempt_disable() \
do { \
preempt_count_inc(); \
barrier(); \
} while (0)

【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )_内存管理_02

源码路径 : linux-5.6.18\include\linux\preempt.h#169




四、preempt_enable 开启内核抢占 源码



在 Linux 内核源码 ​​linux-5.6.18\include\linux\preempt.h​​​ 中 , 定义了 ​​preempt_enable​​ 宏

#ifdef CONFIG_PREEMPTION
#define preempt_enable() \
do { \
barrier(); \
if (unlikely(preempt_count_dec_and_test())) \
__preempt_schedule(); \
} while (0)

【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )_Linux内核_03

源码路径 : linux-5.6.18\include\linux\preempt.h#185