[Beignet] [PATCH] Modify the multi-thread support for queue.

Zhigang Gong zhigang.gong at linux.intel.com
Mon Dec 30 19:29:34 PST 2013


Junyan, this patch introduces one regression:

compiler_cl_finish:
  compiler_cl_finish()    [FAILED]
    Error: t_fin > t_map_w_fin && t_map_wo_fin > t_map_w_fin
  at file /home/gongzg/git/fdo/beignet/utests/compiler_cl_finish.cpp, function compiler_cl_finish, line 46

could you look into it? Thanks.

On Wed, Dec 25, 2013 at 03:02:19PM +0800, junyan.he at inbox.com wrote:
> From: Junyan He <junyan.he at linux.intel.com>
> 
> The old multi-thread support for queue do not work
> when threads will not exit. If the thread not exit
> but the queue is re-generated all the time, the
> gpgpu struct resouce will leak, and will fail to
> create GPU bo for gpgpu struct finally.
> We modify it to release the GPGPU resource every
> enqueuNDR finished and we re-alloc our gpgpu struct
> context next time.
> 
> Signed-off-by: Junyan He <junyan.he at linux.intel.com>
> ---
>  src/cl_command_queue.c |  2 ++
>  src/cl_thread.c        | 60 ++++++++++++++++++++++++++++++++++++++++----------
>  src/cl_thread.h        |  4 ++++
>  3 files changed, 54 insertions(+), 12 deletions(-)
> 
> diff --git a/src/cl_command_queue.c b/src/cl_command_queue.c
> index 3530976..6e7c1a3 100644
> --- a/src/cl_command_queue.c
> +++ b/src/cl_command_queue.c
> @@ -419,6 +419,8 @@ cl_command_queue_flush(cl_command_queue queue)
>    GET_QUEUE_THREAD_GPGPU(queue);
>  
>    cl_gpgpu_flush(gpgpu);
> +
> +  cl_invalid_thread_gpgpu(queue);
>    return CL_SUCCESS;
>  }
>  
> diff --git a/src/cl_thread.c b/src/cl_thread.c
> index fbad5c5..894af9d 100644
> --- a/src/cl_thread.c
> +++ b/src/cl_thread.c
> @@ -20,30 +20,56 @@
>  #include "cl_alloc.h"
>  #include "cl_utils.h"
>  
> +typedef struct _cl_thread_spec_data {
> +  cl_gpgpu gpgpu ;
> +  int valid;
> +}cl_thread_spec_data;
> +
>  cl_gpgpu cl_get_thread_gpgpu(cl_command_queue queue)
>  {
>    pthread_key_t* key = queue->thread_data;
> -  cl_gpgpu gpgpu = pthread_getspecific(*key);
> +  cl_thread_spec_data* thread_spec_data = pthread_getspecific(*key);
>  
> -  if (!gpgpu) {
> -    TRY_ALLOC_NO_ERR (gpgpu, cl_gpgpu_new(queue->ctx->drv));
> +  if (!thread_spec_data) {
> +    TRY_ALLOC_NO_ERR(thread_spec_data, CALLOC(struct _cl_thread_spec_data));
> +    if (pthread_setspecific(*key, thread_spec_data)) {
> +      cl_free(thread_spec_data);
> +      return NULL;
> +    }
>    }
>  
> -  if (pthread_setspecific(*key, gpgpu)) {
> -    cl_gpgpu_delete(gpgpu);
> -    goto error;
> +  if (!thread_spec_data->valid) {
> +    TRY_ALLOC_NO_ERR(thread_spec_data->gpgpu, cl_gpgpu_new(queue->ctx->drv));
> +    thread_spec_data->valid = 1;
>    }
>  
> -exit:
> -  return gpgpu;
>  error:
> -  pthread_setspecific(*key, NULL);
> -  goto exit;
> +  return thread_spec_data->gpgpu;
> +}
> +
> +void cl_invalid_thread_gpgpu(cl_command_queue queue)
> +{
> +  pthread_key_t* key = queue->thread_data;
> +  cl_thread_spec_data* thread_spec_data = pthread_getspecific(*key);
> +
> +  if (!thread_spec_data) {
> +    return;
> +  }
> +
> +  if (!thread_spec_data->valid) {
> +    return;
> +  }
> +
> +  assert(thread_spec_data->gpgpu);
> +  cl_gpgpu_delete(thread_spec_data->gpgpu);
> +  thread_spec_data->valid = 0;
>  }
>  
>  static void thread_data_destructor(void *data) {
> -  cl_gpgpu gpgpu = (cl_gpgpu)data;
> -  cl_gpgpu_delete(gpgpu);
> +  cl_thread_spec_data* thread_spec_data = (cl_thread_spec_data *)data;
> +  if (thread_spec_data->valid)
> +    cl_gpgpu_delete(thread_spec_data->gpgpu);
> +  cl_free(thread_spec_data);
>  }
>  
>  /* Create the thread specific data. */
> @@ -67,6 +93,16 @@ void* cl_thread_data_create(void)
>  void cl_thread_data_destroy(void * data)
>  {
>    pthread_key_t *thread_specific_key = (pthread_key_t *)data;
> +
> +  /* First release self spec data. */
> +  cl_thread_spec_data* thread_spec_data =
> +         pthread_getspecific(*thread_specific_key);
> +  if (thread_spec_data && thread_spec_data->valid) {
> +    cl_gpgpu_delete(thread_spec_data->gpgpu);
> +    if (thread_spec_data)
> +      cl_free(thread_spec_data);
> +  }
> +
>    pthread_key_delete(*thread_specific_key);
>    cl_free(thread_specific_key);
>  }
> diff --git a/src/cl_thread.h b/src/cl_thread.h
> index 65f1bcf..f69c562 100644
> --- a/src/cl_thread.h
> +++ b/src/cl_thread.h
> @@ -31,4 +31,8 @@ void cl_thread_data_destroy(void * data);
>  
>  /* Used to get the gpgpu struct of each thread. */
>  cl_gpgpu cl_get_thread_gpgpu(cl_command_queue queue);
> +
> +/* Used to release the gpgpu struct of each thread. */
> +void cl_invalid_thread_gpgpu(cl_command_queue queue);
> +
>  #endif /* __CL_THREAD_H__ */
> -- 
> 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