下面的代码执行在DISPATCH_LEVEL下
u_currentCPU = KeGetCurrentProcessorNumber();
pkdpc = temp_pkdpc;
for (i = 0; i < KeNumberProcessors; i++, *temp_pkdpc++)
{
// Make sure we don't schedule a DPC on the current
// processor. This would cause a deadlock.
这句话我很疑问?
if (i != u_currentCPU)
{
KeInitializeDpc(temp_pkdpc,
RaiseCPUIrqlAndWait,
NULL);
// Set the target processor for the DPC; otherwise,
// it will be queued on the current processor when
// we call KeInsertQueueDpc.
KeSetTargetProcessorDpc(temp_pkdpc, i);
KeInsertQueueDpc(temp_pkdpc, NULL, NULL);
}
上面这个函数调用完成后,会在适当时刻将AllCPURaised置为1
下面是我要给其他CPU插入的DPC例程RaiseCPUIrqlAndWait(IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
{
InterlockedIncrement(&NumberOfRaisedCPU);
while(!InterlockedCompareExchange(&AllCPURaised, 1, 1))
{
__asm nop;
}
InterlockedDecrement(&NumberOfRaisedCPU);
}
上面的问题点就是:我不理解为什么书上说会死锁?是肯定的,还是只是可能?
我给出我的理解:如果代码中不加if (i != u_currentCPU)这个判断,则会在自己CPU的DPC队列中插入一个新的DPC任务,这样子的话,如果此时发生时钟中断(IRQL高于DISPATCH),则它的中断处理程序会在最后检测DPC队列中有没有DPC任务,如果有的话,自然就去执行DPC函数了。在执行DPC函数的时候问题就产生了,DPC函数中的InterlockedCompareExchange(&AllCPURaised)这句会一直阻塞。。。。从而造成死锁(DPC等待AllCPURaised变为1,而让AllCPURaised变1的线程永远得不到CPU)???我的分析对不对?