I currently have a driver whose job is to notify a waiting single-threaded user mode application of any interrupts sent by the device, which generates interrupts every 1ms. Currently, the driver’s implementation of the problem is pretty standard:
- The user mode application waits on event for the next interrupt.
- The interrupt handler will queue up a DPC if it recognizes an interrupt.
- The DPC sets the event, waking up the user mode app.
Long story short, on older machines running Windows 7 or 10, the DPC scheduling latency (that is, the latency between when a DPC is scheduled and when it is executed) is sometimes large enough to miss the next interrupt or two, occurring on average once or twice per minute. For reference, I profiled the scheduling latency using KeQueryPerformanceCounter, which I believe is one of the right ways of going about that based on previous posts on this list. There is nothing else running on these machines, and I’ve set the resolution of the system clock to 1ms in the user mode app using the media API functions. Even unplugging and disabling all network adapters to reduce the number of DPCs from NDIS did not eliminate the problem.
What I would really like to do is get rid of this latency. My first idea was to get rid of the DPC, but the event APIs are not available at DIRQL AFAIK, and it’s generally frowned upon to do any work in the interrupt handler anyway. However, apparently some competitors are somehow magically not experiencing this latency, so I’m wondering if it really is possible to just not use DPCs. I was thinking about using the Interlocked* APIs somehow with possibly a spin lock (not in the interrupt handler though!), but I was wondering if there was another way since that sounds beyond tricky.
I do understand that I’m trying to do something that really shouldn’t be done, and that Windows isn’t a RTOS, but sometimes in the corporate world there’s not always the luxury to say no.
Thanks in advance for any help.