event.cpp revision c6db1b3396384186aab5b685fe1fd540e17b3a62
1// 2// Copyright 2012 Francisco Jerez 3// 4// Permission is hereby granted, free of charge, to any person obtaining a 5// copy of this software and associated documentation files (the "Software"), 6// to deal in the Software without restriction, including without limitation 7// the rights to use, copy, modify, merge, publish, distribute, sublicense, 8// and/or sell copies of the Software, and to permit persons to whom the 9// Software is furnished to do so, subject to the following conditions: 10// 11// The above copyright notice and this permission notice shall be included in 12// all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20// SOFTWARE. 21// 22 23#include "core/event.hpp" 24#include "pipe/p_screen.h" 25 26using namespace clover; 27 28_cl_event::_cl_event(clover::context &ctx, 29 std::vector<clover::event *> deps, 30 action action_ok, action action_fail) : 31 ctx(ctx), __status(0), wait_count(1), 32 action_ok(action_ok), action_fail(action_fail) { 33 for (auto ev : deps) 34 ev->chain(this); 35} 36 37_cl_event::~_cl_event() { 38} 39 40void 41_cl_event::trigger() { 42 if (!--wait_count) { 43 action_ok(*this); 44 45 while (!__chain.empty()) { 46 __chain.back()->trigger(); 47 __chain.pop_back(); 48 } 49 } 50} 51 52void 53_cl_event::abort(cl_int status) { 54 __status = status; 55 action_fail(*this); 56 57 while (!__chain.empty()) { 58 __chain.back()->abort(status); 59 __chain.pop_back(); 60 } 61} 62 63bool 64_cl_event::signalled() const { 65 return !wait_count; 66} 67 68void 69_cl_event::chain(clover::event *ev) { 70 if (wait_count) { 71 ev->wait_count++; 72 __chain.push_back(ev); 73 ev->deps.push_back(this); 74 } 75} 76 77hard_event::hard_event(clover::command_queue &q, cl_command_type command, 78 std::vector<clover::event *> deps, action action) : 79 _cl_event(q.ctx, deps, action, [](event &ev){}), 80 __queue(q), __command(command), __fence(NULL) { 81 q.sequence(this); 82 trigger(); 83} 84 85hard_event::~hard_event() { 86 pipe_screen *screen = queue()->dev.pipe; 87 screen->fence_reference(screen, &__fence, NULL); 88} 89 90cl_int 91hard_event::status() const { 92 pipe_screen *screen = queue()->dev.pipe; 93 94 if (__status < 0) 95 return __status; 96 97 else if (!__fence) 98 return CL_QUEUED; 99 100 else if (!screen->fence_signalled(screen, __fence)) 101 return CL_SUBMITTED; 102 103 else 104 return CL_COMPLETE; 105} 106 107cl_command_queue 108hard_event::queue() const { 109 return &__queue; 110} 111 112cl_command_type 113hard_event::command() const { 114 return __command; 115} 116 117void 118hard_event::wait() const { 119 pipe_screen *screen = queue()->dev.pipe; 120 121 if (status() == CL_QUEUED) 122 queue()->flush(); 123 124 if (!__fence || 125 !screen->fence_finish(screen, __fence, PIPE_TIMEOUT_INFINITE)) 126 throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); 127} 128 129void 130hard_event::fence(pipe_fence_handle *fence) { 131 pipe_screen *screen = queue()->dev.pipe; 132 screen->fence_reference(screen, &__fence, fence); 133} 134 135soft_event::soft_event(clover::context &ctx, 136 std::vector<clover::event *> deps, 137 bool __trigger, action action) : 138 _cl_event(ctx, deps, action, action) { 139 if (__trigger) 140 trigger(); 141} 142 143cl_int 144soft_event::status() const { 145 if (__status < 0) 146 return __status; 147 148 else if (!signalled() || 149 any_of([](const ref_ptr<event> &ev) { 150 return ev->status() != CL_COMPLETE; 151 }, deps.begin(), deps.end())) 152 return CL_SUBMITTED; 153 154 else 155 return CL_COMPLETE; 156} 157 158cl_command_queue 159soft_event::queue() const { 160 return NULL; 161} 162 163cl_command_type 164soft_event::command() const { 165 return CL_COMMAND_USER; 166} 167 168void 169soft_event::wait() const { 170 for (auto ev : deps) 171 ev->wait(); 172 173 if (status() != CL_COMPLETE) 174 throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); 175} 176