Path: blob/21.2-virgl/src/gallium/frontends/clover/core/event.hpp
4572 views
//1// Copyright 2012 Francisco Jerez2//3// Permission is hereby granted, free of charge, to any person obtaining a4// copy of this software and associated documentation files (the "Software"),5// to deal in the Software without restriction, including without limitation6// the rights to use, copy, modify, merge, publish, distribute, sublicense,7// and/or sell copies of the Software, and to permit persons to whom the8// Software is furnished to do so, subject to the following conditions:9//10// The above copyright notice and this permission notice shall be included in11// all copies or substantial portions of the Software.12//13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR17// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19// OTHER DEALINGS IN THE SOFTWARE.20//2122#ifndef CLOVER_CORE_EVENT_HPP23#define CLOVER_CORE_EVENT_HPP2425#include <condition_variable>26#include <functional>2728#include "core/object.hpp"29#include "core/queue.hpp"30#include "core/timestamp.hpp"31#include "util/lazy.hpp"3233namespace clover {34///35/// Class that represents a task that might be executed36/// asynchronously at some point in the future.37///38/// An event consists of a list of dependencies, a boolean39/// signalled() flag, and an associated task. An event is40/// considered signalled as soon as all its dependencies (if any)41/// are signalled as well, and the trigger() method is called; at42/// that point the associated task will be started through the43/// specified \a action_ok. If the abort() method is called44/// instead, the specified \a action_fail is executed and the45/// associated task will never be started. Dependent events will46/// be aborted recursively.47///48/// The execution status of the associated task can be queried49/// using the status() method, and it can be waited for completion50/// using the wait() method.51///52class event : public ref_counter, public _cl_event {53public:54typedef std::function<void (event &)> action;5556event(clover::context &ctx, const ref_vector<event> &deps,57action action_ok, action action_fail);58virtual ~event();5960event(const event &ev) = delete;61event &62operator=(const event &ev) = delete;6364void trigger();65void abort(cl_int status);66bool signalled() const;6768virtual cl_int status() const;69virtual command_queue *queue() const = 0;70virtual cl_command_type command() const = 0;71void wait_signalled() const;72virtual void wait() const;7374virtual struct pipe_fence_handle *fence() const {75return NULL;76}7778const intrusive_ref<clover::context> context;7980protected:81void chain(event &ev);8283mutable std::vector<intrusive_ref<event>> deps;8485private:86std::vector<intrusive_ref<event>> trigger_self();87std::vector<intrusive_ref<event>> abort_self(cl_int status);88unsigned wait_count() const;8990unsigned _wait_count;91cl_int _status;92action action_ok;93action action_fail;94std::vector<intrusive_ref<event>> _chain;95mutable std::condition_variable cv;96mutable std::mutex mutex;97};9899///100/// Class that represents a task executed by a command queue.101///102/// Similar to a normal clover::event. In addition it's associated103/// with a given command queue \a q and a given OpenCL \a command.104/// hard_event instances created for the same queue are implicitly105/// ordered with respect to each other, and they are implicitly106/// triggered on construction.107///108/// A hard_event is considered complete when the associated109/// hardware task finishes execution.110///111class hard_event : public event {112public:113hard_event(command_queue &q, cl_command_type command,114const ref_vector<event> &deps,115action action = [](event &){});116~hard_event();117118virtual cl_int status() const;119virtual command_queue *queue() const;120virtual cl_command_type command() const;121virtual void wait() const;122123const lazy<cl_ulong> &time_queued() const;124const lazy<cl_ulong> &time_submit() const;125const lazy<cl_ulong> &time_start() const;126const lazy<cl_ulong> &time_end() const;127128friend class command_queue;129130virtual struct pipe_fence_handle *fence() const {131return _fence;132}133134private:135virtual void fence(pipe_fence_handle *fence);136action profile(command_queue &q, const action &action) const;137138const intrusive_ref<command_queue> _queue;139cl_command_type _command;140pipe_fence_handle *_fence;141lazy<cl_ulong> _time_queued, _time_submit, _time_start, _time_end;142};143144///145/// Class that represents a software event.146///147/// A soft_event is not associated with any specific hardware task148/// or command queue. It's considered complete as soon as all its149/// dependencies finish execution.150///151class soft_event : public event {152public:153soft_event(clover::context &ctx, const ref_vector<event> &deps,154bool trigger, action action = [](event &){});155156virtual cl_int status() const;157virtual command_queue *queue() const;158virtual cl_command_type command() const;159virtual void wait() const;160};161}162163#endif164165166