From 2fec4e2e82e686006b94705c057da9dac7a6b1fe Mon Sep 17 00:00:00 2001 From: Denis Steckelmacher Date: Tue, 2 Aug 2011 13:59:17 +0200 Subject: Untested implementation of clEnqueueBarrier, clEnqueueMarker and clEnqueueWaitForEvents. --- src/api/api_enqueue.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++++--- src/core/commandqueue.cpp | 37 +++++++++++++++++++++++++++++ src/core/commandqueue.h | 5 +++- src/core/events.cpp | 44 +++++++++++++++++++++++++++++++++++ src/core/events.h | 31 +++++++++++++++++++++++++ 5 files changed, 172 insertions(+), 4 deletions(-) diff --git a/src/api/api_enqueue.cpp b/src/api/api_enqueue.cpp index 39b07b5..821e8f2 100644 --- a/src/api/api_enqueue.cpp +++ b/src/api/api_enqueue.cpp @@ -3,6 +3,8 @@ #include #include +#include + static inline cl_int queueEvent(Coal::CommandQueue *queue, Coal::Event *command, cl_event *event, @@ -660,7 +662,29 @@ cl_int clEnqueueMarker(cl_command_queue command_queue, cl_event * event) { - return 0; + cl_int rs = CL_SUCCESS; + + if (!command_queue) + return CL_INVALID_COMMAND_QUEUE; + + // Get the events in command_queue + unsigned int count; + Coal::Event **events = command_queue->events(count); + + Coal::MarkerEvent *command = new Coal::MarkerEvent( + (Coal::CommandQueue *)command_queue, + count, (const Coal::Event **)events, &rs); + + if (rs != CL_SUCCESS) + { + delete command; + return rs; + } + + // Free events, they were memcpyed by Coal::Event + std::free(events); + + return queueEvent(command_queue, command, event, false); } cl_int @@ -668,11 +692,40 @@ clEnqueueWaitForEvents(cl_command_queue command_queue, cl_uint num_events, const cl_event * event_list) { - return 0; + cl_int rs = CL_SUCCESS; + + if (!command_queue) + return CL_INVALID_COMMAND_QUEUE; + + Coal::WaitForEventsEvent *command = new Coal::WaitForEventsEvent( + (Coal::CommandQueue *)command_queue, + num_events, (const Coal::Event **)event_list, &rs); + + if (rs != CL_SUCCESS) + { + delete command; + return rs; + } + + return queueEvent(command_queue, command, 0, false); } cl_int clEnqueueBarrier(cl_command_queue command_queue) { - return 0; + cl_int rs = CL_SUCCESS; + + if (!command_queue) + return CL_INVALID_COMMAND_QUEUE; + + Coal::BarrierEvent *command = new Coal::BarrierEvent( + (Coal::CommandQueue *)command_queue, &rs); + + if (rs != CL_SUCCESS) + { + delete command; + return rs; + } + + return queueEvent(command_queue, command, 0, false); } diff --git a/src/core/commandqueue.cpp b/src/core/commandqueue.cpp index 994de7b..85eb3aa 100644 --- a/src/core/commandqueue.cpp +++ b/src/core/commandqueue.cpp @@ -275,6 +275,12 @@ void CommandQueue::pushEventsOnDevice() if (skip_event) { + // If we encounter a WaitForEvents event that is not "finished", + // don't push events after it. + if (event->type() == Event::WaitForEvents) + break; + + // The event has its dependencies not already met. ++it; continue; } @@ -302,6 +308,36 @@ void CommandQueue::pushEventsOnDevice() pthread_mutex_unlock(&p_event_list_mutex); } +Event **CommandQueue::events(unsigned int &count) +{ + Event **result; + + pthread_mutex_lock(&p_event_list_mutex); + + count = p_events.size(); + result = (Event **)std::malloc(count * sizeof(Event *)); + + // Copy each event of the list into result, retaining them + unsigned int index = 0; + std::list::iterator it = p_events.begin(); + + while (it != p_events.end()) + { + result[index] = *it; + result[index]->reference(); + + ++it; + ++index; + } + + // Now result contains an immutable list of events. Even if the events + // become completed in another thread while result is used, the events + // are retained and so guaranteed to remain valid. + pthread_mutex_unlock(&p_event_list_mutex); + + return result; +} + /* * Event */ @@ -421,6 +457,7 @@ bool Event::isDummy() const case Marker: case User: case Barrier: + case WaitForEvents: return true; default: diff --git a/src/core/commandqueue.h b/src/core/commandqueue.h index 6e064fe..f162440 100644 --- a/src/core/commandqueue.h +++ b/src/core/commandqueue.h @@ -40,6 +40,8 @@ class CommandQueue : public RefCounted void pushEventsOnDevice(); void cleanEvents(); + Event **events(unsigned int &count); /*!< @note Retains all the events */ + private: Context *p_ctx; DeviceInterface *p_device; @@ -75,7 +77,8 @@ class Event : public RefCounted WriteBufferRect = CL_COMMAND_WRITE_BUFFER_RECT, CopyBufferRect = CL_COMMAND_COPY_BUFFER_RECT, User = CL_COMMAND_USER, - Barrier + Barrier, + WaitForEvents }; enum Status diff --git a/src/core/events.cpp b/src/core/events.cpp index 9bdabc6..f44c41e 100644 --- a/src/core/events.cpp +++ b/src/core/events.cpp @@ -1414,3 +1414,47 @@ Event::Type CopyBufferToImageEvent::type() const { return Event::CopyBufferToImage; } + +/* + * Barrier + */ + +BarrierEvent::BarrierEvent(CommandQueue *parent, cl_int *errcode_ret) +: Event(parent, Queued, 0, 0, errcode_ret) +{} + +Event::Type BarrierEvent::type() const +{ + return Event::Barrier; +} + +/* + * WaitForEvents + */ + +WaitForEventsEvent::WaitForEventsEvent(CommandQueue *parent, + cl_uint num_events_in_wait_list, + const Event **event_wait_list, + cl_int *errcode_ret) +: Event(parent, Queued, num_events_in_wait_list, event_wait_list, errcode_ret) +{} + +Event::Type WaitForEventsEvent::type() const +{ + return Event::WaitForEvents; +} + +/* + * Marker + */ +MarkerEvent::MarkerEvent(CommandQueue *parent, + cl_uint num_events_in_wait_list, + const Event **event_wait_list, + cl_int *errcode_ret) +: WaitForEventsEvent(parent, num_events_in_wait_list, event_wait_list, errcode_ret) +{} + +Event::Type MarkerEvent::type() const +{ + return Event::Marker; +} diff --git a/src/core/events.h b/src/core/events.h index 75b2833..1f4bc4a 100644 --- a/src/core/events.h +++ b/src/core/events.h @@ -498,6 +498,37 @@ class UserEvent : public Event std::vector p_dependent_queues; }; +class BarrierEvent : public Event +{ + public: + BarrierEvent(CommandQueue *parent, + cl_int *errcode_ret); + + Type type() const; +}; + +class WaitForEventsEvent : public Event +{ + public: + WaitForEventsEvent(CommandQueue *parent, + cl_uint num_events_in_wait_list, + const Event **event_wait_list, + cl_int *errcode_ret); + + virtual Type type() const; +}; + +class MarkerEvent : public WaitForEventsEvent +{ + public: + MarkerEvent(CommandQueue *parent, + cl_uint num_events_in_wait_list, + const Event **event_wait_list, + cl_int *errcode_ret); + + Type type() const; +}; + } #endif -- cgit v1.2.3