Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/ptl/include/PTL/Task.hh

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/ptl/include/PTL/Task.hh (Version 11.3.0) and /externals/ptl/include/PTL/Task.hh (Version 10.7.p4)


  1 //                                                  1 //
  2 // MIT License                                      2 // MIT License
  3 // Copyright (c) 2020 Jonathan R. Madsen            3 // Copyright (c) 2020 Jonathan R. Madsen
  4 // Permission is hereby granted, free of charg      4 // Permission is hereby granted, free of charge, to any person obtaining a copy
  5 // of this software and associated documentati      5 // of this software and associated documentation files (the "Software"), to deal
  6 // in the Software without restriction, includ      6 // in the Software without restriction, including without limitation the rights
  7 // to use, copy, modify, merge, publish, distr      7 // to use, copy, modify, merge, publish, distribute, sublicense, and
  8 // copies of the Software, and to permit perso      8 // copies of the Software, and to permit persons to whom the Software is
  9 // furnished to do so, subject to the followin      9 // furnished to do so, subject to the following conditions:
 10 // The above copyright notice and this permiss     10 // The above copyright notice and this permission notice shall be included in
 11 // all copies or substantial portions of the S     11 // all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
 12 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPR     12 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 13 // LIMITED TO THE WARRANTIES OF MERCHANTABILIT     13 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SH     14 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR     15 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARIS     16 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 17 // WITH THE SOFTWARE OR THE USE OR OTHER DEALI     17 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 18 //                                                 18 //
 19 //                                                 19 //
 20 // -------------------------------------------     20 // ---------------------------------------------------------------
 21 // Tasking class header file                       21 // Tasking class header file
 22 //                                                 22 //
 23 // Class Description:                              23 // Class Description:
 24 //                                                 24 //
 25 // This file defines the task types for TaskMa     25 // This file defines the task types for TaskManager and ThreadPool
 26 //                                                 26 //
 27 // -------------------------------------------     27 // ---------------------------------------------------------------
 28 // Author: Jonathan Madsen (Feb 13th 2018)         28 // Author: Jonathan Madsen (Feb 13th 2018)
 29 // -------------------------------------------     29 // ---------------------------------------------------------------
 30                                                    30 
 31 #pragma once                                       31 #pragma once
 32                                                    32 
 33 #include "PTL/VTask.hh"                        <<  33 #include "Globals.hh"
 34 #include "PTL/detail/CxxBackports.hh"          <<  34 #include "TaskAllocator.hh"
                                                   >>  35 #include "VTask.hh"
 35                                                    36 
 36 #include <cstdint>                                 37 #include <cstdint>
 37 #include <future>                              <<  38 #include <functional>
 38 #include <tuple>                               <<  39 #include <stdexcept>
 39 #include <utility>                             << 
 40                                                    40 
 41 namespace PTL                                      41 namespace PTL
 42 {                                                  42 {
 43 //============================================ <<  43 class VTaskGroup;
 44                                                <<  44 class ThreadPool;
 45 /// \brief The task class is supplied to threa << 
 46 template <typename RetT>                       << 
 47 class TaskFuture : public VTask                << 
 48 {                                              << 
 49 public:                                        << 
 50     using promise_type = std::promise<RetT>;   << 
 51     using future_type  = std::future<RetT>;    << 
 52     using result_type  = RetT;                 << 
 53                                                << 
 54 public:                                        << 
 55     // pass a free function pointer            << 
 56     template <typename... Args>                << 
 57     TaskFuture(Args&&... args)                 << 
 58     : VTask{ std::forward<Args>(args)... }     << 
 59     {}                                         << 
 60                                                << 
 61     ~TaskFuture() override = default;          << 
 62                                                << 
 63     TaskFuture(const TaskFuture&) = delete;    << 
 64     TaskFuture& operator=(const TaskFuture&) = << 
 65                                                << 
 66     TaskFuture(TaskFuture&&) noexcept = defaul << 
 67     TaskFuture& operator=(TaskFuture&&) noexce << 
 68                                                << 
 69 public:                                        << 
 70     // execution operator                      << 
 71     virtual future_type get_future() = 0;      << 
 72     virtual void        wait()       = 0;      << 
 73     virtual RetT        get()        = 0;      << 
 74 };                                             << 
 75                                                    45 
 76 //============================================     46 //======================================================================================//
 77                                                    47 
 78 /// \brief The task class is supplied to threa     48 /// \brief The task class is supplied to thread_pool.
 79 template <typename RetT, typename... Args>         49 template <typename RetT, typename... Args>
 80 class PackagedTask : public TaskFuture<RetT>   <<  50 class PackagedTask : public VTask
 81 {                                                  51 {
 82 public:                                            52 public:
 83     using this_type          = PackagedTask<Re <<  53     typedef PackagedTask<RetT, Args...>       this_type;
 84     using promise_type       = std::promise<Re <<  54     typedef std::promise<RetT>                promise_type;
 85     using future_type        = std::future<Ret <<  55     typedef std::future<RetT>                 future_type;
 86     using packaged_task_type = std::packaged_t <<  56     typedef std::packaged_task<RetT(Args...)> packaged_task_type;
 87     using result_type        = RetT;           <<  57     typedef RetT                              result_type;
 88     using tuple_type         = std::tuple<Args <<  58     typedef std::tuple<Args...>               tuple_type;
 89                                                    59 
 90 public:                                            60 public:
 91     // pass a free function pointer                61     // pass a free function pointer
 92     template <typename FuncT>                      62     template <typename FuncT>
 93     PackagedTask(FuncT func, Args... args)     <<  63     PackagedTask(FuncT&& func, Args... args)
 94     : TaskFuture<RetT>{ true, 0 }              <<  64     : VTask()
 95     , m_ptask{ std::move(func) }               <<  65     , m_ptask(std::forward<FuncT>(func))
 96     , m_args{ args... }                        <<  66     , m_args(args...)
 97     {}                                             67     {}
 98                                                    68 
 99     template <typename FuncT>                      69     template <typename FuncT>
100     PackagedTask(bool _is_native, intmax_t _de <<  70     PackagedTask(VTaskGroup* tg, FuncT&& func, Args... args)
101     : TaskFuture<RetT>{ _is_native, _depth }   <<  71     : VTask(tg)
102     , m_ptask{ std::move(func) }               <<  72     , m_ptask(std::forward<FuncT>(func))
103     , m_args{ args... }                        <<  73     , m_args(args...)
104     {}                                             74     {}
105                                                    75 
106     ~PackagedTask() override = default;        <<  76     template <typename FuncT>
107                                                <<  77     PackagedTask(ThreadPool* _pool, FuncT&& func, Args... args)
108     PackagedTask(const PackagedTask&) = delete <<  78     : VTask(_pool)
109     PackagedTask& operator=(const PackagedTask <<  79     , m_ptask(std::forward<FuncT>(func))
                                                   >>  80     , m_args(args...)
                                                   >>  81     {}
110                                                    82 
111     PackagedTask(PackagedTask&&) noexcept = de <<  83     virtual ~PackagedTask() {}
112     PackagedTask& operator=(PackagedTask&&) no << 
113                                                    84 
114 public:                                            85 public:
115     // execution operator                          86     // execution operator
116     void        operator()() final { PTL::appl <<  87     virtual void operator()() override
117     future_type get_future() final { return m_ <<  88     {
118     void        wait() final { return m_ptask. <<  89         mpl::apply(std::move(m_ptask), std::move(m_args));
119     RetT        get() final { return m_ptask.g <<  90     }
                                                   >>  91     future_type  get_future() { return m_ptask.get_future(); }
                                                   >>  92     virtual bool is_native_task() const override { return true; }
120                                                    93 
121 private:                                           94 private:
122     packaged_task_type m_ptask;                    95     packaged_task_type m_ptask;
123     tuple_type         m_args;                     96     tuple_type         m_args;
124 };                                                 97 };
125                                                    98 
126 //============================================     99 //======================================================================================//
127                                                   100 
128 /// \brief The task class is supplied to threa    101 /// \brief The task class is supplied to thread_pool.
129 template <typename RetT, typename... Args>        102 template <typename RetT, typename... Args>
130 class Task : public TaskFuture<RetT>           << 103 class Task : public VTask
131 {                                                 104 {
132 public:                                           105 public:
133     using this_type          = Task<RetT, Args << 106     typedef Task<RetT, Args...>               this_type;
134     using promise_type       = std::promise<Re << 107     typedef std::promise<RetT>                promise_type;
135     using future_type        = std::future<Ret << 108     typedef std::future<RetT>                 future_type;
136     using packaged_task_type = std::packaged_t << 109     typedef std::packaged_task<RetT(Args...)> packaged_task_type;
137     using result_type        = RetT;           << 110     typedef RetT                              result_type;
138     using tuple_type         = std::tuple<Args << 111     typedef std::tuple<Args...>               tuple_type;
139                                                   112 
140 public:                                           113 public:
141     template <typename FuncT>                     114     template <typename FuncT>
142     Task(FuncT func, Args... args)             << 115     Task(FuncT&& func, Args... args)
143     : TaskFuture<RetT>{}                       << 116     : VTask()
144     , m_ptask{ std::move(func) }               << 117     , m_ptask(std::forward<FuncT>(func))
145     , m_args{ args... }                        << 118     , m_args(args...)
146     {}                                            119     {}
147                                                   120 
148     template <typename FuncT>                     121     template <typename FuncT>
149     Task(bool _is_native, intmax_t _depth, Fun << 122     Task(VTaskGroup* tg, FuncT&& func, Args... args)
150     : TaskFuture<RetT>{ _is_native, _depth }   << 123     : VTask(tg)
151     , m_ptask{ std::move(func) }               << 124     , m_ptask(std::forward<FuncT>(func))
152     , m_args{ args... }                        << 125     , m_args(args...)
153     {}                                            126     {}
154                                                   127 
155     ~Task() override = default;                << 128     template <typename FuncT>
156                                                << 129     Task(ThreadPool* tp, FuncT&& func, Args... args)
157     Task(const Task&) = delete;                << 130     : VTask(tp)
158     Task& operator=(const Task&) = delete;     << 131     , m_ptask(std::forward<FuncT>(func))
                                                   >> 132     , m_args(args...)
                                                   >> 133     {}
159                                                   134 
160     Task(Task&&) noexcept = default;           << 135     virtual ~Task() {}
161     Task& operator=(Task&&) noexcept = default << 
162                                                   136 
163 public:                                           137 public:
164     // execution operator                         138     // execution operator
165     void operator()() final                    << 139     virtual void operator()() final
166     {                                             140     {
167         if(m_ptask.valid())                    << 141         mpl::apply(std::move(m_ptask), std::move(m_args));
168             PTL::apply(std::move(m_ptask), std << 142         // decrements the task-group counter on active tasks
                                                   >> 143         // when the counter is < 2, if the thread owning the task group is
                                                   >> 144         // sleeping at the TaskGroup::wait(), it signals the thread to wake
                                                   >> 145         // up and check if all tasks are finished, proceeding if this
                                                   >> 146         // check returns as true
                                                   >> 147         this_type::operator--();
169     }                                             148     }
170     future_type get_future() final { return m_ << 149 
171     void        wait() final { return m_ptask. << 150     virtual bool is_native_task() const override { return true; }
172     RetT        get() final { return m_ptask.g << 151     future_type  get_future() { return m_ptask.get_future(); }
173                                                   152 
174 private:                                          153 private:
175     packaged_task_type m_ptask{};              << 154     packaged_task_type m_ptask;
176     tuple_type         m_args{};               << 155     tuple_type         m_args;
177 };                                                156 };
178                                                   157 
179 //============================================    158 //======================================================================================//
180                                                   159 
181 /// \brief The task class is supplied to threa    160 /// \brief The task class is supplied to thread_pool.
182 template <typename RetT>                          161 template <typename RetT>
183 class Task<RetT, void> : public TaskFuture<Ret << 162 class Task<RetT, void> : public VTask
184 {                                                 163 {
185 public:                                           164 public:
186     using this_type          = Task<RetT>;     << 165     typedef Task<RetT>                 this_type;
187     using promise_type       = std::promise<Re << 166     typedef std::promise<RetT>         promise_type;
188     using future_type        = std::future<Ret << 167     typedef std::future<RetT>          future_type;
189     using packaged_task_type = std::packaged_t << 168     typedef std::packaged_task<RetT()> packaged_task_type;
190     using result_type        = RetT;           << 169     typedef RetT                       result_type;
191                                                   170 
192 public:                                           171 public:
193     template <typename FuncT>                     172     template <typename FuncT>
194     Task(FuncT func)                           << 173     Task(FuncT&& func)
195     : TaskFuture<RetT>()                       << 174     : VTask()
196     , m_ptask{ std::move(func) }               << 175     , m_ptask(std::forward<FuncT>(func))
197     {}                                            176     {}
198                                                   177 
199     template <typename FuncT>                     178     template <typename FuncT>
200     Task(bool _is_native, intmax_t _depth, Fun << 179     Task(VTaskGroup* tg, FuncT&& func)
201     : TaskFuture<RetT>{ _is_native, _depth }   << 180     : VTask(tg)
202     , m_ptask{ std::move(func) }               << 181     , m_ptask(std::forward<FuncT>(func))
203     {}                                            182     {}
204                                                   183 
205     virtual ~Task() = default;                 << 184     template <typename FuncT>
206                                                << 185     Task(ThreadPool* tp, FuncT&& func)
207     Task(const Task&) = delete;                << 186     : VTask(tp)
208     Task& operator=(const Task&) = delete;     << 187     , m_ptask(std::forward<FuncT>(func))
                                                   >> 188     {}
209                                                   189 
210     Task(Task&&) noexcept = default;           << 190     virtual ~Task() {}
211     Task& operator=(Task&&) noexcept = default << 
212                                                   191 
213 public:                                           192 public:
214     // execution operator                         193     // execution operator
215     virtual void        operator()() final { m << 194     virtual void operator()() final
216     virtual future_type get_future() final { r << 195     {
217     virtual void        wait() final { return  << 196         m_ptask();
218     virtual RetT        get() final { return m << 197         // decrements the task-group counter on active tasks
                                                   >> 198         // when the counter is < 2, if the thread owning the task group is
                                                   >> 199         // sleeping at the TaskGroup::wait(), it signals the thread to wake
                                                   >> 200         // up and check if all tasks are finished, proceeding if this
                                                   >> 201         // check returns as true
                                                   >> 202         this_type::operator--();
                                                   >> 203     }
                                                   >> 204 
                                                   >> 205     virtual bool is_native_task() const override { return true; }
                                                   >> 206     future_type  get_future() { return m_ptask.get_future(); }
219                                                   207 
220 private:                                          208 private:
221     packaged_task_type m_ptask{};              << 209     packaged_task_type m_ptask;
222 };                                                210 };
223                                                   211 
224 //============================================    212 //======================================================================================//
225                                                   213 
226 /// \brief The task class is supplied to threa    214 /// \brief The task class is supplied to thread_pool.
227 template <>                                       215 template <>
228 class Task<void, void> : public TaskFuture<voi << 216 class Task<void, void> : public VTask
229 {                                                 217 {
230 public:                                           218 public:
231     using RetT               = void;           << 219     typedef void                       RetT;
232     using this_type          = Task<void, void << 220     typedef Task<void, void>           this_type;
233     using promise_type       = std::promise<Re << 221     typedef std::promise<RetT>         promise_type;
234     using future_type        = std::future<Ret << 222     typedef std::future<RetT>          future_type;
235     using packaged_task_type = std::packaged_t << 223     typedef std::packaged_task<RetT()> packaged_task_type;
236     using result_type        = RetT;           << 224     typedef RetT                       result_type;
237                                                   225 
238 public:                                           226 public:
239     template <typename FuncT>                     227     template <typename FuncT>
240     explicit Task(FuncT func)                  << 228     explicit Task(FuncT&& func)
241     : TaskFuture<RetT>{}                       << 229     : VTask()
242     , m_ptask{ std::move(func) }               << 230     , m_ptask(std::forward<FuncT>(func))
243     {}                                            231     {}
244                                                   232 
245     template <typename FuncT>                     233     template <typename FuncT>
246     Task(bool _is_native, intmax_t _depth, Fun << 234     Task(VTaskGroup* tg, FuncT&& func)
247     : TaskFuture<RetT>{ _is_native, _depth }   << 235     : VTask(tg)
248     , m_ptask{ std::move(func) }               << 236     , m_ptask(std::forward<FuncT>(func))
249     {}                                            237     {}
250                                                   238 
251     ~Task() override = default;                << 239     template <typename FuncT>
252                                                << 240     Task(ThreadPool* tp, FuncT&& func)
253     Task(const Task&) = delete;                << 241     : VTask(tp)
254     Task& operator=(const Task&) = delete;     << 242     , m_ptask(std::forward<FuncT>(func))
                                                   >> 243     {}
255                                                   244 
256     Task(Task&&)  = default;                   << 245     virtual ~Task() {}
257     Task& operator=(Task&&) = default;         << 
258                                                   246 
259 public:                                           247 public:
260     // execution operator                         248     // execution operator
261     void        operator()() final { m_ptask() << 249     virtual void operator()() final
262     future_type get_future() final { return m_ << 250     {
263     void        wait() final { return m_ptask. << 251         m_ptask();
264     RetT        get() final { return m_ptask.g << 252         // decrements the task-group counter on active tasks
                                                   >> 253         // when the counter is < 2, if the thread owning the task group is
                                                   >> 254         // sleeping at the TaskGroup::wait(), it signals the thread to wake
                                                   >> 255         // up and check if all tasks are finished, proceeding if this
                                                   >> 256         // check returns as true
                                                   >> 257         this_type::operator--();
                                                   >> 258     }
                                                   >> 259 
                                                   >> 260     virtual bool is_native_task() const override { return true; }
                                                   >> 261     future_type  get_future() { return m_ptask.get_future(); }
265                                                   262 
266 private:                                          263 private:
267     packaged_task_type m_ptask{};              << 264     packaged_task_type m_ptask;
268 };                                                265 };
269                                                   266 
270 //============================================    267 //======================================================================================//
271                                                   268 
272 }  // namespace PTL                               269 }  // namespace PTL
273                                                   270