# version 1.0 # PowerShell script to detect loop delays as follows: # - Soft failure if delay is between 9-12ms or >=20ms # - Hard failure if delay is between 13-19ms, which stops WPR and exits the script. # (delays in this range are likely to be caused by the mysterious ~14ms idle periods that are being investigated) # Raise script process priority to High try { $currentProcess = [System.Diagnostics.Process]::GetCurrentProcess() $currentProcess.PriorityClass = [System.Diagnostics.ProcessPriorityClass]::High Write-Host "Process priority set to High." } catch { Write-Warning "Failed to set process priority to High: $_" } # Define P/Invoke for NtSetTimerResolution Add-Type @" using System; using System.Runtime.InteropServices; public class TimerResolution { [DllImport("ntdll.dll", SetLastError=true)] public static extern int NtSetTimerResolution(uint DesiredResolution, bool Set, out uint CurrentResolution); } "@ # Set system timer to 1ms resolution (10000 in 100ns units) $currentResolution = 0 try { $timerResult = [TimerResolution]::NtSetTimerResolution(10000, $true, [ref]$currentResolution) if ($timerResult -ne 0) { Write-Warning "Failed to set timer resolution to 1ms (status: $timerResult). Continuing with default resolution." } else { Write-Host "Timer resolution set to 1ms (current: $($currentResolution/10000)ms)." } } catch { Write-Warning "Error setting timer resolution: $_ Continuing with default resolution." } # Counter for total iterations $totalIterations = 0 # Main loop try { while ($true) { $start = [System.Diagnostics.Stopwatch]::StartNew() # Precise sleep for 1ms [System.Threading.Thread]::Sleep(1) $elapsedMs = [math]::Round($start.Elapsed.TotalMilliseconds) $totalIterations++ # Check delay categories if ($elapsedMs -ge 9 -and $elapsedMs -le 12 -or $elapsedMs -ge 20) { Write-Host "Soft failure: $elapsedMs ms" } elseif ($elapsedMs -ge 13 -and $elapsedMs -le 19) { Write-Host "Loop delay exceeded 10ms: $elapsedMs ms" # Spawn process to stop WPR try { Write-Host "Stopping WPR..." Start-Process -FilePath "wpr" -ArgumentList "-stop WPRRecording.etl" -NoNewWindow -Wait Write-Host "WPR stopped. ETL file saved to: WPRRecording.etl" } catch { Write-Error "Failed to stop WPR: $_" } # Exit the script Write-Host "Exiting script after $totalIterations iterations." exit } } } finally { # Restore default timer resolution try { $currentResolution = 0 $timerResult = [TimerResolution]::NtSetTimerResolution(0, $false, [ref]$currentResolution) if ($timerResult -ne 0) { Write-Warning "Failed to restore default timer resolution (status: $timerResult)." } else { Write-Host "Timer resolution restored." } } catch { Write-Warning "Error restoring timer resolution: $_" } }