Skip to content

Commit 403bbbb

Browse files
authored
Merge pull request #2476 from nrspruit/fix_event_memory_leak
[L0] Fix Event Memory Leak due to no destroy on delete
2 parents 6dc48da + a43302f commit 403bbbb

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

source/adapters/level_zero/context.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ ur_result_t ur_context_handle_t_::finalize() {
422422
for (auto &EventCache : EventCaches) {
423423
for (auto &Event : EventCache) {
424424
auto ZeResult = ZE_CALL_NOCHECK(zeEventDestroy, (Event->ZeEvent));
425+
Event->ZeEvent = nullptr;
425426
// Gracefully handle the case that L0 was already unloaded.
426427
if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
427428
return ze2urResult(ZeResult);

source/adapters/level_zero/event.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,26 @@ ur_result_t ur_event_handle_t_::getOrCreateHostVisibleEvent(
10511051
return UR_RESULT_SUCCESS;
10521052
}
10531053

1054+
/**
1055+
* @brief Destructor for the ur_event_handle_t_ class.
1056+
*
1057+
* This destructor is responsible for cleaning up the event handle when the
1058+
* object is destroyed. It checks if the event (`ZeEvent`) is valid and if the
1059+
* event has been completed (`Completed`). If both conditions are met, it
1060+
* further checks if the associated queue (`UrQueue`) is valid and if it is not
1061+
* set to discard events. If all conditions are satisfied, it calls
1062+
* `zeEventDestroy` to destroy the event.
1063+
*
1064+
* This ensures that resources are properly released and avoids potential memory
1065+
* leaks or resource mismanagement.
1066+
*/
1067+
ur_event_handle_t_::~ur_event_handle_t_() {
1068+
if (this->ZeEvent && this->Completed) {
1069+
if (this->UrQueue && !this->UrQueue->isDiscardEvents())
1070+
ZE_CALL_NOCHECK(zeEventDestroy, (this->ZeEvent));
1071+
}
1072+
}
1073+
10541074
ur_result_t urEventReleaseInternal(ur_event_handle_t Event) {
10551075
if (!Event->RefCount.decrementAndTest())
10561076
return UR_RESULT_SUCCESS;
@@ -1073,6 +1093,7 @@ ur_result_t urEventReleaseInternal(ur_event_handle_t Event) {
10731093
if (Event->OwnNativeHandle) {
10741094
if (DisableEventsCaching) {
10751095
auto ZeResult = ZE_CALL_NOCHECK(zeEventDestroy, (Event->ZeEvent));
1096+
Event->ZeEvent = nullptr;
10761097
// Gracefully handle the case that L0 was already unloaded.
10771098
if (ZeResult && ZeResult != ZE_RESULT_ERROR_UNINITIALIZED)
10781099
return ze2urResult(ZeResult);

source/adapters/level_zero/event.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ struct ur_event_handle_t_ : _ur_object {
156156
reinterpret_cast<ur_event_handle_t_ *>(HostVisibleEvent));
157157
}
158158

159+
~ur_event_handle_t_();
160+
159161
// Provide direct access to Context, instead of going via queue.
160162
// Not every PI event has a queue, and we need a handle to Context
161163
// to get to event pool related information.

0 commit comments

Comments
 (0)