@@ -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