[Beignet] [PATCH 2/2] runtime: fix some subtle event bugs.

Yang, Rong R rong.r.yang at intel.com
Thu Jul 10 22:51:24 PDT 2014


The patchset LGTM, thanks.

> -----Original Message-----
> From: Beignet [mailto:beignet-bounces at lists.freedesktop.org] On Behalf Of
> Zhigang Gong
> Sent: Friday, July 11, 2014 10:18 AM
> To: beignet at lists.freedesktop.org
> Cc: Gong, Zhigang
> Subject: [Beignet] [PATCH 2/2] runtime: fix some subtle event bugs.
> 
> This patch fix the following two bugs in event handling.
> 1. When it's time to call a event's user call back function, we need to
>    set the executed to true before the call. As that call back function
>    may call into clReleaseEvent(), and if we don't set the executed status
>    to true, it will enter infinite recursive loop.
> 
> 2. After the user call clEnqueueNDRangeKernel to get a valid event, the
>    user set a call back function to that event, and in that call back
>    function, it will release that event. This scenario is totally correct.
>    But our current event handling doesn't have a deadicated timer thread to
>    update those on-the-fly events' status. Thus those events will not have
>    a chance to get updated, and those call back function will not executed
>    forever. To introduce a complete timer style thread to maintain this type
>    of events is too heavy for this fix release. This patch choose an easy
>    way to work around it. It will make sure the last gpgpu event to be finished
>    before current task to be enqueued.
> 
> After this patch, most of the OpenCV 3.0 cases could run smoothly without any
> serious issue.
> 
> Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
> ---
>  src/cl_api.c           |  2 +-
>  src/cl_command_queue.c | 11 +++++++++++
>  src/cl_event.c         | 12 ++++++------
>  src/cl_event.h         |  2 +-
>  4 files changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/src/cl_api.c b/src/cl_api.c index 8759027..177a7e8 100644
> --- a/src/cl_api.c
> +++ b/src/cl_api.c
> @@ -1365,7 +1365,7 @@ clGetEventInfo(cl_event      event,
>    } else if (param_name == CL_EVENT_COMMAND_TYPE) {
>      FILL_GETINFO_RET (cl_command_type, 1, &event->type, CL_SUCCESS);
>    } else if (param_name == CL_EVENT_COMMAND_EXECUTION_STATUS) {
> -    cl_event_update_status(event);
> +    cl_event_update_status(event, 0);
>      FILL_GETINFO_RET (cl_int, 1, &event->status, CL_SUCCESS);
>    } else if (param_name == CL_EVENT_REFERENCE_COUNT) {
>      cl_uint ref = event->ref_n;
> diff --git a/src/cl_command_queue.c b/src/cl_command_queue.c index
> d9718bf..d45e92f 100644
> --- a/src/cl_command_queue.c
> +++ b/src/cl_command_queue.c
> @@ -75,6 +75,10 @@ cl_command_queue_delete(cl_command_queue queue)
>    assert(queue);
>    if (atomic_dec(&queue->ref_n) != 1) return;
> 
> +  // If there is a valid last event, we need to give it a chance to  //
> + call the call-back function.
> +  if (queue->last_event && queue->last_event->user_cb)
> +    cl_event_update_status(queue->last_event, 1);
>    /* Remove it from the list */
>    assert(queue->ctx);
>    pthread_mutex_lock(&queue->ctx->queue_lock);
> @@ -454,6 +458,13 @@ cl_command_queue_flush(cl_command_queue
> queue)  {
>    GET_QUEUE_THREAD_GPGPU(queue);
>    cl_command_queue_flush_gpgpu(queue, gpgpu);
> +  // As we don't have a deadicate timer thread to take care the
> + possible  // event which has a call back function registerred and the
> + event will  // be released at the call back function, no other
> + function will access  // the event any more. If we don't do this here,
> + we will leak that event  // and all the corresponding buffers which is really
> bad.
> +  if (queue->last_event && queue->last_event->user_cb)
> +    cl_event_update_status(queue->last_event, 1);
>    if (queue->current_event)
>      cl_event_flush(queue->current_event);
>    cl_invalid_thread_gpgpu(queue);
> diff --git a/src/cl_event.c b/src/cl_event.c index d40881a..99e60eb 100644
> --- a/src/cl_event.c
> +++ b/src/cl_event.c
> @@ -55,6 +55,7 @@ void cl_event_flush(cl_event event)
>      event->gpgpu = NULL;
>    }
>    cl_gpgpu_event_flush(event->gpgpu_event);
> +  event->queue->last_event = event;
>  }
> 
>  cl_event cl_event_new(cl_context ctx, cl_command_queue queue,
> cl_command_type type, cl_bool emplict) @@ -95,8 +96,6 @@ cl_event
> cl_event_new(cl_context ctx, cl_command_queue queue, cl_command_type ty
>    event->enqueue_cb = NULL;
>    event->waits_head = NULL;
>    event->emplict = emplict;
> -  if(queue && event->gpgpu_event)
> -    queue->last_event = event;
> 
>  exit:
>    return event;
> @@ -111,7 +110,7 @@ void cl_event_delete(cl_event event)
>    if (UNLIKELY(event == NULL))
>      return;
> 
> -  cl_event_update_status(event);
> +  cl_event_update_status(event, 0);
> 
>    if (atomic_dec(&event->ref_n) > 1)
>      return;
> @@ -124,6 +123,7 @@ void cl_event_delete(cl_event event)
>    while(event->user_cb) {
>      cb = event->user_cb;
>      if(cb->executed == CL_FALSE) {
> +      cb->executed = CL_TRUE;
>        cb->pfn_notify(event, event->status, cb->user_data);
>      }
>      event->user_cb = cb->next;
> @@ -443,8 +443,8 @@ void cl_event_set_status(cl_event event, cl_int status)
>    user_cb = event->user_cb;
>    while(user_cb) {
>      if(user_cb->status >= status) {
> -      user_cb->pfn_notify(event, event->status, user_cb->user_data);
>        user_cb->executed = CL_TRUE;
> +      user_cb->pfn_notify(event, event->status, user_cb->user_data);
>      }
>      user_cb = user_cb->next;
>    }
> @@ -492,12 +492,12 @@ void cl_event_set_status(cl_event event, cl_int
> status)
>    event->waits_head = NULL;
>  }
> 
> -void cl_event_update_status(cl_event event)
> +void cl_event_update_status(cl_event event, int wait)
>  {
>    if(event->status <= CL_COMPLETE)
>      return;
>    if((event->gpgpu_event) &&
> -     (cl_gpgpu_event_update_status(event->gpgpu_event, 0) ==
> command_complete))
> +     (cl_gpgpu_event_update_status(event->gpgpu_event, wait) ==
> + command_complete))
>      cl_event_set_status(event, CL_COMPLETE);  }
> 
> diff --git a/src/cl_event.h b/src/cl_event.h index 3c23d74..cfe5ddd 100644
> --- a/src/cl_event.h
> +++ b/src/cl_event.h
> @@ -89,7 +89,7 @@ void cl_event_new_enqueue_callback(cl_event,
> enqueue_data *, cl_uint, const cl_e
>  /* Set the event status and call all callbacks */  void
> cl_event_set_status(cl_event, cl_int);
>  /* Check and update event status */
> -void cl_event_update_status(cl_event);
> +void cl_event_update_status(cl_event, cl_int);
>  /* Create the marker event */
>  cl_int cl_event_marker_with_wait_list(cl_command_queue, cl_uint, const
> cl_event *,  cl_event*);
>  /* Create the barrier event */
> --
> 1.8.3.2
> 
> _______________________________________________
> Beignet mailing list
> Beignet at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/beignet


More information about the Beignet mailing list