diff options
author | Junyan He <junyan.he@intel.com> | 2016-04-27 09:49:58 +0800 |
---|---|---|
committer | Junyan He <junyan.he@intel.com> | 2016-04-27 09:49:58 +0800 |
commit | 3b538c2a6896bc404451383b992b956058ee0d4d (patch) | |
tree | 1a3e61ac7fd009a221fcf75f764b7c30baff0bcd | |
parent | 04b7ba95da781db41c2747e889e00287d83770a8 (diff) |
event call without lock
-rw-r--r-- | libclapi/cl_enqueue.c | 1 | ||||
-rw-r--r-- | libclapi/cl_event.c | 45 | ||||
-rw-r--r-- | libclapi/cl_mem.c | 31 |
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) |