[Beignet] [PATCH] Refine clSetMemObjectDestructorCallback API

junyan.he at inbox.com junyan.he at inbox.com
Thu Oct 13 10:54:36 UTC 2016


From: Junyan He <junyan.he at intel.com>

Signed-off-by: Junyan He <junyan.he at intel.com>
---
 src/cl_api.c     | 24 ------------------------
 src/cl_api_mem.c | 14 ++++++++++++++
 src/cl_mem.c     | 42 ++++++++++++++++++++++++++++++++----------
 src/cl_mem.h     | 11 +++++++----
 4 files changed, 53 insertions(+), 38 deletions(-)

diff --git a/src/cl_api.c b/src/cl_api.c
index d80335e..fb1d322 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -344,30 +344,6 @@ error:
   return err;
 }
 
-cl_int
-clSetMemObjectDestructorCallback(cl_mem  memobj,
-                                 void (CL_CALLBACK *pfn_notify) (cl_mem, void*),
-                                 void * user_data)
-{
-  cl_int err = CL_SUCCESS;
-  CHECK_MEM(memobj);
-  INVALID_VALUE_IF (pfn_notify == 0);
-
-  cl_mem_dstr_cb *cb = (cl_mem_dstr_cb*)malloc(sizeof(cl_mem_dstr_cb));
-  if (!cb) {
-    err = CL_OUT_OF_HOST_MEMORY;
-    goto error;
-  }
-
-  memset(cb, 0, sizeof(cl_mem_dstr_cb));
-  cb->pfn_notify = pfn_notify;
-  cb->user_data = user_data;
-  cb->next = memobj->dstr_cb;
-  memobj->dstr_cb = cb;
-
-error:
-  return err;
-}
 
 cl_program
 clCreateProgramWithSource(cl_context     context,
diff --git a/src/cl_api_mem.c b/src/cl_api_mem.c
index 7f04637..6635c3a 100644
--- a/src/cl_api_mem.c
+++ b/src/cl_api_mem.c
@@ -2435,3 +2435,17 @@ clReleaseMemObject(cl_mem memobj)
   cl_mem_delete(memobj);
   return CL_SUCCESS;
 }
+
+cl_int
+clSetMemObjectDestructorCallback(cl_mem memobj,
+                                 void(CL_CALLBACK *pfn_notify)(cl_mem, void *),
+                                 void *user_data)
+{
+  if (!CL_OBJECT_IS_MEM(memobj))
+    return CL_INVALID_MEM_OBJECT;
+
+  if (pfn_notify == NULL)
+    return CL_INVALID_VALUE;
+
+  return cl_mem_set_destructor_callback(memobj, pfn_notify, user_data);
+}
diff --git a/src/cl_mem.c b/src/cl_mem.c
index 57ea003..4830447 100644
--- a/src/cl_mem.c
+++ b/src/cl_mem.c
@@ -94,6 +94,7 @@ cl_mem_allocate(enum cl_mem_type type,
   }
 
   CL_OBJECT_INIT_BASE(mem, CL_OBJECT_MEM_MAGIC);
+  list_init(&mem->dstr_cb_head);
   mem->type = type;
   mem->flags = flags;
   mem->is_userptr = 0;
@@ -391,6 +392,7 @@ cl_mem_new_sub_buffer(cl_mem buffer,
   mem = &sub_buf->base;
 
   CL_OBJECT_INIT_BASE(mem, CL_OBJECT_MEM_MAGIC);
+  list_init(&mem->dstr_cb_head);
   mem->type = CL_MEM_SUBBUFFER_TYPE;
   mem->flags = flags;
   mem->offset = buffer->offset;
@@ -998,6 +1000,8 @@ LOCAL void
 cl_mem_delete(cl_mem mem)
 {
   cl_int i;
+  cl_mem_dstr_cb cb = NULL;
+
   if (UNLIKELY(mem == NULL))
     return;
   if (CL_OBJECT_DEC_REF(mem) > 1)
@@ -1013,6 +1017,14 @@ cl_mem_delete(cl_mem mem)
     cmrt_destroy_memory(mem);
 #endif
 
+  /* First, call all the callbacks registered by user. */
+  while (!list_empty(&mem->dstr_cb_head)) {
+    cb = list_entry(mem->dstr_cb_head.next, _cl_mem_dstr_cb, node);
+    list_del(&cb->node);
+    cb->pfn_notify(mem, cb->user_data);
+    cl_free(cb);
+  }
+
   /* iff we are a image, delete the 1d buffer if has. */
   if (IS_IMAGE(mem)) {
     if (cl_mem_image(mem)->buffer_1d) {
@@ -1045,16 +1057,6 @@ cl_mem_delete(cl_mem mem)
   if (mem->mapped_ptr)
     free(mem->mapped_ptr);
 
-  if (mem->dstr_cb) {
-    cl_mem_dstr_cb *cb = mem->dstr_cb;
-    while (mem->dstr_cb) {
-      cb = mem->dstr_cb;
-      cb->pfn_notify(mem, cb->user_data);
-      mem->dstr_cb = cb->next;
-      free(cb);
-    }
-  }
-
   /* Iff we are sub, do nothing for bo release. */
   if (mem->type == CL_MEM_SUBBUFFER_TYPE) {
     struct _cl_mem_buffer* buffer = (struct _cl_mem_buffer*)mem;
@@ -2219,3 +2221,23 @@ error:
     *mem_ptr = NULL;
   return err;
 }
+
+LOCAL cl_int
+cl_mem_set_destructor_callback(cl_mem memobj,
+                               void(CL_CALLBACK *pfn_notify)(cl_mem, void *), void *user_data)
+{
+  cl_mem_dstr_cb cb = cl_calloc(1, sizeof(_cl_mem_dstr_cb));
+  if (cb == NULL) {
+    return CL_OUT_OF_HOST_MEMORY;
+  }
+
+  memset(cb, 0, sizeof(_cl_mem_dstr_cb));
+  list_init(&cb->node);
+  cb->pfn_notify = pfn_notify;
+  cb->user_data = user_data;
+
+  CL_OBJECT_LOCK(memobj);
+  list_add(&cb->node, &memobj->dstr_cb_head, memobj->dstr_cb_head.next);
+  CL_OBJECT_UNLOCK(memobj);
+  return CL_SUCCESS;
+}
diff --git a/src/cl_mem.h b/src/cl_mem.h
index 66ab121..b913603 100644
--- a/src/cl_mem.h
+++ b/src/cl_mem.h
@@ -64,10 +64,12 @@ typedef struct _cl_mapped_ptr {
 }cl_mapped_ptr;
 
 typedef struct _cl_mem_dstr_cb {
-  struct _cl_mem_dstr_cb * next;
+  list_head node;    /* Mem callback list node */
   void (CL_CALLBACK *pfn_notify)(cl_mem memobj, void *user_data);
   void *user_data;
-}cl_mem_dstr_cb;
+} _cl_mem_dstr_cb;
+
+typedef _cl_mem_dstr_cb* cl_mem_dstr_cb;
 
 /* Used for buffers and images */
 enum cl_mem_type {
@@ -92,7 +94,7 @@ typedef  struct _cl_mem {
   int mapped_ptr_sz;        /* The array size of mapped_ptr. */
   int map_ref;              /* The mapped count. */
   uint8_t mapped_gtt;       /* This object has mapped gtt, for unmap. */
-  cl_mem_dstr_cb *dstr_cb;  /* The destroy callback. */
+  list_head dstr_cb_head;   /* All destroy callbacks. */
   uint8_t is_userptr;       /* CL_MEM_USE_HOST_PTR is enabled*/
   size_t offset;            /* offset of host_ptr to the page beginning, only for CL_MEM_USE_HOST_PTR*/
 
@@ -340,5 +342,6 @@ extern cl_mem cl_mem_new_image_from_fd(cl_context ctx,
 extern cl_int cl_mem_record_map_mem(cl_mem mem, void *ptr, void **mem_ptr, size_t offset,
                       size_t size, const size_t *origin, const size_t *region);
 
+extern cl_int cl_mem_set_destructor_callback(cl_mem memobj,
+                      void(CL_CALLBACK *pfn_notify)(cl_mem, void *), void *user_data);
 #endif /* __CL_MEM_H__ */
-
-- 
2.7.4





More information about the Beignet mailing list