From: Junyan He <[email protected]> When a event complete, we need to notify all the command_queue within the same context. But sometime, some command_queue in the context is already invalid. Modify to ensure all the command_queue to be notified are valid.
Signed-off-by: Junyan He <[email protected]> --- src/cl_command_queue.c | 12 ++---------- src/cl_context.c | 11 ++++++++--- src/cl_context.h | 2 +- src/cl_event.c | 50 ++++++++++++++++---------------------------------- 4 files changed, 27 insertions(+), 48 deletions(-) diff --git a/src/cl_command_queue.c b/src/cl_command_queue.c index 2d66550..aa371d0 100644 --- a/src/cl_command_queue.c +++ b/src/cl_command_queue.c @@ -81,19 +81,11 @@ cl_command_queue_delete(cl_command_queue queue) if (CL_OBJECT_DEC_REF(queue) > 1) return; - cl_command_queue_destroy_enqueue(queue); - -#ifdef HAS_CMRT - if (queue->cmrt_event != NULL) - cmrt_destroy_event(queue); -#endif + cl_context_remove_queue(queue->ctx, queue); - // If there is a list of valid events, we need to give them - // a chance to call the call-back function. - //cl_event_update_last_events(queue,1); + cl_command_queue_destroy_enqueue(queue); cl_mem_delete(queue->perf); - cl_context_remove_queue(queue->ctx, queue); if (queue->barrier_events) { cl_free(queue->barrier_events); } diff --git a/src/cl_context.c b/src/cl_context.c index 65e7909..3f2e757 100644 --- a/src/cl_context.c +++ b/src/cl_context.c @@ -46,9 +46,11 @@ cl_context_add_queue(cl_context ctx, cl_command_queue queue) { cl_context_add_ref(ctx); CL_OBJECT_LOCK(ctx); + while (ctx->queue_modify_disable) { + CL_OBJECT_WAIT_ON_COND(ctx); + } list_add_tail(&ctx->queues, &queue->base.node); ctx->queue_num++; - ctx->queue_cookie++; CL_OBJECT_UNLOCK(ctx); queue->ctx = ctx; @@ -57,10 +59,13 @@ cl_context_add_queue(cl_context ctx, cl_command_queue queue) { LOCAL void cl_context_remove_queue(cl_context ctx, cl_command_queue queue) { assert(queue->ctx == ctx); + CL_OBJECT_LOCK(ctx); + while (ctx->queue_modify_disable) { + CL_OBJECT_WAIT_ON_COND(ctx); + } list_node_del(&queue->base.node); ctx->queue_num--; - ctx->queue_cookie++; CL_OBJECT_UNLOCK(ctx); cl_context_delete(ctx); @@ -333,7 +338,7 @@ cl_context_new(struct _cl_context_prop *props, cl_uint dev_num, cl_device_id* al list_init(&ctx->samplers); list_init(&ctx->events); list_init(&ctx->programs); - ctx->queue_cookie = 1; + ctx->queue_modify_disable = CL_FALSE; TRY_ALLOC_NO_ERR (ctx->drv, cl_driver_new(props)); ctx->props = *props; ctx->ver = cl_driver_get_ver(ctx->drv); diff --git a/src/cl_context.h b/src/cl_context.h index 9820b6e..4812afd 100644 --- a/src/cl_context.h +++ b/src/cl_context.h @@ -105,7 +105,7 @@ struct _cl_context { cl_uint device_num; /* Devices number of this context */ list_head queues; /* All command queues currently allocated */ cl_uint queue_num; /* All queue number currently allocated */ - cl_uint queue_cookie; /* Cookie will change every time we change queue list. */ + cl_uint queue_modify_disable; /* Temp disable queue list change. */ list_head mem_objects; /* All memory object currently allocated */ cl_uint mem_object_num; /* All memory number currently allocated */ list_head samplers; /* All sampler object currently allocated */ diff --git a/src/cl_event.c b/src/cl_event.c index 4dcc728..3e1dc22 100644 --- a/src/cl_event.c +++ b/src/cl_event.c @@ -428,10 +428,7 @@ cl_event_set_status(cl_event event, cl_int status) /* Need to notify all the command queue within the same context. */ if (notify_queue) { - cl_command_queue *q_list = NULL; - cl_uint queue_num = 0; - int i = 0; - int cookie = 0; + cl_command_queue queue = NULL; /*First, we need to remove it from queue's barrier list. */ if (CL_EVENT_IS_BARRIER(event)) { @@ -441,37 +438,22 @@ cl_event_set_status(cl_event event, cl_int status) /* Then, notify all the queues within the same context. */ CL_OBJECT_LOCK(event->ctx); - do { - queue_num = event->ctx->queue_num; - cookie = event->ctx->queue_cookie; - - if (queue_num > 0) { - q_list = cl_calloc(queue_num, sizeof(cl_command_queue)); - assert(q_list); - i = 0; - list_for_each(pos, &event->ctx->queues) - { - q_list[i] = (cl_command_queue)(list_entry(pos, _cl_base_object, node)); - assert(i < queue_num); - i++; - } - - CL_OBJECT_UNLOCK(event->ctx); // Update status without context lock. - - for (i = 0; i < queue_num; i++) { - cl_command_queue_notify(q_list[i]); - } - - CL_OBJECT_LOCK(event->ctx); // Lock again. - } else { - /* No queue? Just do nothing. */ - } - - } while (cookie != event->ctx->queue_cookie); // Some queue may be added when we unlock. + /* Disable remove and add queue to the context temporary. We need to + make sure all the queues in the context currently are valid. */ + event->ctx->queue_modify_disable++; + CL_OBJECT_UNLOCK(event->ctx); + list_for_each(pos, &event->ctx->queues) + { + queue = (cl_command_queue)(list_entry(pos, _cl_base_object, node)); + assert(queue != NULL); + cl_command_queue_notify(queue); + } + CL_OBJECT_LOCK(event->ctx); + /* Disable remove and add queue to the context temporary. We need to + make sure all the queues in the context currently are valid. */ + event->ctx->queue_modify_disable--; + CL_OBJECT_NOTIFY_COND(event->ctx); CL_OBJECT_UNLOCK(event->ctx); - - if (q_list) - cl_free(q_list); } return CL_SUCCESS; -- 2.7.4 _______________________________________________ Beignet mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/beignet
