summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunyan He <junyan.he@intel.com>2016-04-27 09:49:58 +0800
committerJunyan He <junyan.he@intel.com>2016-04-27 09:49:58 +0800
commit3b538c2a6896bc404451383b992b956058ee0d4d (patch)
tree1a3e61ac7fd009a221fcf75f764b7c30baff0bcd
parent04b7ba95da781db41c2747e889e00287d83770a8 (diff)
event call without lock
-rw-r--r--libclapi/cl_enqueue.c1
-rw-r--r--libclapi/cl_event.c45
-rw-r--r--libclapi/cl_mem.c31
3 files changed, 67 insertions, 10 deletions
diff --git a/libclapi/cl_enqueue.c b/libclapi/cl_enqueue.c
index 991d29d0..2cffa30c 100644
--- a/libclapi/cl_enqueue.c
+++ b/libclapi/cl_enqueue.c
@@ -73,7 +73,6 @@ static void set_work_item_status(cl_command_queue_work_item it, cl_int status)
cl_event_set_status(it->event, status);
}
-
/* Return 0 means still not ready, 1 means ready, -1 means err and need to cancel. */
static cl_int check_work_item_ready(cl_command_queue_work_item item)
{
diff --git a/libclapi/cl_event.c b/libclapi/cl_event.c
index c7a54552..228e5e59 100644
--- a/libclapi/cl_event.c
+++ b/libclapi/cl_event.c
@@ -42,6 +42,7 @@ LOCAL cl_int cl_event_get_status(cl_event event)
LOCAL cl_int cl_event_set_status(cl_event event, cl_int status)
{
cl_event_user_cb user_cb = NULL;
+ cl_event_user_cb saved_user_cb = NULL;
cl_command_queue* queue_array = NULL;
cl_command_queue q = NULL;
int queue_num = 0;
@@ -53,15 +54,16 @@ LOCAL cl_int cl_event_set_status(cl_event event, cl_int status)
assert(!IS_BARRIER_EVENT(event));
CL_MUTEX_LOCK(&event->lock);
+ if (event->status <= CL_COMPLETE) { // Already set
+ CL_MUTEX_UNLOCK(&event->lock);
+ return CL_INVALID_OPERATION;
+ }
+
if (event->user_event) {
assert(event->status != CL_RUNNING && event->status != CL_QUEUED);
- if (event->status <= CL_COMPLETE) { // Already set
- CL_MUTEX_UNLOCK(&event->lock);
- return CL_INVALID_OPERATION;
- }
} else {
assert(event->queue);
- if (status >= event->status) { //Should never go back.
+ if (status >= event->status) { // Should never go back.
CL_MUTEX_UNLOCK(&event->lock);
return CL_INVALID_OPERATION;
}
@@ -69,19 +71,44 @@ LOCAL cl_int cl_event_set_status(cl_event event, cl_int status)
event->status = status;
+CALLBACK_AGAIN:
+
/* Call all the callbacks. */
- user_cb = event->user_cb;
+ saved_user_cb = user_cb = event->user_cb;
+ event->user_cb = NULL; // Set it to NULL, temp
+ CL_MUTEX_UNLOCK(&event->lock);
+
+ /* We call all the callbacks without mutex. */
while (user_cb) {
- if (user_cb->status < event->status)
+ if (user_cb->status < status)
continue;
if (user_cb->executed)
continue;
user_cb->executed = CL_TRUE;
- user_cb->pfn_notify(event, event->status, user_cb->user_data);
+ user_cb->pfn_notify(event, status, user_cb->user_data);
user_cb = user_cb->next;
}
+
+ CL_MUTEX_LOCK(&event->lock);
+ // Set back the callbacks.
+ if (event->user_cb) { // Some one set it before we get the lock again.
+ user_cb = event->user_cb;
+ while (user_cb->next)
+ user_cb = user_cb->next;
+
+ user_cb->next = saved_user_cb;
+ } else {
+ event->user_cb = user_cb;
+ }
+
+ if (status != event->status) { // Someone changed the status, so check again.
+ assert(status > event->status); // Should never set back.
+ status = event->status;
+ goto CALLBACK_AGAIN;
+ }
+
CL_MUTEX_UNLOCK(&event->lock);
if (status > CL_COMPLETE) // For event still pending, nothing to do further.
@@ -621,11 +648,11 @@ static cl_int cl_event_set_callback(cl_event event , cl_int exec_type,
} else {
/* The state has already OK, call it immediately. */
exec_imm = CL_TRUE;
- cb->pfn_notify(event, event->status, cb->user_data);
}
CL_MUTEX_UNLOCK(&event->lock);
if (exec_imm) {
+ cb->pfn_notify(event, event->status, cb->user_data);
CL_FREE(cb);
}
diff --git a/libclapi/cl_mem.c b/libclapi/cl_mem.c
index f74b0911..0eebf6e8 100644
--- a/libclapi/cl_mem.c
+++ b/libclapi/cl_mem.c
@@ -525,6 +525,7 @@ static void* cl_enqueue_map_buffer(cl_command_queue queue, cl_mem buffer, cl_boo
const cl_event *event_list, cl_event *event_ret, cl_int *errcode_ret)
{
cl_event event = NULL;
+ cl_command_queue_work_item it = NULL;
cl_int err = CL_SUCCESS;
void *mem_ptr = NULL;
cl_int index;
@@ -534,12 +535,40 @@ static void* cl_enqueue_map_buffer(cl_command_queue queue, cl_mem buffer, cl_boo
if (event == NULL)
goto error;
}
+#if 0
+ if (blocking_map) {
+ /* According to spec, when in block mode, we need to ensure all the
+ commands in queue are flushed. */
+ err = cl_enqueue_wait_for_flush(queue);
+ if (err != CL_SUCCESS)
+ goto error;
+
+ if (event_list) { // Need to wait for events.
+ if (cl_enqueue_wait_for_events(event_list, num_events) == false) {
+ /* canceled or some errors. */
+ return CL_MAP_FAILURE;
+ }
+ }
+ }
+
+
+ it = cl_enqueue_create_work_item(queue, num_events, event_list, event);
+ if (it == NULL) {
+ err = CL_OUT_OF_HOST_MEMORY;
+ goto error;
+ }
err = queue->device->driver->enqueue_map_buffer(queue, buffer, &mem_ptr, blocking_map, map_flags,
offset, size, num_events, event_list, event);
if (err != CL_SUCCESS)
goto error;
+
+
+
+
+#endif
+
/* We need to store the map info for unmap and debug. */
err = cl_record_mapped(buffer, mem_ptr, offset, size, NULL, NULL);
if (err != CL_SUCCESS) {
@@ -561,6 +590,8 @@ static void* cl_enqueue_map_buffer(cl_command_queue queue, cl_mem buffer, cl_boo
return mem_ptr;
error:
+ if (it)
+ cl_enqueue_destroy_work_item(queue, it);
if (errcode_ret)
*errcode_ret = err;
if (event)