"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/state_trackers/clover/api/event.cpp" (16 Sep 2020, 7998 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "event.cpp" see the Fossies "Dox" file reference documentation.

    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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
   18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   20 // OTHER DEALINGS IN THE SOFTWARE.
   21 //
   22 
   23 #include "api/util.hpp"
   24 #include "core/event.hpp"
   25 
   26 using namespace clover;
   27 
   28 CLOVER_API cl_event
   29 clCreateUserEvent(cl_context d_ctx, cl_int *r_errcode) try {
   30    auto &ctx = obj(d_ctx);
   31 
   32    ret_error(r_errcode, CL_SUCCESS);
   33    return desc(new soft_event(ctx, {}, false));
   34 
   35 } catch (error &e) {
   36    ret_error(r_errcode, e);
   37    return NULL;
   38 }
   39 
   40 CLOVER_API cl_int
   41 clSetUserEventStatus(cl_event d_ev, cl_int status) try {
   42    auto &sev = obj<soft_event>(d_ev);
   43 
   44    if (status > 0)
   45       return CL_INVALID_VALUE;
   46 
   47    if (sev.status() <= 0)
   48       return CL_INVALID_OPERATION;
   49 
   50    if (status)
   51       sev.abort(status);
   52    else
   53       sev.trigger();
   54 
   55    return CL_SUCCESS;
   56 
   57 } catch (error &e) {
   58    return e.get();
   59 }
   60 
   61 CLOVER_API cl_int
   62 clWaitForEvents(cl_uint num_evs, const cl_event *d_evs) try {
   63    auto evs = objs(d_evs, num_evs);
   64 
   65    for (auto &ev : evs) {
   66       if (ev.context() != evs.front().context())
   67          throw error(CL_INVALID_CONTEXT);
   68 
   69       if (ev.status() < 0)
   70          throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
   71    }
   72 
   73    // Create a temporary soft event that depends on all the events in
   74    // the wait list
   75    auto sev = create<soft_event>(evs.front().context(), evs, true);
   76 
   77    // ...and wait on it.
   78    sev().wait();
   79 
   80    return CL_SUCCESS;
   81 
   82 } catch (error &e) {
   83    return e.get();
   84 }
   85 
   86 CLOVER_API cl_int
   87 clGetEventInfo(cl_event d_ev, cl_event_info param,
   88                size_t size, void *r_buf, size_t *r_size) try {
   89    property_buffer buf { r_buf, size, r_size };
   90    auto &ev = obj(d_ev);
   91 
   92    switch (param) {
   93    case CL_EVENT_COMMAND_QUEUE:
   94       buf.as_scalar<cl_command_queue>() = desc(ev.queue());
   95       break;
   96 
   97    case CL_EVENT_CONTEXT:
   98       buf.as_scalar<cl_context>() = desc(ev.context());
   99       break;
  100 
  101    case CL_EVENT_COMMAND_TYPE:
  102       buf.as_scalar<cl_command_type>() = ev.command();
  103       break;
  104 
  105    case CL_EVENT_COMMAND_EXECUTION_STATUS:
  106       buf.as_scalar<cl_int>() = ev.status();
  107       break;
  108 
  109    case CL_EVENT_REFERENCE_COUNT:
  110       buf.as_scalar<cl_uint>() = ev.ref_count();
  111       break;
  112 
  113    default:
  114       throw error(CL_INVALID_VALUE);
  115    }
  116 
  117    return CL_SUCCESS;
  118 
  119 } catch (error &e) {
  120    return e.get();
  121 }
  122 
  123 CLOVER_API cl_int
  124 clSetEventCallback(cl_event d_ev, cl_int type,
  125                    void (CL_CALLBACK *pfn_notify)(cl_event, cl_int, void *),
  126                    void *user_data) try {
  127    auto &ev = obj(d_ev);
  128 
  129    if (!pfn_notify ||
  130        (type != CL_COMPLETE && type != CL_SUBMITTED && type != CL_RUNNING))
  131       throw error(CL_INVALID_VALUE);
  132 
  133    // Create a temporary soft event that depends on ev, with
  134    // pfn_notify as completion action.
  135    create<soft_event>(ev.context(), ref_vector<event> { ev }, true,
  136                       [=, &ev](event &) {
  137                          ev.wait();
  138                          pfn_notify(desc(ev), ev.status(), user_data);
  139                       });
  140 
  141    return CL_SUCCESS;
  142 
  143 } catch (error &e) {
  144    return e.get();
  145 }
  146 
  147 CLOVER_API cl_int
  148 clRetainEvent(cl_event d_ev) try {
  149    obj(d_ev).retain();
  150    return CL_SUCCESS;
  151 
  152 } catch (error &e) {
  153    return e.get();
  154 }
  155 
  156 CLOVER_API cl_int
  157 clReleaseEvent(cl_event d_ev) try {
  158    if (obj(d_ev).release())
  159       delete pobj(d_ev);
  160 
  161    return CL_SUCCESS;
  162 
  163 } catch (error &e) {
  164    return e.get();
  165 }
  166 
  167 CLOVER_API cl_int
  168 clEnqueueMarker(cl_command_queue d_q, cl_event *rd_ev) try {
  169    auto &q = obj(d_q);
  170 
  171    if (!rd_ev)
  172       throw error(CL_INVALID_VALUE);
  173 
  174    *rd_ev = desc(new hard_event(q, CL_COMMAND_MARKER, {}));
  175 
  176    return CL_SUCCESS;
  177 
  178 } catch (error &e) {
  179    return e.get();
  180 }
  181 
  182 CLOVER_API cl_int
  183 clEnqueueMarkerWithWaitList(cl_command_queue d_q, cl_uint num_deps,
  184                             const cl_event *d_deps, cl_event *rd_ev) try {
  185    auto &q = obj(d_q);
  186    auto deps = objs<wait_list_tag>(d_deps, num_deps);
  187 
  188    for (auto &ev : deps) {
  189       if (ev.context() != q.context())
  190          throw error(CL_INVALID_CONTEXT);
  191    }
  192 
  193    // Create a hard event that depends on the events in the wait list:
  194    // previous commands in the same queue are implicitly serialized
  195    // with respect to it -- hard events always are.
  196    auto hev = create<hard_event>(q, CL_COMMAND_MARKER, deps);
  197 
  198    ret_object(rd_ev, hev);
  199    return CL_SUCCESS;
  200 
  201 } catch (error &e) {
  202    return e.get();
  203 }
  204 
  205 CLOVER_API cl_int
  206 clEnqueueBarrier(cl_command_queue d_q) try {
  207    obj(d_q);
  208 
  209    // No need to do anything, q preserves data ordering strictly.
  210 
  211    return CL_SUCCESS;
  212 
  213 } catch (error &e) {
  214    return e.get();
  215 }
  216 
  217 CLOVER_API cl_int
  218 clEnqueueBarrierWithWaitList(cl_command_queue d_q, cl_uint num_deps,
  219                              const cl_event *d_deps, cl_event *rd_ev) try {
  220    auto &q = obj(d_q);
  221    auto deps = objs<wait_list_tag>(d_deps, num_deps);
  222 
  223    for (auto &ev : deps) {
  224       if (ev.context() != q.context())
  225          throw error(CL_INVALID_CONTEXT);
  226    }
  227 
  228    // Create a hard event that depends on the events in the wait list:
  229    // subsequent commands in the same queue will be implicitly
  230    // serialized with respect to it -- hard events always are.
  231    auto hev = create<hard_event>(q, CL_COMMAND_BARRIER, deps);
  232 
  233    ret_object(rd_ev, hev);
  234    return CL_SUCCESS;
  235 
  236 } catch (error &e) {
  237    return e.get();
  238 }
  239 
  240 CLOVER_API cl_int
  241 clEnqueueWaitForEvents(cl_command_queue d_q, cl_uint num_evs,
  242                        const cl_event *d_evs) try {
  243    // The wait list is mandatory for clEnqueueWaitForEvents().
  244    objs(d_evs, num_evs);
  245 
  246    return clEnqueueBarrierWithWaitList(d_q, num_evs, d_evs, NULL);
  247 
  248 } catch (error &e) {
  249    return e.get();
  250 }
  251 
  252 CLOVER_API cl_int
  253 clGetEventProfilingInfo(cl_event d_ev, cl_profiling_info param,
  254                         size_t size, void *r_buf, size_t *r_size) try {
  255    property_buffer buf { r_buf, size, r_size };
  256    hard_event &hev = dynamic_cast<hard_event &>(obj(d_ev));
  257 
  258    if (hev.status() != CL_COMPLETE)
  259       throw error(CL_PROFILING_INFO_NOT_AVAILABLE);
  260 
  261    switch (param) {
  262    case CL_PROFILING_COMMAND_QUEUED:
  263       buf.as_scalar<cl_ulong>() = hev.time_queued();
  264       break;
  265 
  266    case CL_PROFILING_COMMAND_SUBMIT:
  267       buf.as_scalar<cl_ulong>() = hev.time_submit();
  268       break;
  269 
  270    case CL_PROFILING_COMMAND_START:
  271       buf.as_scalar<cl_ulong>() = hev.time_start();
  272       break;
  273 
  274    case CL_PROFILING_COMMAND_END:
  275       buf.as_scalar<cl_ulong>() = hev.time_end();
  276       break;
  277 
  278    default:
  279       throw error(CL_INVALID_VALUE);
  280    }
  281 
  282    return CL_SUCCESS;
  283 
  284 } catch (std::bad_cast &e) {
  285    return CL_PROFILING_INFO_NOT_AVAILABLE;
  286 
  287 } catch (lazy<cl_ulong>::undefined_error &e) {
  288    return CL_PROFILING_INFO_NOT_AVAILABLE;
  289 
  290 } catch (error &e) {
  291    return e.get();
  292 }
  293 
  294 CLOVER_API cl_int
  295 clFinish(cl_command_queue d_q) try {
  296    auto &q = obj(d_q);
  297 
  298    // Create a temporary hard event -- it implicitly depends on all
  299    // the previously queued hard events.
  300    auto hev = create<hard_event>(q, 0, ref_vector<event> {});
  301 
  302    // And wait on it.
  303    hev().wait();
  304 
  305    return CL_SUCCESS;
  306 
  307 } catch (error &e) {
  308    return e.get();
  309 }