windows内核原理分析之DPC函数的执行(2)
来源:互联网 发布:生刷枪软件下载 编辑:程序博客网 时间:2024/05/20 13:04
windows内核原理分析之DPC函数的执行(2)
需要执行DPC函数时,就通过KeInsertQueueDpc()提出DPC请求,就是把具体的KDPC结构挂入PRCB中的DPC请求队列,这常常是由中断服务程序完成的。
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { ...... ASSERT_DPC(Dpc); /* Check IRQL and Raise it to HIGH_LEVEL */ KeRaiseIrql(HIGH_LEVEL, &OldIrql); CurrentPrcb = KeGetCurrentPrcb(); //获取当前所在CPU的PRCB /* Check if the DPC has more then the maximum number of CPUs */ if (Dpc->Number >= MAXIMUM_PROCESSORS) { /* Then substract the maximum and get that PRCB. */ Cpu = Dpc->Number - MAXIMUM_PROCESSORS; Prcb = KiProcessorBlock[Cpu]; } else { /* Use the current one */ Prcb = CurrentPrcb; Cpu = Prcb->Number; } /* ROS Sanity Check */ ASSERT(Prcb == CurrentPrcb); /* Check if this is a threaded DPC and threaded DPCs are enabled */ if ((Dpc->Type == ThreadedDpcObject) && (Prcb->ThreadDpcEnable)) { /* Then use the threaded data */ DpcData = &Prcb->DpcData[DPC_THREADED]; } else { /* Otherwise, use the regular data */ DpcData = &Prcb->DpcData[DPC_NORMAL]; } /* Acquire the DPC lock */ KiAcquireSpinLock(&DpcData->DpcLock); /* Get the DPC Data */ if (!InterlockedCompareExchangePointer(&Dpc->DpcData, DpcData, NULL)) { /* Now we can play with the DPC safely */ Dpc->SystemArgument1SystemArgument1 = SystemArgument1; Dpc->SystemArgument2SystemArgument2 = SystemArgument2; DpcData->DpcQueueDepth++; DpcData->DpcCount++; DpcConfigured = TRUE; /* Check if this is a high importance DPC */ if (Dpc->Importance == HighImportance) { /* Pre-empty other DPCs */ InsertHeadList(&DpcData->DpcListHead, &Dpc->DpcListEntry); } else { /* Add it at the end */ InsertTailList(&DpcData->DpcListHead, &Dpc->DpcListEntry); } /* Check if this is the DPC on the threaded list */ if (&Prcb->DpcData[DPC_THREADED] == DpcData) { /* Make sure a threaded DPC isn't already active */ if (!(Prcb->DpcThreadActive) && !(Prcb->DpcThreadRequested)) { /* FIXME: Setup Threaded DPC */ DPRINT1("Threaded DPC not supported\n"); while (TRUE); } } //end if (&Prcb->DpcData[DPC_THREADED] == DpcData) else { /* Make sure a DPC isn't executing already */ if (!(Prcb->DpcRoutineActive) && !(Prcb-> DpcInterruptRequested)) { /* Check if this is the same CPU */ if (Prcb != CurrentPrcb) { /* Check if the DPC is of high importance or above the * maximum depth. If it is, then make sure that the CPU * isn't idle, or that it's sleeping. */ if (((Dpc->Importance == HighImportance) || (DpcData->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth)) && (!(AFFINITY_MASK(Cpu) & KiIdleSummary) || (Prcb->Sleeping))) { /* Set interrupt requested */ Prcb->DpcInterruptRequested = TRUE; /* Set DPC inserted */ DpcInserted = TRUE; } } //end if (Prcb != CurrentPrcb) else { /* Check if the DPC is of anything but low importance */ if ((Dpc->Importance != LowImportance) || (DpcData->DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) || (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) { /* Set interrupt requested */ Prcb->DpcInterruptRequested = TRUE; /* Set DPC inserted */ DpcInserted = TRUE; } } } //end if (!(Prcb->DpcRoutineActive) && !(Prcb->DpcInterrupt Requested)) } //end if (&Prcb->DpcData[DPC_THREADED] == DpcData) else } //end if (!InterlockedCompareExchangePointer(&Dpc->DpcData, DpcData, NULL)) /* Release the lock */ KiReleaseSpinLock(&DpcData->DpcLock); /* Check if the DPC was inserted */ if (DpcInserted) { /* Check if this was SMP */ if (Prcb != CurrentPrcb) { /* It was, request and IPI */ KiIpiSendRequest(AFFINITY_MASK(Cpu), IPI_DPC); } else { /* It wasn't, request an interrupt from HAL */ //要求扫描DPC请求队列 HalRequestSoftwareInterrupt(DISPATCH_LEVEL); //调用HalRequestSoftwareInterrupt函数 } } /* Lower IRQL */ KeLowerIrql(OldIrql); //降低到原来的Irql return DpcConfigured; }
这段代码是支持SMP多处理器结构的,所以不同的CPU有不同的PRCB数据结构,但是单CPU的系统只有一个PRCB。
如果将DPC请求挂入了队列,就通过HalRequestSoftwareInterrupt()将PCR中的相应标志位设置成TRUE,表示要求扫描DPC请求队列:
[KeInsertQueueDpc() > HalRequestSoftwareInterrupt()] VOID FASTCALL HalRequestSoftwareInterrupt(IN KIRQL Request) { switch (Request) { case APC_LEVEL: ((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = TRUE; break; case DISPATCH_LEVEL: ((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = TRUE; break; default: KEBUGCHECK(0); } }
0 0
- windows内核原理分析之DPC函数的执行(2)
- windows内核原理分析之DPC函数的执行(1)
- windows内核原理分析之DPC函数的执行(3)
- windows内核情景分析 --- DPC
- ReactOS分析windows DPC机制(1)
- windows内核情景分析 --- DPC 目的信令点编码
- windows内核情景分析之——APC的执行
- 关于内核定时器,DPC,线程的使用
- 关于内核定时器,DPC,线程的使用
- DPC函数
- windows的IO管理器内核实现机制原理分析。
- windows的IO管理器内核实现机制原理分析
- Linux内核分析之五——分析系统调用(system_call)的执行机制
- DPC,时间中断,以及DPC定时器(2)
- 《Windows内核情景分析》常用内核函数
- windows内核情景分析之—— KeRaiseIrql函数与KeLowerIrql()函数
- Windows内核函数(2) - 内核模式下的文件操作
- 驱动中的DPC函数
- Linux C调用C++库
- 微信直接打开App
- Documentation/fb/framebuffer.txt 翻译
- 基数排序
- myeclispe启动提示could not reserve enough space for object heap
- windows内核原理分析之DPC函数的执行(2)
- python实现了字符串的按位异或和php中的strpad函数
- JavaScript 命名函数与匿名函数
- bootstrap 学习笔记 - 4 (按钮 + 图片 + 辅助类)
- Android ListView功能扩展,实现高性能的瀑布流布局
- 简单的横向ListView实现(version 4.0)
- <picture>-浏览器内置的响应式标签(翻译)
- Linux 内核--总线设备驱动模型(字符/块/网络设备 && platform设备)
- Android中自定义View的onMeasure以及MeasureSpec使用