首页
社区
课程
招聘
CLI 和 DISPATCH_LEVEL 级别有什么区别?
发表于: 2014-11-7 13:16 5012

CLI 和 DISPATCH_LEVEL 级别有什么区别?

2014-11-7 13:16
5012
书上说DISPATCH_LEVEL下,不会发生普通线程的切换
而cli是禁止CPU时间片, 屏蔽中断, 这是不是也禁止了线程的切换,
那这两个有什么区别?
我看别人的驱动源码在提升IQRL后, 又用了cli...

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 102
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
不太懂, 试着说下?
CLI是关中断, 所有的中断都不会得到IRQ的处理, 因此PIT发出的时间中断也会被屏蔽,
没办法触发时间中断也就没法计算线程的时间片, 所以线程的时间片不会被消耗, 也就不会被切换了?
至于DISPATCH_LEVEL...不知道是什么.
以上仅仅是猜测.
2014-11-7 13:33
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
DISPATCH_LEVEL是windows设置的IRQL级别,是一种软件级别,由其内部调度程序使用,当一个线程处于这个级别,调度程序就不对其进行切换,结果就是该线程独占处理器,直至其降低 IRQL。
而一个 线程处于 DISPATCH_LEVEL级别时,cpu硬件是会产生硬件中断的,这些硬件中断由外部硬件触发,比如定时器,或者磁盘控制器啊,或者其他外设等等,产生硬件中断,cpu会检查标志寄存器的EFLAGS的中断标志,如果是打开的,就会跳转去执行中断处理程序,这个硬中断也是有特权级别的,其高于DISPATCH_LEVEL,cpu根本就不识别passive_level,DISPATCH_LEVEL等等 IRQL,实际DISPATCH_LEVEL在cpu硬件看来,就是运行在一种普通的运行方式而已,所以任何外部中断都会中断DISPATCH_LEVEL的运行。这个时候cli标志关闭了外部中断,那么外部中断也被屏蔽,无法运行了。
2014-11-7 14:06
0
雪    币: 608
活跃值: (643)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
cli是用于屏蔽可屏蔽的外部中断用的,让CPU不去响应外部中断,属于硬件上的屏蔽
DISPATCH_LEVEL是软件中断,解释同楼上
2014-11-7 14:16
0
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
5
HIGH_LEVEL吧~
2014-11-7 14:21
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我记得线程的切换是基于时间片的切换, 是不是直接用cli标志关闭了外部中断, 也不能切换线程, 那是不是说cli的效果包含了DISPATCH_LEVEL效果?
2014-11-7 14:49
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我记得线程的切换是基于时间片的切换, 是不是直接用cli标志关闭了外部中断, 也不能切换线程, 那是不是说cli的效果包含了DISPATCH_LEVEL效果?
2014-11-7 14:50
0
雪    币: 478
活跃值: (50)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
仅仅提升到dispatch,代码可能被硬件中断给打断。
只cli,线程会收到调度的影响,也可能会被打断。不知道说的对不对
2014-11-7 15:16
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
DISPATCH_LEVEL是驱动程序编写中要考虑的IRQL的有关问题,因为很多系统调用在DISPATCH_LEVEL级别不能使用,而且DISPATCH_LEVEL级别不能使用分页内存,所以一般情况下不要提升到DISPATCH_LEVEL,但是有些情况要提升到DISPATCH_LEVEL是防止某一段代码还没执行完就被调度程序切换,而这一断代码是不可中断的需要完全执行完才行,所以要提升到DISPATCH_LEVEL.
这里所说的需要完全执行完,而不被打断的程序,其功能可能是同步处理某些数据,等等,如果其处理某些数据的时候,被中断了,切换到其他线程,又改变了上个线程要处理的数据,那么就会出错。所以使用DISPATCH_LEVEL是防止同类别的其他线程再不同步的情况下改动本线程需要完全控制的资源。而与cpu的硬件中断无太大关系,cpu硬件中断执行以后,又原地返回,对这个线程来说,就相当于“暂停一下”,继续执行。
而cli则是更加关闭了外部中断。那什么情况需要cli关闭外部中断呢?那是因为外部硬件中断的时候,会有硬件机制切换堆栈,再比如实模式切换到保护模式的时候,会有cr3寄存器的切换,寻址方式从实模式切换到分页模式等等,涉及到硬件系统的功能,为了防止硬件系统状态的切换不被打断,所以强行cli关闭外部中断。所以一般只有再这些时候才使用cli关闭中断,一般的线程同步的时候,与cpu硬件状态的切换关系不大的时候,不需要cli关闭中断。
为什么不要经常性的cli关闭中断,或者cli关闭中断的时间不能太久呢?因为那样,会有许多的外部中断不断产生,比如键盘,比如鼠标,定时器,而cli关闭的外部中断,就会丢失这些中断,造成键盘,鼠标按键都没有任何反应。所以,一定要在极少的情况下使用cli,而且cli以后要尽可能快的使用sti重新打开中断。
至于一般的线程同步功能,提升到DISPATCH_LEVEL即可,不需要cli,因为即使有外部中断,让外部中断进行处理即可,你的DISPATCH_LEVEL的线程仅仅只是打个盹而已,继续执行。
2014-11-7 15:38
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢, 那么在内核中需要改写某个地址的内容时, 是需要cli还是提升DISPATCH_LEVEL?
2014-11-8 13:26
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
一般情况下,不需要使用cli,提升到DISPATCH_LEVEL即可,如果不是独占的内存的话,不用提升IRQL也没关系,你自己看看你的线程逻辑,假设在改写某个地址的时候,被改写了一半就被切换出去,如果发生这种情况,会不会影响执行结果,造成错误,如果不会出错,那么不用提升IRQL都可以。
2014-11-10 09:08
0
雪    币: 55
活跃值: (348)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
你3楼和9楼的前面部分都阐述得很好,但是对于提升IRQL(比如至DISPATCH_LEVEL)方式或cli来保证线程同步的联系阐述我有不同看法:要考虑多处理器问题,IRQL提升至DISPATCH_LEVEL或更粗暴的cli只能保证当前CPU不会切换到另外的线程,但不能保证其它CPU调度有竞争资源访问的相关线程来执行。所以线程同步需要通过操作系统提供的标准同步例程来实现,并不一定半身IRQL的提高或CLI执行,尽管这些同步例程内部实现上可能会提高IRQL或执行CLI,但那对调用线程而言却是透明的。
2014-11-18 20:39
0
雪    币: 86
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
不错,学习了
2014-11-19 11:42
0
游客
登录 | 注册 方可回帖
返回
//