Skip to content

Commit

Permalink
Merge pull request #2476 from nrspruit/fix_event_memory_leak
Browse files Browse the repository at this point in the history
[L0] Fix Event Memory Leak due to no destroy on delete
  • Loading branch information
martygrant authored Dec 19, 2024
2 parents d18d523 + 56a3c84 commit 06a8c51
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions source/adapters/level_zero/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ ur_result_t ur_context_handle_t_::finalize() {
for (auto &EventCache : EventCaches) {
for (auto &Event : EventCache) {
auto ZeResult = ZE_CALL_NOCHECK(zeEventDestroy, (Event->ZeEvent));
Event->ZeEvent = nullptr;
// Gracefully handle the case that L0 was already unloaded.
if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
return ze2urResult(ZeResult);
Expand Down
21 changes: 21 additions & 0 deletions source/adapters/level_zero/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,26 @@ ur_result_t ur_event_handle_t_::getOrCreateHostVisibleEvent(
return UR_RESULT_SUCCESS;
}

/**
* @brief Destructor for the ur_event_handle_t_ class.
*
* This destructor is responsible for cleaning up the event handle when the
* object is destroyed. It checks if the event (`ZeEvent`) is valid and if the
* event has been completed (`Completed`). If both conditions are met, it
* further checks if the associated queue (`UrQueue`) is valid and if it is not
* set to discard events. If all conditions are satisfied, it calls
* `zeEventDestroy` to destroy the event.
*
* This ensures that resources are properly released and avoids potential memory
* leaks or resource mismanagement.
*/
ur_event_handle_t_::~ur_event_handle_t_() {
if (this->ZeEvent && this->Completed) {
if (this->UrQueue && !this->UrQueue->isDiscardEvents())
ZE_CALL_NOCHECK(zeEventDestroy, (this->ZeEvent));
}
}

ur_result_t urEventReleaseInternal(ur_event_handle_t Event) {
if (!Event->RefCount.decrementAndTest())
return UR_RESULT_SUCCESS;
Expand All @@ -1073,6 +1093,7 @@ ur_result_t urEventReleaseInternal(ur_event_handle_t Event) {
if (Event->OwnNativeHandle) {
if (DisableEventsCaching) {
auto ZeResult = ZE_CALL_NOCHECK(zeEventDestroy, (Event->ZeEvent));
Event->ZeEvent = nullptr;
// Gracefully handle the case that L0 was already unloaded.
if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
return ze2urResult(ZeResult);
Expand Down
2 changes: 2 additions & 0 deletions source/adapters/level_zero/event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ struct ur_event_handle_t_ : _ur_object {
reinterpret_cast<ur_event_handle_t_ *>(HostVisibleEvent));
}

~ur_event_handle_t_();

// Provide direct access to Context, instead of going via queue.
// Not every PI event has a queue, and we need a handle to Context
// to get to event pool related information.
Expand Down

0 comments on commit 06a8c51

Please sign in to comment.