diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/interrupt_signal.h b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/interrupt_signal.h index 755f0dd447..3822cd972d 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/interrupt_signal.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/interrupt_signal.h @@ -45,9 +45,11 @@ #ifndef HSA_RUNTME_CORE_INC_INTERRUPT_SIGNAL_H_ #define HSA_RUNTME_CORE_INC_INTERRUPT_SIGNAL_H_ +#include +#include + #include "hsakmt.h" -#include "core/inc/runtime.h" #include "core/inc/signal.h" #include "core/util/utils.h" @@ -63,6 +65,28 @@ namespace core { /// signaling. class InterruptSignal : private LocalSignal, public Signal { public: + class EventPool { + public: + struct Deleter { + void operator()(HsaEvent* evt) { InterruptSignal::DestroyEvent(evt); } + }; + using unique_event_ptr = ::std::unique_ptr; + + EventPool() : allEventsAllocated(false) {} + + HsaEvent* alloc(); + void free(HsaEvent* evt); + void clear() { + events_.clear(); + allEventsAllocated = false; + } + + private: + KernelMutex lock_; + std::vector events_; + bool allEventsAllocated; + }; + static HsaEvent* CreateEvent(HSA_EVENTTYPE type, bool manual_reset); static void DestroyEvent(HsaEvent* evt); diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/runtime.h b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/runtime.h index 477ee36c3e..7f88cc6705 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/inc/runtime.h +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/inc/runtime.h @@ -56,6 +56,7 @@ #include "core/inc/exceptions.h" #include "core/inc/memory_region.h" #include "core/inc/signal.h" +#include "core/inc/interrupt_signal.h" #include "core/util/flag.h" #include "core/util/locks.h" #include "core/util/os.h" @@ -335,6 +336,8 @@ class Runtime { SharedSignalPool_t* GetSharedSignalPool() { return &SharedSignalPool; } + InterruptSignal::EventPool* GetEventPool() { return &EventPool; } + protected: static void AsyncEventsLoop(void*); @@ -510,6 +513,9 @@ class Runtime { // Pools memory for SharedSignal (Signal ABI blocks) SharedSignalPool_t SharedSignalPool; + // Pools KFD Events for InterruptSignal + InterruptSignal::EventPool EventPool; + // Frees runtime memory when the runtime library is unloaded if safe to do so. // Failure to release the runtime indicates an incorrect application but is // common (example: calls library routines at process exit). diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/interrupt_signal.cpp b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/interrupt_signal.cpp index 08ef9dd4f4..4342decc9e 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/interrupt_signal.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/interrupt_signal.cpp @@ -41,10 +41,35 @@ //////////////////////////////////////////////////////////////////////////////// #include "core/inc/interrupt_signal.h" +#include "core/inc/runtime.h" #include "core/util/timer.h" +#include "core/util/locks.h" namespace core { +HsaEvent* InterruptSignal::EventPool::alloc() { + ScopedAcquire lock(&lock_); + if (events_.empty()) { + if (!allEventsAllocated) { + HsaEvent* evt = InterruptSignal::CreateEvent(HSA_EVENTTYPE_SIGNAL, false); + if (evt == nullptr) allEventsAllocated = true; + return evt; + } + return nullptr; + } + HsaEvent* ret = events_.back().release(); + events_.pop_back(); + return ret; +} + +void InterruptSignal::EventPool::free(HsaEvent* evt) { + if (evt == nullptr) return; + ScopedAcquire lock(&lock_); + events_.push_back(unique_event_ptr(evt)); +} + +int InterruptSignal::rtti_id_ = 0; + HsaEvent* InterruptSignal::CreateEvent(HSA_EVENTTYPE type, bool manual_reset) { HsaEventDescriptor event_descriptor; event_descriptor.EventType = type; @@ -64,21 +89,19 @@ HsaEvent* InterruptSignal::CreateEvent(HSA_EVENTTYPE type, bool manual_reset) { return ret; } -int InterruptSignal::rtti_id_ = 0; - void InterruptSignal::DestroyEvent(HsaEvent* evt) { hsaKmtDestroyEvent(evt); } InterruptSignal::InterruptSignal(hsa_signal_value_t initial_value, HsaEvent* use_event) : LocalSignal(initial_value, false), Signal(signal()) { - if (use_event != NULL) { + if (use_event != nullptr) { event_ = use_event; free_event_ = false; } else { - event_ = CreateEvent(HSA_EVENTTYPE_SIGNAL, false); + event_ = Runtime::runtime_singleton_->GetEventPool()->alloc(); free_event_ = true; } - if (event_ != NULL) { + if (event_ != nullptr) { signal_.event_id = event_->EventId; signal_.event_mailbox_ptr = event_->EventData.HWData2; } else { @@ -89,7 +112,7 @@ InterruptSignal::InterruptSignal(hsa_signal_value_t initial_value, HsaEvent* use } InterruptSignal::~InterruptSignal() { - if (free_event_) hsaKmtDestroyEvent(event_); + if (free_event_) Runtime::runtime_singleton_->GetEventPool()->free(event_); } hsa_signal_value_t InterruptSignal::LoadRelaxed() { diff --git a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/runtime.cpp b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/runtime.cpp index 772b8310ae..ffc39afcc5 100644 --- a/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/runtime.cpp +++ b/projects/rocr-runtime/runtime/hsa-runtime/core/runtime/runtime.cpp @@ -1221,6 +1221,8 @@ void Runtime::Unload() { SharedSignalPool.clear(); + EventPool.clear(); + DestroyAgents(); CloseTools();