news 2026/8/11 4:18:49

KiSelectReadyThread函数分析之nt!KiPriorityMask数组和nt!KiFindFirstSetLeft数组的关系

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
KiSelectReadyThread函数分析之nt!KiPriorityMask数组和nt!KiFindFirstSetLeft数组的关系

KiSelectReadyThread函数分析之nt!KiPriorityMask数组和nt!KiFindFirstSetLeft数组的关系

第0部分:


VOID
KiQuantumEnd (
VOID
)
{


} else {
Thread->Quantum = Process->ThreadQuantum;

//
// Compute the new thread priority and attempt to reschedule the
// current processor.
//
// N.B. The new priority will never be greater than the previous
// priority.
//

Thread->Priority = KiComputeNewPriority(Thread, 1);
if (Prcb->NextThread == NULL) {
if ((NewThread =KiSelectReadyThread(Thread->Priority, Prcb)) != NULL) {


第1部分:

FORCEINLINE
PKTHREAD
KiSelectReadyThread (
IN KPRIORITY LowPriority,
IN PKPRCB Prcb
)
{

ULONG HighPriority;
PRLIST_ENTRY ListEntry;
ULONG PrioritySet;
PKTHREAD Thread;

//
// Compute the set of priority levels that should be scanned in an attempt
// to find a thread that can run on the current processor.
//

PrioritySet =KiPriorityMask[LowPriority] & Prcb->ReadySummary;
Thread = NULL;
if (PrioritySet != 0) {
KeFindFirstSetLeftMember(PrioritySet, &HighPriority);

第2部分:

0: kd> x nt!KiPriorityMask
80a05f30 nt!KiPriorityMask = unsigned long []
80a05f30 nt!KiPriorityMask = unsigned long [32]
80a05f30 nt!KiPriorityMask = unsigned long []
0: kd> dx -r1 (*((ntkrnlmp!unsigned long (*)[32])0x80a05f30))
(*((ntkrnlmp!unsigned long (*)[32])0x80a05f30)) [Type: unsigned long [32]]
[0] : 0xffffffff [Type: unsigned long]
[1] : 0xfffffffe [Type: unsigned long]
[2] : 0xfffffffc [Type: unsigned long]
[3] : 0xfffffff8 [Type: unsigned long]
[4] : 0xfffffff0 [Type: unsigned long]
[5] : 0xffffffe0 [Type: unsigned long]
[6] : 0xffffffc0 [Type: unsigned long]
[7] : 0xffffff80 [Type: unsigned long]
[8] : 0xffffff00 [Type: unsigned long]
[9] : 0xfffffe00 [Type: unsigned long]
[10] : 0xfffffc00 [Type: unsigned long]
[11] : 0xfffff800 [Type: unsigned long]
[12] : 0xfffff000 [Type: unsigned long]
[13] : 0xffffe000 [Type: unsigned long]
[14] : 0xffffc000 [Type: unsigned long]
[15] : 0xffff8000 [Type: unsigned long]
[16] : 0xffff0000 [Type: unsigned long]
[17] : 0xfffe0000 [Type: unsigned long]
[18] : 0xfffc0000 [Type: unsigned long]
[19] : 0xfff80000 [Type: unsigned long]
[20] : 0xfff00000 [Type: unsigned long]
[21] : 0xffe00000 [Type: unsigned long]
[22] : 0xffc00000 [Type: unsigned long]
[23] : 0xff800000 [Type: unsigned long]
[24] : 0xff000000 [Type: unsigned long]
[25] : 0xfe000000 [Type: unsigned long]
[26] : 0xfc000000 [Type: unsigned long]
[27] : 0xf8000000 [Type: unsigned long]
[28] : 0xf0000000 [Type: unsigned long]
[29] : 0xe0000000 [Type: unsigned long]
[30] : 0xc0000000 [Type: unsigned long]
[31] : 0x80000000 [Type: unsigned long]


0: kd> dt kTHREAD 8999e620
CSRSRV!KTHREAD

+0x05b Priority : 13 '' 当前线程的优先级为13

[13] : 0xffffe000 [Type: unsigned long]


1111 1111 1111 1111 1110 0000 0000 0000 正好13个0。
从第13位到31位的,都可以选到。优先级为13到优先级31的线程都能被选到。

第3部分:找到一个32位整数的第一个为1的位的位置索引。


KeFindFirstSetLeftMember

#define KeFindFirstSetLeftMember(Set, Member) { \
ULONG _Mask; \
ULONG _Offset = 16; \
if ((_Mask = Set >> 16) == 0) { \
_Offset = 0; \
_Mask = Set; \
} \
if (_Mask >> 8) { \
_Offset += 8; \
} \
*(Member) = KiFindFirstSetLeft[Set >> _Offset] + _Offset; \
}

例子:0x10 00 00 00

0001 0000 0000 0000 0000 0000 0000 0000


第一步判断在高16位还是低16位,右移16位为0说明在低16位,_offset应该设置为0,否则在高16位,不用变化_offset。

if ((_Mask = Set >> 16) == 0) { \ 表示Set变量右移16为赋值给_Mask变量,[Set变量不会有变化]。
_Offset = 0; \
_Mask = Set; \
}

不符合条件,说明在高16位,_Offset = 16,不变。
_Mask=0x10 00


第一步判断选出来的mask中在高8位还是低8位

if (_Mask >> 8) { \
_Offset += 8; \
}

_Mask >> 8后为0x10,_offset=24

0x10
0001 0000

KiFindFirstSetLeft[0x10]=04 0001 0000最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x11]=04 0001 0001最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x12]=04 0001 0010最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x13]=04 0001 0011最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x14]=04 0001 0100最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x15]=04 0001 0101最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x16]=04 0001 0110最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x17]=04 0001 0111最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x18]=04 0001 1000最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x19]=04 0001 1001最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x1a]=04 0001 1010最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x1b]=04 0001 1011最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x1c]=04 0001 1100最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x1d]=04 0001 1101最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x1e]=04 0001 1110最左边第一个为1的位是第四位。
KiFindFirstSetLeft[0x1f]=04 0001 1111最左边第一个为1的位是第四位。

KiFindFirstSetLeft[0x20]=05

0: kd> x nt!KiFindFirstSetLeft
80a05db0 nt!KiFindFirstSetLeft = char [256] ""
0: kd> dx -r1 (*((ntkrnlmp!char (*)[256])0x80a05db0))
(*((ntkrnlmp!char (*)[256])0x80a05db0)) : "" [Type: char [256]]
0: kd> db 80a05db0
80a05db0 00 00 01 01 02 02 02 02-03 03 03 03 03 03 03 03 ................
80a05dc0 04 04 04 04 04 04 04 04-04 04 04 04 04 04 04 04 ................
80a05dd0 05 05 05 05 05 05 05 05-05 05 05 05 05 05 05 05 ................
80a05de0 05 05 05 05 05 05 05 05-05 05 05 05 05 05 05 05 ................
80a05df0 06 06 06 06 06 06 06 06-06 06 06 06 06 06 06 06 ................
80a05e00 06 06 06 06 06 06 06 06-06 06 06 06 06 06 06 06 ................
80a05e10 06 06 06 06 06 06 06 06-06 06 06 06 06 06 06 06 ................
80a05e20 06 06 06 06 06 06 06 06-06 06 06 06 06 06 06 06 ................
0: kd> db 80a05db0+80
80a05e30 07 07 07 07 07 07 07 07-07 07 07 07 07 07 07 07 ................
80a05e40 07 07 07 07 07 07 07 07-07 07 07 07 07 07 07 07 ................
80a05e50 07 07 07 07 07 07 07 07-07 07 07 07 07 07 07 07 ................
80a05e60 07 07 07 07 07 07 07 07-07 07 07 07 07 07 07 07 ................
80a05e70 07 07 07 07 07 07 07 07-07 07 07 07 07 07 07 07 ................
80a05e80 07 07 07 07 07 07 07 07-07 07 07 07 07 07 07 07 ................
80a05e90 07 07 07 07 07 07 07 07-07 07 07 07 07 07 07 07 ................
80a05ea0 07 07 07 07 07 07 07 07-07 07 07 07 07 07 07 07 ................

2个 2个 4个 8个 16个 32个 64个 128个
0 1 2 3 4 5 6 7

最终结果是24+4=28位,正确。

0 0 0 1 0 0 0 0
31位 30位 29位 28位

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/11 13:52:39

基于SpringBoot的大学生科技竞赛管理系统(毕业设计项目源码+文档)

课题摘要在高校科技竞赛规范化、数字化管理需求升级的背景下,传统竞赛管理存在 “报名流程繁琐、评审效率低、数据统计滞后” 的痛点,基于 SpringBoot 构建的大学生科技竞赛管理系统,适配高校教务处、竞赛组委会、参赛师生等多角色&#xff0…

作者头像 李华
网站建设 2026/8/11 4:10:08

基于SpringBoot的动漫分享系统的设计与实现(毕业设计项目源码+文档)

课题摘要 在二次元文化普及、用户动漫分享需求多元化的背景下,传统动漫平台存在 “内容分散、互动性弱、版权管理缺失” 的痛点,基于 SpringBoot 构建的动漫分享系统,适配动漫爱好者、创作者、版权方等角色,打造集资源分享、社区互…

作者头像 李华
网站建设 2026/8/11 3:31:54

震惊!这3家环保服务商靠谱到让你意想不到!

震惊!这3家环保服务商靠谱到让你意想不到! 在水环境治理日益成为社会焦点的今天,选择一家技术扎实、服务可靠的环保服务商,对于企业实现绿色可持续发展至关重要。市场上环保企业众多,但真正能做到以技术创新为驱动、以…

作者头像 李华
网站建设 2026/8/9 13:40:37

微服务网格:Istio 流量管理实战

在微服务架构盛行的当下,随着服务数量的激增,流量管理逐渐成为保障系统稳定性、灵活性的核心挑战。传统的流量控制方案(如服务内部硬编码路由规则)存在耦合度高、扩展性差、运维成本高等问题。而 Istio 作为业界主流的微服务网格&…

作者头像 李华
网站建设 2026/8/9 19:07:44

电脑启动太慢怎么解决?从底层优化到专业电脑加速的5大终极策略

为什么刚买的电脑秒开机,用了一年就变成了“老牛拉破车”?很多CSDN的极客朋友习惯直接重装系统,但对于大多数用户来说,重装意味着环境配置丢失、数据迁移麻烦。 其实,电脑加速并不需要大动干戈。电脑卡顿、启动慢的核…

作者头像 李华
网站建设 2026/8/10 7:05:36

我的新能源车企,如何靠六西格玛培训跑赢质量与成本的终极竞赛?

三年前,我们发布了第一款量产车,发布会很成功。但随之而来的,是让我夜不能寐的数据:早期用户反馈的“小毛病”种类超过100项,售后成本是行业平均值的1.5倍。更可怕的是,电池包的核心部件——电池管理系统&a…

作者头像 李华