diff --git a/runtime/hsa-runtime/core/runtime/interrupt_signal.cpp b/runtime/hsa-runtime/core/runtime/interrupt_signal.cpp index 773bbffa1e..93d33f471c 100644 --- a/runtime/hsa-runtime/core/runtime/interrupt_signal.cpp +++ b/runtime/hsa-runtime/core/runtime/interrupt_signal.cpp @@ -147,8 +147,15 @@ hsa_signal_value_t InterruptSignal::WaitRelaxed( uint32_t prior = waiting_++; MAKE_SCOPE_GUARD([&]() { waiting_--; }); - // Allow only the first waiter to sleep (temporary, known to be bad). - if (prior != 0) wait_hint = HSA_WAIT_STATE_ACTIVE; + + uint64_t event_age = 1; + + if (!core::Runtime::runtime_singleton_->KfdVersion().supports_event_age) { + event_age = 0; + // Allow only the first waiter to sleep. Without event age tracking, + // race condition can cause some threads to sleep without wakeup since missing interrupt. + if (prior != 0) wait_hint = HSA_WAIT_STATE_ACTIVE; + } int64_t value; @@ -222,7 +229,7 @@ hsa_signal_value_t InterruptSignal::WaitRelaxed( uint64_t ct=timer::duration_cast( time_remaining).count(); wait_ms = (ct>0xFFFFFFFEu) ? 0xFFFFFFFEu : ct; - hsaKmtWaitOnEvent(event_, wait_ms); + hsaKmtWaitOnEvent_Ext(event_, wait_ms, &event_age); } } diff --git a/runtime/hsa-runtime/core/runtime/signal.cpp b/runtime/hsa-runtime/core/runtime/signal.cpp index 486a2a305e..6c14820b01 100644 --- a/runtime/hsa-runtime/core/runtime/signal.cpp +++ b/runtime/hsa-runtime/core/runtime/signal.cpp @@ -197,8 +197,10 @@ uint32_t Signal::WaitAny(uint32_t signal_count, const hsa_signal_t* hsa_signals, for (uint32_t i = 0; i < signal_count; i++) signals[i]->waiting_--; }); - // Allow only the first waiter to sleep (temporary, known to be bad). - if (prior != 0) wait_hint = HSA_WAIT_STATE_ACTIVE; + if (!core::Runtime::runtime_singleton_->KfdVersion().supports_event_age) + // Allow only the first waiter to sleep. Without event age tracking, + // race condition can cause some threads to sleep without wakeup since missing interrupt. + if (prior != 0) wait_hint = HSA_WAIT_STATE_ACTIVE; // Ensure that all signals in the list can be slept on. if (wait_hint != HSA_WAIT_STATE_ACTIVE) { @@ -229,6 +231,11 @@ uint32_t Signal::WaitAny(uint32_t signal_count, const hsa_signal_t* hsa_signals, if (signal_count > small_size) delete[] evts; }); + uint64_t event_age[unique_evts] = {0}; + if (core::Runtime::runtime_singleton_->KfdVersion().supports_event_age) + for (uint32_t i = 0; i < unique_evts; i++) + event_age[i] = 1; + int64_t value; timer::fast_clock::time_point start_time = timer::fast_clock::now(); @@ -310,7 +317,7 @@ uint32_t Signal::WaitAny(uint32_t signal_count, const hsa_signal_t* hsa_signals, uint64_t ct=timer::duration_cast( time_remaining).count(); wait_ms = (ct>0xFFFFFFFEu) ? 0xFFFFFFFEu : ct; - hsaKmtWaitOnMultipleEvents(evts, unique_evts, false, wait_ms); + hsaKmtWaitOnMultipleEvents_Ext(evts, unique_evts, false, wait_ms, event_age); } }