summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Steckelmacher <steckdenis@yahoo.fr>2011-08-08 15:40:01 +0200
committerDenis Steckelmacher <steckdenis@yahoo.fr>2011-08-08 15:40:01 +0200
commitfddcc53e44aecd16d284b9c3b8a4eb5a37e752e7 (patch)
tree239c696c3672f79d2a759ab5de31677c68e69934
parent1a80d876947c922873b93a03e2d3b73f57d3468a (diff)
Test clEnqueueWaitForEvents, Barrier and Marker. Fix bugs.
-rw-r--r--src/api/api_enqueue.cpp3
-rw-r--r--src/core/commandqueue.cpp30
-rw-r--r--tests/test_commandqueue.cpp144
3 files changed, 159 insertions, 18 deletions
diff --git a/src/api/api_enqueue.cpp b/src/api/api_enqueue.cpp
index 589c3b6..81ffdd0 100644
--- a/src/api/api_enqueue.cpp
+++ b/src/api/api_enqueue.cpp
@@ -685,6 +685,9 @@ clEnqueueMarker(cl_command_queue command_queue,
if (!command_queue->isA(Coal::Object::T_CommandQueue))
return CL_INVALID_COMMAND_QUEUE;
+ if (!event)
+ return CL_INVALID_VALUE;
+
// Get the events in command_queue
unsigned int count;
Coal::Event **events = command_queue->events(count);
diff --git a/src/core/commandqueue.cpp b/src/core/commandqueue.cpp
index 462e777..281e5e6 100644
--- a/src/core/commandqueue.cpp
+++ b/src/core/commandqueue.cpp
@@ -7,6 +7,7 @@
#include <cstring>
#include <cstdlib>
#include <ctime>
+#include <iostream>
using namespace Coal;
@@ -146,6 +147,10 @@ void CommandQueue::flush()
void CommandQueue::finish()
{
+ // As pushEventsOnDevice doesn't remove SUCCESS events, we may need
+ // to do that here in order not to be stuck.
+ cleanEvents();
+
// All the queued events must have completed. When they are, they get
// deleted from the command queue, so simply wait for it to become empty.
pthread_mutex_lock(&p_event_list_mutex);
@@ -231,7 +236,7 @@ void CommandQueue::pushEventsOnDevice()
// - If we are in-order, only the first event in Event::Queued state can
// be pushed
- std::list<Event *>::iterator it = p_events.begin(), oldit;
+ std::list<Event *>::iterator it = p_events.begin();
bool first = true;
// We assume that we will flush the command queue (submit all the events)
@@ -258,24 +263,12 @@ void CommandQueue::pushEventsOnDevice()
break;
}
- // If we encounter a barrier, check if it's the first in the list
- if (event->type() == Event::Barrier)
+ // Stop if we encounter a barrier that isn't the first event in the list.
+ if (event->type() == Event::Barrier && !first)
{
- if (first)
- {
- // Remove the barrier, we don't need it anymore
- oldit = it;
- ++it;
-
- p_events.erase(oldit);
- continue;
- }
- else
- {
- // We have events to wait, stop
- p_flushed = false;
- break;
- }
+ // We have events to wait, stop
+ p_flushed = false;
+ break;
}
// Completed events and first barriers are out, it remains real events
@@ -490,6 +483,7 @@ bool Event::isDummy() const
void Event::setStatus(Status status)
{
+ // TODO: If status < 0, terminate all the events depending on us.
pthread_mutex_lock(&p_state_mutex);
p_status = status;
diff --git a/tests/test_commandqueue.cpp b/tests/test_commandqueue.cpp
index 1fac3eb..e361e41 100644
--- a/tests/test_commandqueue.cpp
+++ b/tests/test_commandqueue.cpp
@@ -809,6 +809,149 @@ START_TEST (test_copy_image_buffer)
}
END_TEST
+START_TEST (test_misc_events)
+{
+ cl_platform_id platform = 0;
+ cl_device_id device;
+ cl_context ctx;
+ cl_command_queue queue;
+ cl_int result;
+ cl_event uevent1, uevent2, marker1, marker2;
+
+ result = clGetDeviceIDs(platform, CL_DEVICE_TYPE_DEFAULT, 1, &device, 0);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to get the default device"
+ );
+
+ ctx = clCreateContext(0, 1, &device, 0, 0, &result);
+ fail_if(
+ result != CL_SUCCESS || ctx == 0,
+ "unable to create a valid context"
+ );
+
+ queue = clCreateCommandQueue(ctx, device, 0, &result);
+ fail_if(
+ result != CL_SUCCESS || queue == 0,
+ "cannot create a command queue"
+ );
+
+ /*
+ * This test will build a command queue blocked by an user event. The events
+ * will be in this order :
+ *
+ * -: UserEvent1
+ * 0: WaitForEvents1 (wait=UserEvent1)
+ * 1: Marker1
+ * -: UserEvent2
+ * 2: WaitForEvents2 (wait=UserEvent2)
+ * 3: Barrier
+ * 4: Marker2 (to check the barrier worked)
+ *
+ * When the command queue is built, we :
+ * - Check that Marker1 is Queued (WaitForEvents waits)
+ * - Set UserEvent1 to Complete
+ * - Check that Marker1 is Complete (WaitForEvents stopped to wait)
+ * - Check that Marker2 is Queued (Barrier is there)
+ * - Set UserEvent2 to Complete
+ * - Check that Marker2 is Complete (no more barrier)
+ */
+ uevent1 = clCreateUserEvent(ctx, &result);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to create UserEvent1"
+ );
+
+ uevent2 = clCreateUserEvent(ctx, &result);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to create UserEvent2"
+ );
+
+ result = clEnqueueWaitForEvents(queue, 1, &uevent1);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to enqueue WaitForEvents(UserEvent1)"
+ );
+
+ result = clEnqueueMarker(queue, &marker1);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to enqueue Marker1"
+ );
+
+ result = clEnqueueWaitForEvents(queue, 1, &uevent2);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to enqueue WaitForEvents(UserEvent2)"
+ );
+
+ result = clEnqueueBarrier(queue);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to enqueue Barrier"
+ );
+
+ result = clEnqueueMarker(queue, &marker2);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to enqueue Marker2"
+ );
+
+ // Now the checks
+ cl_int status;
+
+ result = clGetEventInfo(marker1, CL_EVENT_COMMAND_EXECUTION_STATUS,
+ sizeof(cl_int), &status, 0);
+ fail_if(
+ result != CL_SUCCESS || status != CL_QUEUED,
+ "Marker1 must be Queued"
+ );
+
+ result = clSetUserEventStatus(uevent1, CL_COMPLETE);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to set UserEvent1 to Complete"
+ );
+
+ result = clGetEventInfo(marker1, CL_EVENT_COMMAND_EXECUTION_STATUS,
+ sizeof(cl_int), &status, 0);
+ fail_if(
+ result != CL_SUCCESS || status != CL_COMPLETE,
+ "Marker1 must be Complete"
+ );
+
+ result = clGetEventInfo(marker2, CL_EVENT_COMMAND_EXECUTION_STATUS,
+ sizeof(cl_int), &status, 0);
+ fail_if(
+ result != CL_SUCCESS || status != CL_QUEUED,
+ "Marker2 must be Queued"
+ );
+
+ result = clSetUserEventStatus(uevent2, CL_COMPLETE);
+ fail_if(
+ result != CL_SUCCESS,
+ "unable to set UserEvent2 to Complete"
+ );
+
+ result = clGetEventInfo(marker2, CL_EVENT_COMMAND_EXECUTION_STATUS,
+ sizeof(cl_int), &status, 0);
+ fail_if(
+ result != CL_SUCCESS || status != CL_COMPLETE,
+ "Marker2 must be Complete"
+ );
+
+ clFinish(queue);
+
+ clReleaseEvent(uevent1);
+ clReleaseEvent(uevent2);
+ clReleaseEvent(marker1);
+ clReleaseEvent(marker2);
+ clReleaseCommandQueue(queue);
+ clReleaseContext(ctx);
+}
+END_TEST
+
TCase *cl_commandqueue_tcase_create(void)
{
TCase *tc = NULL;
@@ -821,5 +964,6 @@ TCase *cl_commandqueue_tcase_create(void)
tcase_add_test(tc, test_copy_buffer);
tcase_add_test(tc, test_read_write_image);
tcase_add_test(tc, test_copy_image_buffer);
+ tcase_add_test(tc, test_misc_events);
return tc;
}