Skip to content

Commit 816221d

Browse files
committed
event: add retain event during event sync
Since the waiting event is added to the notify_list of the notifier_event, a reference should be kept to prevent the notifier event from notifying an event that doesn't exist anymore. With the recent changes to the lock_events_inorder, this also greatly simplifies the broadcast code.
1 parent a2284ea commit 816221d

File tree

2 files changed

+26
-50
lines changed

2 files changed

+26
-50
lines changed

lib/CL/devices/common.c

+6-8
Original file line numberDiff line numberDiff line change
@@ -847,14 +847,11 @@ pocl_broadcast (cl_event brc_event)
847847
POCL_LOCK_OBJ (brc_event);
848848
while ((target = brc_event->notify_list))
849849
{
850-
cl_event target_event = target->event;
851-
POCL_UNLOCK_OBJ (brc_event);
852-
POname (clRetainEvent) (target_event);
853-
854-
pocl_lock_events_inorder (brc_event, target_event);
850+
POCL_LOCK_OBJ (target->event);
855851
if (target != brc_event->notify_list)
856852
{
857-
pocl_unlock_events_inorder (brc_event, target_event);
853+
assert (0 && "should be unreachable");
854+
pocl_unlock_events_inorder (brc_event, target->event);
858855
POCL_LOCK_OBJ (brc_event);
859856
continue;
860857
}
@@ -888,10 +885,11 @@ pocl_broadcast (cl_event brc_event)
888885
}
889886
}
890887
LL_DELETE (brc_event->notify_list, target);
891-
pocl_unlock_events_inorder (brc_event, target_event);
888+
POCL_UNLOCK_OBJ (target->event);
889+
/* Now that the event is deleted from the notify_list,
890+
* undo the retain done during pocl_create_event_sync. */
892891
POname (clReleaseEvent) (target->event);
893892
pocl_mem_manager_free_event_node (target);
894-
POCL_LOCK_OBJ (brc_event);
895893
}
896894
POCL_UNLOCK_OBJ (brc_event);
897895
}

lib/CL/pocl_util.c

+20-42
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,20 @@ pocl_create_event_sync (cl_event notifier_event, cl_event waiting_event)
364364
}
365365
}
366366

367-
if (notifier_event->status == CL_COMPLETE)
368-
goto FINISH;
367+
/* If the notifier event is already complete (or failed),
368+
don't create an event sync. This is fine since if the wait
369+
event has no notifier events and gets submitted, it can start
370+
right away.
371+
*/
372+
if (notifier_event->status < 0 || notifier_event->status == CL_COMPLETE)
373+
{
374+
POCL_MSG_PRINT_EVENTS (
375+
"notifier event %" PRIu64
376+
" already complete, not creating sync with event %" PRIu64 "\n",
377+
notifier_event->id, waiting_event->id);
378+
goto FINISH;
379+
}
380+
369381
notify_target = pocl_mem_manager_new_event_node();
370382
wait_list_item = pocl_mem_manager_new_event_node();
371383
if (!notify_target || !wait_list_item)
@@ -377,6 +389,11 @@ pocl_create_event_sync (cl_event notifier_event, cl_event waiting_event)
377389

378390
notify_target->event = waiting_event;
379391
wait_list_item->event = notifier_event;
392+
/* Retain the waiting_event since we hold a reference to it in the notify
393+
list. This is not needed for the wait_list since the only purpose is to
394+
keep a count of the number of events it's waiting on.
395+
*/
396+
POCL_RETAIN_OBJECT_UNLOCKED (waiting_event);
380397
LL_PREPEND (notifier_event->notify_list, notify_target);
381398
LL_PREPEND (waiting_event->wait_list, wait_list_item);
382399

@@ -1980,14 +1997,14 @@ pocl_update_event_finished (cl_int status, const char *func, unsigned line,
19801997
{
19811998
assert (event != NULL);
19821999
assert (event->queue != NULL);
1983-
assert (event->status > CL_COMPLETE);
19842000
int notify_cmdq = CL_FALSE;
19852001
cl_command_buffer_khr command_buffer = NULL;
19862002
_cl_command_node *node = NULL;
19872003

19882004
cl_command_queue cq = event->queue;
19892005
POCL_LOCK_OBJ (cq);
19902006
POCL_LOCK_OBJ (event);
2007+
assert (event->status > CL_COMPLETE);
19912008
if ((cq->properties & CL_QUEUE_PROFILING_ENABLE)
19922009
&& (cq->device->has_own_timer == 0))
19932010
event->time_end = pocl_gettimemono_ns ();
@@ -2064,45 +2081,6 @@ pocl_update_event_finished (cl_int status, const char *func, unsigned line,
20642081

20652082
ops->broadcast (event);
20662083

2067-
#ifdef ENABLE_REMOTE_CLIENT
2068-
/* With remote being asynchronous it is possible that an event completion
2069-
* signal is received before some of its dependencies. Therefore this event
2070-
* has to be removed from the notify lists of any remaining events in the
2071-
* wait list.
2072-
*
2073-
* Mind the acrobatics of trying to avoid races with pocl_broadcast and
2074-
* pocl_create_event_sync. */
2075-
event_node *tmp;
2076-
POCL_LOCK_OBJ (event);
2077-
while ((tmp = event->wait_list))
2078-
{
2079-
cl_event notifier = tmp->event;
2080-
POCL_UNLOCK_OBJ (event);
2081-
pocl_lock_events_inorder (notifier, event);
2082-
if (tmp != event->wait_list)
2083-
{
2084-
pocl_unlock_events_inorder (notifier, event);
2085-
POCL_LOCK_OBJ (event);
2086-
continue;
2087-
}
2088-
event_node *tmp2;
2089-
LL_FOREACH (notifier->notify_list, tmp2)
2090-
{
2091-
if (tmp2->event == event)
2092-
{
2093-
LL_DELETE (notifier->notify_list, tmp2);
2094-
pocl_mem_manager_free_event_node (tmp2);
2095-
break;
2096-
}
2097-
}
2098-
LL_DELETE (event->wait_list, tmp);
2099-
pocl_unlock_events_inorder (notifier, event);
2100-
pocl_mem_manager_free_event_node (tmp);
2101-
POCL_LOCK_OBJ (event);
2102-
}
2103-
POCL_UNLOCK_OBJ (event);
2104-
#endif
2105-
21062084
#ifdef POCL_DEBUG_MESSAGES
21072085
if (msg != NULL)
21082086
{

0 commit comments

Comments
 (0)