| 3501 | } |
| 3502 | |
| 3503 | void PMTraceConsumer::ResetPresentTrackingData(bool shrink) { |
| 3504 | |
| 3505 | // Disable any future processing first |
| 3506 | SetEventProcessingEnabled(false); |
| 3507 | |
| 3508 | // Wait for in-flight event handlers to drain so we can safely clear the |
| 3509 | // tracking maps without taking a mutex on every ETW event. This is only |
| 3510 | // meaningful when provider-toggle mode is enabled and EventProcessingScope |
| 3511 | // is active in the ETW callbacks. |
| 3512 | auto const& shim = GetWaitOnAddressShim(); |
| 3513 | |
| 3514 | ULONGLONG const startMs = ::GetTickCount64(); |
| 3515 | DWORD const timeoutMs = 2000; |
| 3516 | |
| 3517 | while (::InterlockedCompareExchange(&mEventProcessingInFlight, 0, 0) != 0) { |
| 3518 | ULONGLONG elapsed = ::GetTickCount64() - startMs; |
| 3519 | if (elapsed >= timeoutMs) { |
| 3520 | pmlog_warn("Timed out waiting for event processing to quiesce; skipping present tracking reset"); |
| 3521 | return; |
| 3522 | } |
| 3523 | DWORD remaining = timeoutMs - (DWORD)elapsed; |
| 3524 | if (shim.Available()) { |
| 3525 | LONG expected = ::InterlockedCompareExchange(&mEventProcessingInFlight, 0, 0); |
| 3526 | if (expected != 0) { |
| 3527 | // Wait until the value at the address changes from 'expected'. |
| 3528 | // Spurious wakeups are possible; loop re-check handles it. |
| 3529 | shim.Wait(&mEventProcessingInFlight, &expected, sizeof(expected), remaining); |
| 3530 | } |
| 3531 | } |
| 3532 | else { |
| 3533 | // Win7 fallback |
| 3534 | ::Sleep(1); |
| 3535 | } |
| 3536 | } |
| 3537 | |
| 3538 | pmlog_info("Present tracking reset: Event processing quiesced; proceeding with present tracking reset shrink =" |
| 3539 | + std::to_string(shrink)); |
| 3540 | // Now it is safe to clear the state |
| 3541 | { |
| 3542 | std::lock_guard<std::mutex> lock(mPresentEventMutex); |
| 3543 | // Clear rings and counters |
| 3544 | for(auto& p : mTrackedPresents) { |
| 3545 | p.reset(); |
| 3546 | } |
| 3547 | for(auto& p : mCompletedPresents) { |
| 3548 | p.reset(); |
| 3549 | } |
| 3550 | mNextFreeRingIndex = 0; |
| 3551 | mCompletedIndex = 0; |
| 3552 | mCompletedCount = 0; |
| 3553 | mReadyCount = 0; |
| 3554 | mNumOverflowedPresents = 0; |
| 3555 | |
| 3556 | // We need to see a completed present again after the providers restart |
| 3557 | mHasCompletedAPresent = false; |
| 3558 | |
| 3559 | // DWM tracking |
| 3560 | mPresentsWaitingForDWM.clear(); |
no test coverage detected