preempt_disable宏
1.相关数据结构及函数如下:
struct thread_info中
{unisgned int preempt_count;//线程抢占引用计数器,为0才能被抢占
}
2.preempt_disable的定义
#define preempt_disable() \
do{ \inc_preempt_count(); \//增加preempt_countbarrier(); \//内存屏障
}while(0)
3.barrier:内存屏障
内存屏障出现因为编译器gcc或现在的处理器常会自作聪明地对指令序列进行一些处理,比如数据缓存,读写指令乱序执行等等。如果优化对象是普通内存,那么一般会提升性能而且不会产生逻辑错误。但如果对 I/O操作进行类似优化很可能造成致命错误。
4. 常见的调度点
1)进程被阻塞时比如申请资源时被阻塞
2)调整参数时 比如通过sched_setscheduler() ,nice()等函数调整进程的调度策略,静态优先级时
3)睡眠进程被唤醒时:比如wake_up唤醒等待队列中的进程时,如果该进程具有更高优先级则会设置当前进程TIF_NEED_RESCHED,如果允许内核态抢占,则会调度一次
4)中断处理完时 如果中断处理过程中设置了TIF_NEED_SCHED标志,中断返回时,不论是要返回内核态还是用户态,都会发生一次抢占。当然,在这也会检查有没有软中断需要处理。
5)执行了preempt_enable()函数。
5. linux下有两种调度方式:
1)显式调度,进程自己因为缺少相应的所申请的资源,显式调用调度器,让出处理器,比如:内核申请的信号阻塞了,自旋锁锁住了。
2)隐式调度,整个linux系统在运行过程中的非显示的调用调度器,这又分两种情况:
A)用户态抢占调度 比如:在系统调用,中断处理,异常处理返回用户态时,该进程的时间片已经用完。
B)内核态抢占调度 比如:当前内核态执行过程中事先没有禁止内核态抢占,有中断产生时,中断处理 又产生了更高级优先进程,那么就会直接抢占前面的内核态执行体。
6. 抢占式内核中有三处地方需要显示的禁用抢占:
1) 操作Per-CPU变量的时候,比如smp_processor_id()就是这一类问题,但一个进程被抢占后重新调度,有可能调度到其他的CPU上去,这时定义的Per-CPU变量就会有问题。下面是一个例子:
2) 必须保护CPU的状态。这类问题是体系结构依赖的。例如,在x86上,进入和退出FPU就是一种临界区,必须在禁抢占的情况下使用。
3) 获得和释放锁必须在一个进程中实现。也就是说一个锁被一个进程持有,也必须在这个进程中释放。
7.禁用/使能抢占的函数主要有:
1)spin_lock()/spin_unlock() spin_lock_irq()/spin_unlock_irq()
2)disable_preempt()/enable_preempt()(禁止或使能内核抢占)调用下面的inc_preempt_count()/dec_preempt_count(),并且加入了memory barrier。
3)inc_preempt_count()/dec_preempt_count()
4)get_cpu()/put_cpu()
preempt_disable宏相关推荐
- 【Linux 内核 内存管理】优化内存屏障 ③ ( 编译器屏障 | 禁止 / 开启内核抢占 与 方法保护临界区 | preempt_disable 禁止内核抢占源码 | 开启内核抢占源码 )
文章目录 一.禁止 / 开启内核抢占 与 方法保护临界区 二.编译器优化屏障 三.preempt_disable 禁止内核抢占 源码 四.preempt_enable 开启内核抢占 源码 一.禁止 / ...
- LINUX内核内存屏障
================= LINUX内核内存屏障 ================= By: David Howells <dhowells@redhat.com> Paul E ...
- C++ 笔记(32)— 预处理、文件包含include、宏替换define、条件包含ifndef、define
C/C++预处理器在源代码编译之前对其进行一些文本性质的操作. 它的主要任务包括删除注释 . 插入 #include 指令包含的文件的内容 . 定义和替换由 #defme 指令定义的符号以及确定代码的 ...
- OpenCV 笔记(04)— OpenCV2 升级到 OpenCV3/CV4 的改动(去掉 CV_前缀、使用新的前缀替换、使用新的命名空间宏)
1. 由于宏名称的变更照成的"未声明的标识符"系列问题 有时候,遇到此类问题加入一句 #include <cv.h> 便可以让 OpenCV3 或者 OpenCV4 也 ...
- TensorRT宏碁自建云(BYOC, BuildYourOwnCloud)上集成
TensorRT宏碁自建云(BYOC, BuildYourOwnCloud)上集成 这个PR增加了对分区.编译和运行TensorRT BYOC目标的支持. Building 有两个新的cmake标志: ...
- 打开word出现“您正试图运行的函数包含有宏或需要宏语言支持的内容。”的解决方法
1.Word选项→加载bai项→管理→转到--,转到→把勾勾都取消→确定即可. 2.工具→宏->安全性→可靠发行商,将下方的选择框中的钩清空,再将宏安全性改为最高. 3.可能是初次安装Offic ...
- C++ #define(宏定义)的使用
C++ 宏定义 #define命令是C++语言中的一个宏定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本. 宏定义的一般形式 #define <宏名& ...
- 宏使用 Tricks
人为地定义一些"无意义"的宏(宏名本身有意义),以起到提升代码程序的可读性. 1. IN/OUT 指定参数用于输入还是输出: #define IN #define OUTvoid ...
- Keil中使用宏编译来定义DEBUG输出
使用宏编译来格式化调试信息,是一个不错的方法,即可以在需要的时候打印出信息,还可以格式化我们所需要的输出. #define DEBUG 1 #if (DEBUG == 1) #define DBG(A ...
- 子程序调用与宏定义的异同_如何用数控系统进行简单的宏程序调用?老师傅告诉你,用G65就行...
什么是简单调用?很多人都不知道吧,如果想要深入操作宏, 就先要学会变量,学会变量之担,再去操作宏,就会变得非常的简单,今天给大家分享如何用G65进行简单的宏程序调用. 用户宏的简单宏调用是指在主程序中 ...
最新文章
- 深入解析Python中的变量和赋值运算符
- Nature:实验室培育的大脑可以拥有意识吗?
- SQL Server中的锁的简单学习
- 10、MySQL存储引擎有哪些?
- 关于datediff(year,开始日期,结束日期)中year格式的说明,特别注意year两边不能加引号,否则报错...
- tensorflow中的log中数字的含义
- 聊聊 computed 影响性能的场景
- 查看未提交事务或sleep session最后执行的sql语句
- 【转】Python学习路线
- SQL Server CTE 递归查询全解
- Java虚拟机------JVM介绍
- 未來用工新趨勢_浅谈2019年灵活用工五大新趋势
- truffle Migration是什么
- XP 多国语言包 .
- Shiro保姆级教程
- 调用百度图像识别api处理网络图片(文字识别)
- Java操作excel自动生成水印背景
- 大咖云集!2018中国计算机大会在杭州举行
- Windows使用阿里云RAM访问控制API实现自建DDNS动态域名解析
- 华为音频编辑服务实时变声,多种音色随意变换