Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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. #ifndef __CORE_EVENT_HPP__
  24. #define __CORE_EVENT_HPP__
  25.  
  26. #include <functional>
  27.  
  28. #include "core/base.hpp"
  29. #include "core/queue.hpp"
  30.  
  31. namespace clover {
  32.    typedef struct _cl_event event;
  33. }
  34.  
  35. ///
  36. /// Class that represents a task that might be executed asynchronously
  37. /// at some point in the future.
  38. ///
  39. /// An event consists of a list of dependencies, a boolean signalled()
  40. /// flag, and an associated task.  An event is considered signalled as
  41. /// soon as all its dependencies (if any) are signalled as well, and
  42. /// the trigger() method is called; at that point the associated task
  43. /// will be started through the specified \a action_ok.  If the
  44. /// abort() method is called instead, the specified \a action_fail is
  45. /// executed and the associated task will never be started.  Dependent
  46. /// events will be aborted recursively.
  47. ///
  48. /// The execution status of the associated task can be queried using
  49. /// the status() method, and it can be waited for completion using the
  50. /// wait() method.
  51. ///
  52. struct _cl_event : public clover::ref_counter {
  53. public:
  54.    typedef std::function<void (clover::event &)> action;
  55.  
  56.    _cl_event(clover::context &ctx, std::vector<clover::event *> deps,
  57.              action action_ok, action action_fail);
  58.    virtual ~_cl_event();
  59.  
  60.    void trigger();
  61.    void abort(cl_int status);
  62.    bool signalled() const;
  63.  
  64.    virtual cl_int status() const = 0;
  65.    virtual cl_command_queue queue() const = 0;
  66.    virtual cl_command_type command() const = 0;
  67.    virtual void wait() const = 0;
  68.  
  69.    clover::context &ctx;
  70.  
  71. protected:
  72.    void chain(clover::event *ev);
  73.  
  74.    cl_int __status;
  75.    std::vector<clover::ref_ptr<clover::event>> deps;
  76.  
  77. private:
  78.    unsigned wait_count;
  79.    action action_ok;
  80.    action action_fail;
  81.    std::vector<clover::ref_ptr<clover::event>> __chain;
  82. };
  83.  
  84. namespace clover {
  85.    ///
  86.    /// Class that represents a task executed by a command queue.
  87.    ///
  88.    /// Similar to a normal clover::event.  In addition it's associated
  89.    /// with a given command queue \a q and a given OpenCL \a command.
  90.    /// hard_event instances created for the same queue are implicitly
  91.    /// ordered with respect to each other, and they are implicitly
  92.    /// triggered on construction.
  93.    ///
  94.    /// A hard_event is considered complete when the associated
  95.    /// hardware task finishes execution.
  96.    ///
  97.    class hard_event : public event {
  98.    public:
  99.       hard_event(clover::command_queue &q, cl_command_type command,
  100.                  std::vector<clover::event *> deps,
  101.                  action action = [](event &){});
  102.       ~hard_event();
  103.  
  104.       virtual cl_int status() const;
  105.       virtual cl_command_queue queue() const;
  106.       virtual cl_command_type command() const;
  107.       virtual void wait() const;
  108.  
  109.       friend class ::_cl_command_queue;
  110.  
  111.    private:
  112.       virtual void fence(pipe_fence_handle *fence);
  113.  
  114.       clover::command_queue &__queue;
  115.       cl_command_type __command;
  116.       pipe_fence_handle *__fence;
  117.    };
  118.  
  119.    ///
  120.    /// Class that represents a software event.
  121.    ///
  122.    /// A soft_event is not associated with any specific hardware task
  123.    /// or command queue.  It's considered complete as soon as all its
  124.    /// dependencies finish execution.
  125.    ///
  126.    class soft_event : public event {
  127.    public:
  128.       soft_event(clover::context &ctx, std::vector<clover::event *> deps,
  129.                  bool trigger, action action = [](event &){});
  130.  
  131.       virtual cl_int status() const;
  132.       virtual cl_command_queue queue() const;
  133.       virtual cl_command_type command() const;
  134.       virtual void wait() const;
  135.    };
  136. }
  137.  
  138. #endif
  139.