Supporting Interrupt Latency Timing

Interrupt latency timing measures the following two times:

  • The time between an interrupt being generated and its interrupt service routine (ISR) being invoked.
  • The time between the ISR exiting and when the interrupt service thread (IST) begins scheduled.

Latency timing is measured using Iltiming.exe and requires significant support from the OAL. The interrupt latency measurement leverages the fact that timer ISRs should occur at known times, on whole milliseconds. The number of timer ticks in dwIsrTime1 measures the interval between the timer interrupt occurring and the start of its ISR.

Iltiming.exe creates an interrupt object for SYSINTR_TIMING. It obtains a kernel mode pointer to PerfCountSinceTick using one of the IOCTL_HAL_ILTIMING calls. When the timer ISR returns with a value of SYSINTR_TIMING, the interrupt service thread in Iltiming.exe is scheduled. The service thread runs in kernel mode, so it calls directly into the kernel's code space to get the current PerfCountSinceTick value. It subtracts dwIsrTime2 from this to measure the latency between when the ISR exits, presumably very close to the time the IST is scheduled, and when the IST actually starts.

In some cases, other interrupts will occur between the time the Iltiming.exe IST is scheduled and when it starts executing. Iltiming.exe determines when this has happened by comparing dwIsrTime1 and dwIsrTime2; if an extra interrupt has occurred, dwIsrTime1 will be greater than dwIsrTime2. Iltiming.exe can also determine if extra interrupts have occurred by examining wNumInterrupts; this is why all ISRs need to set these variables.

To support interrupt latency timing

  1. Implement IOCTL_HAL_ILTIMING support in OEMIoControl. This code is hardware independent and can be copied from any of the sample platforms. It includes the global variables fIntrTime, dwIsrTime1, dwIsrTime2, and wNumInterrupts, among others that should all be copied.
  2. OEMInterruptEnable should return success for SYSINTR_TIMING without actually performing an action.
  3. Implement PerfCountSinceTick and PerfCountFreq. PerfCountSinceTick is the number of counter ticks that have elapsed since the latest timer interrupt occurred. For more information, see PerfCountSinceTick and PerfCountFreq.
  4. All ISRs must check fIntrTime, one of the global variables, at their entry point. If this variable is set, the ISR should set dwIsrTime1 to PerfCountSinceTick and increment wNumInterrupts.
  5. If fIntrTime is set, the timer ISR should decrement dwIntrTimeCountdown and return SYSINTR_TIMING if it is zero. Otherwise, it should return SYSINTR_RESCHED or SYSINTR_NOP as normal. Once it is zero, dwIntrTimeCountdown should be reloaded from dwIntrTimeCountdownRef; this variable is initialized through an IOCTL_HAL_ILTIMING message.
  6. When it returns SYSINTR_TIMING, the timer ISR needs to set dwIsrTime2 to PerfCountSinceTick.

The sample implementation of OEMIdle already checks fIntrTime and handles interrupt latency timing as a special case.

See Also

How to Develop an OEM Adaptation Layer | Implementing the OEMIoControl Function

Last updated on Wednesday, April 13, 2005

© 2005 Microsoft Corporation. All rights reserved.