Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions unified-runtime/source/adapters/level_zero/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,16 +890,24 @@ urEventRelease(
(Event->CommandType == UR_COMMAND_EVENTS_WAIT ||
Event->CommandType == UR_COMMAND_EVENTS_WAIT_WITH_BARRIER) &&
Event->Completed;
bool isEventDeleted = false;
UR_CALL(urEventReleaseInternal(Event, &isEventDeleted));
// If this is a Completed Event Wait Out Event, then we need to cleanup the
// event at user release and not at the time of completion.
// Use CleanupCompletedEvent which is a no-op if the event was already
// cleaned up (e.g. by CleanupEventListFromResetCmdList), preventing a
// double-release of the internal reference count.
if (isEventsWaitCompleted & !isEventDeleted) {
//
// Clean up before dropping the reference this call owns. Once
// urEventReleaseInternal() drops the last reference the event goes back into
// the context event cache, and another thread can take it from there right
// away for an unrelated command. Touching it after that point corrupts the
// new owner's event: CleanupCompletedEvent() would set CleanedUp on it, which
// makes every subsequent cleanup of the recycled event return early and so
// leak the reference that createEventAndAssociateQueue() took. That reference
// keeps the queue alive too, so its ZeCommandQueue is never destroyed.
if (isEventsWaitCompleted) {
UR_CALL(CleanupCompletedEvent(Event, false, false));
}
UR_CALL(urEventReleaseInternal(Event));

return UR_RESULT_SUCCESS;
}
Expand Down Expand Up @@ -1116,13 +1124,12 @@ ur::level_zero::v1::ur_event_handle_t_::~ur_event_handle_t_() {
}
}

ur_result_t urEventReleaseInternal(ur_event_handle_t Event,
bool *isEventDeleted) {
ur_result_t urEventReleaseInternal(ur_event_handle_t Event) {
if (!Event->RefCount.release())
return UR_RESULT_SUCCESS;

if (Event->OriginAllocEvent) {
urEventReleaseInternal(Event->OriginAllocEvent, isEventDeleted);
urEventReleaseInternal(Event->OriginAllocEvent);
}

if (Event->CommandType == UR_COMMAND_MEM_UNMAP && Event->CommandData) {
Expand Down Expand Up @@ -1163,7 +1170,7 @@ ur_result_t urEventReleaseInternal(ur_event_handle_t Event,
// and release a reference to it.
if (Event->HostVisibleEvent && Event->HostVisibleEvent != Event) {
// Decrement ref-count of the host-visible proxy event.
UR_CALL(urEventReleaseInternal(Event->HostVisibleEvent, isEventDeleted));
UR_CALL(urEventReleaseInternal(Event->HostVisibleEvent));
}

// Save pointer to the queue before deleting/resetting event.
Expand Down Expand Up @@ -1192,9 +1199,6 @@ ur_result_t urEventReleaseInternal(ur_event_handle_t Event,
// must released later.
if (DisableEventsCaching || !Event->OwnNativeHandle) {
delete Event;
if (isEventDeleted) {
*isEventDeleted = true;
}
} else {
Event->Context->addEventToContextCache(Event);
}
Expand Down
3 changes: 1 addition & 2 deletions unified-runtime/source/adapters/level_zero/event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@

namespace ur::level_zero::v1 {

ur_result_t urEventReleaseInternal(ur_event_handle_t Event,
bool *isEventDeleted = nullptr);
ur_result_t urEventReleaseInternal(ur_event_handle_t Event);
ur_result_t EventCreate(ur_context_handle_t Context, ur_queue_handle_t Queue,
bool IsMultiDevice, bool HostVisible,
ur_event_handle_t *RetEvent,
Expand Down
Loading