diff options
Diffstat (limited to 'src/zenutil/parallelwork.cpp')
| -rw-r--r-- | src/zenutil/parallelwork.cpp | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/src/zenutil/parallelwork.cpp b/src/zenutil/parallelwork.cpp index aa806438b..a571d1d11 100644 --- a/src/zenutil/parallelwork.cpp +++ b/src/zenutil/parallelwork.cpp @@ -33,18 +33,21 @@ ParallelWork::~ParallelWork() "ParallelWork disposed without explicit wait for completion, likely caused by an exception, waiting for dispatched threads " "to complete"); m_PendingWork.CountDown(); + m_DispatchComplete = true; + } + const bool WaitSucceeded = m_PendingWork.Wait(); + const ptrdiff_t RemainingWork = m_PendingWork.Remaining(); + if (!WaitSucceeded) + { + ZEN_ERROR("ParallelWork::~ParallelWork(): waiting for latch failed, pending work count at {}", RemainingWork); } - m_PendingWork.Wait(); - ptrdiff_t RemainingWork = m_PendingWork.Remaining(); if (RemainingWork != 0) { void* Frames[8]; uint32_t FrameCount = GetCallstack(2, 8, Frames); CallstackFrames* Callstack = CreateCallstack(FrameCount, Frames); - ZEN_ERROR("ParallelWork destructor waited for outstanding work but pending work count is {} instead of 0\n{}", - RemainingWork, - CallstackToString(Callstack, " ")); - FreeCallstack(Callstack); + auto _ = MakeGuard([Callstack]() { FreeCallstack(Callstack); }); + ZEN_WARN("ParallelWork::~ParallelWork(): waited for outstanding work but pending work count is {} instead of 0", RemainingWork); uint32_t WaitedMs = 0; while (m_PendingWork.Remaining() > 0 && WaitedMs < 2000) @@ -52,20 +55,27 @@ ParallelWork::~ParallelWork() Sleep(50); WaitedMs += 50; } - RemainingWork = m_PendingWork.Remaining(); - if (RemainingWork != 0) + ptrdiff_t RemainingWorkAfterSafetyWait = m_PendingWork.Remaining(); + if (RemainingWorkAfterSafetyWait != 0) { - ZEN_WARN("ParallelWork destructor safety wait failed, pending work count at {}", RemainingWork) + ZEN_ERROR("ParallelWork::~ParallelWork(): safety wait for {} tasks failed, pending work count at {} after {}\n{}", + RemainingWork, + RemainingWorkAfterSafetyWait, + NiceLatencyNs(WaitedMs * 1000000u), + CallstackToString(Callstack, " ")) } else { - ZEN_INFO("ParallelWork destructor safety wait succeeded"); + ZEN_ERROR("ParallelWork::~ParallelWork(): safety wait for {} tasks completed after {}\n{}", + RemainingWork, + NiceLatencyNs(WaitedMs * 1000000u), + CallstackToString(Callstack, " ")); } } } catch (const std::exception& Ex) { - ZEN_ERROR("Exception in ~ParallelWork: {}", Ex.what()); + ZEN_ERROR("Exception in ParallelWork::~ParallelWork(): {}", Ex.what()); } } @@ -82,10 +92,9 @@ void ParallelWork::Wait(int32_t UpdateIntervalMS, UpdateCallback&& UpdateCallback) { ZEN_ASSERT(!m_DispatchComplete); - m_DispatchComplete = true; - ZEN_ASSERT(m_PendingWork.Remaining() > 0); m_PendingWork.CountDown(); + m_DispatchComplete = true; while (!m_PendingWork.Wait(UpdateIntervalMS)) { @@ -99,11 +108,20 @@ void ParallelWork::Wait() { ZEN_ASSERT(!m_DispatchComplete); - m_DispatchComplete = true; - ZEN_ASSERT(m_PendingWork.Remaining() > 0); m_PendingWork.CountDown(); - m_PendingWork.Wait(); + m_DispatchComplete = true; + + const bool WaitSucceeded = m_PendingWork.Wait(); + const ptrdiff_t RemainingWork = m_PendingWork.Remaining(); + if (!WaitSucceeded) + { + ZEN_ERROR("ParallelWork::Wait(): waiting for latch failed, pending work count at {}", RemainingWork); + } + else if (RemainingWork != 0) + { + ZEN_ERROR("ParallelWork::Wait(): pending work count at {} after successful wait for latch", RemainingWork); + } RethrowErrors(); } |