diff --git a/rocclr/device/device.hpp b/rocclr/device/device.hpp index a1be15530f..283cafe7a3 100644 --- a/rocclr/device/device.hpp +++ b/rocclr/device/device.hpp @@ -1423,6 +1423,9 @@ class Device : public RuntimeObject { return false; } + // Notifies device about context destroy + virtual void ContextDestroy() {} + //! Returns active wait state for this device bool ActiveWait() const { return activeWait_; } diff --git a/rocclr/device/pal/paldevice.hpp b/rocclr/device/pal/paldevice.hpp index dcac1a16ec..f19b7429f8 100644 --- a/rocclr/device/pal/paldevice.hpp +++ b/rocclr/device/pal/paldevice.hpp @@ -365,6 +365,11 @@ class Device : public NullDevice { virtual bool unbindExternalDevice(uint flags, void* const pDevice[], void* pContext, bool validateOnly); + //! Free resource cache on device if OCL context was destroyed. + //! @note: Backend device doesn't track resources per context and releases all resources, regardless + //! the number of still active contexts + virtual void ContextDestroy() { resourceCache().free(); } + //! Validates kernel before execution virtual bool validateKernel(const amd::Kernel& kernel, //!< AMD kernel object const device::VirtualDevice* vdev, bool coop_group = false); diff --git a/rocclr/device/pal/palresource.cpp b/rocclr/device/pal/palresource.cpp index 87f60ee89b..6ebff35e82 100644 --- a/rocclr/device/pal/palresource.cpp +++ b/rocclr/device/pal/palresource.cpp @@ -2187,7 +2187,7 @@ bool ResourceCache::free(size_t minCacheEntries) { if (minCacheEntries < resCache_.size()) { result = true; // Clear the cache - while (static_cast(cacheSize_) > 0) { + while (static_cast(cacheSize_) > 0) { removeLast(); } CondLog((cacheSize_ != 0), "Incorrect size for cache release!"); @@ -2201,14 +2201,16 @@ void ResourceCache::removeLast() { { // Protect access to the global data amd::ScopedLock l(&lockCacheOps_); - entry = resCache_.back(); - resCache_.pop_back(); - cacheSize_ -= entry.second->iMem()->Desc().size; - if (entry.first->type_ == Resource::Local) { - lclCacheSize_ -= entry.second->iMem()->Desc().size; + if (resCache_.size() > 0) { + entry = resCache_.back(); + resCache_.pop_back(); + cacheSize_ -= entry.second->iMem()->Desc().size; + if (entry.first->type_ == Resource::Local) { + lclCacheSize_ -= entry.second->iMem()->Desc().size; + } + // Delete Descriptor + delete entry.first; } - // Delete Descriptor - delete entry.first; } // Destroy PAL resource diff --git a/rocclr/platform/context.cpp b/rocclr/platform/context.cpp index b62c905aad..7e792e615f 100644 --- a/rocclr/platform/context.cpp +++ b/rocclr/platform/context.cpp @@ -75,12 +75,18 @@ Context::Context(const std::vector& devices, const Info& info) Context::~Context() { static const bool VALIDATE_ONLY = false; - // Dissociate OCL context with any external device - if (info_.flags_ & (GLDeviceKhr | D3D10DeviceKhr | D3D11DeviceKhr)) { - // Loop through all devices - for (const auto& it : devices_) { + // Loop through all devices + for (const auto& it : devices_) { + // Dissociate OCL context with any external device + if (info_.flags_ & (GLDeviceKhr | D3D10DeviceKhr | D3D11DeviceKhr)) { it->unbindExternalDevice(info_.flags_, info_.hDev_, info_.hCtx_, VALIDATE_ONLY); } + + // Notify device about context destroy + it->ContextDestroy(); + + // Release device + it->release(); } if (properties_ != NULL) { @@ -91,8 +97,6 @@ Context::~Context() { glenv_ = NULL; } - std::for_each(devices_.begin(), devices_.end(), std::mem_fun(&Device::release)); - #ifdef WITH_LIQUID_FLASH lfTerminate(); #endif