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 11.0)


  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 "VTask.hh"
 35                                                    35 
 36 #include <cstdint>                                 36 #include <cstdint>
 37 #include <future>                              <<  37 #include <functional>
 38 #include <tuple>                               <<  38 #include <stdexcept>
 39 #include <utility>                             << 
 40                                                    39 
 41 namespace PTL                                      40 namespace PTL
 42 {                                                  41 {
                                                   >>  42 class ThreadPool;
                                                   >>  43 
 43 //============================================     44 //======================================================================================//
 44                                                    45 
 45 /// \brief The task class is supplied to threa     46 /// \brief The task class is supplied to thread_pool.
 46 template <typename RetT>                           47 template <typename RetT>
 47 class TaskFuture : public VTask                    48 class TaskFuture : public VTask
 48 {                                                  49 {
 49 public:                                            50 public:
 50     using promise_type = std::promise<RetT>;   <<  51     typedef std::promise<RetT> promise_type;
 51     using future_type  = std::future<RetT>;    <<  52     typedef std::future<RetT>  future_type;
 52     using result_type  = RetT;                 <<  53     typedef RetT               result_type;
 53                                                    54 
 54 public:                                            55 public:
 55     // pass a free function pointer                56     // pass a free function pointer
 56     template <typename... Args>                    57     template <typename... Args>
 57     TaskFuture(Args&&... args)                     58     TaskFuture(Args&&... args)
 58     : VTask{ std::forward<Args>(args)... }         59     : VTask{ std::forward<Args>(args)... }
 59     {}                                             60     {}
 60                                                    61 
 61     ~TaskFuture() override = default;          <<  62     virtual ~TaskFuture() = default;
 62                                                    63 
 63     TaskFuture(const TaskFuture&) = delete;        64     TaskFuture(const TaskFuture&) = delete;
 64     TaskFuture& operator=(const TaskFuture&) =     65     TaskFuture& operator=(const TaskFuture&) = delete;
 65                                                    66 
 66     TaskFuture(TaskFuture&&) noexcept = defaul <<  67     TaskFuture(TaskFuture&&) = default;
 67     TaskFuture& operator=(TaskFuture&&) noexce <<  68     TaskFuture& operator=(TaskFuture&&) = default;
 68                                                    69 
 69 public:                                            70 public:
 70     // execution operator                          71     // execution operator
 71     virtual future_type get_future() = 0;          72     virtual future_type get_future() = 0;
 72     virtual void        wait()       = 0;          73     virtual void        wait()       = 0;
 73     virtual RetT        get()        = 0;          74     virtual RetT        get()        = 0;
 74 };                                                 75 };
 75                                                    76 
 76 //============================================     77 //======================================================================================//
 77                                                    78 
 78 /// \brief The task class is supplied to threa     79 /// \brief The task class is supplied to thread_pool.
 79 template <typename RetT, typename... Args>         80 template <typename RetT, typename... Args>
 80 class PackagedTask : public TaskFuture<RetT>       81 class PackagedTask : public TaskFuture<RetT>
 81 {                                                  82 {
 82 public:                                            83 public:
 83     using this_type          = PackagedTask<Re <<  84     typedef PackagedTask<RetT, Args...>       this_type;
 84     using promise_type       = std::promise<Re <<  85     typedef std::promise<RetT>                promise_type;
 85     using future_type        = std::future<Ret <<  86     typedef std::future<RetT>                 future_type;
 86     using packaged_task_type = std::packaged_t <<  87     typedef std::packaged_task<RetT(Args...)> packaged_task_type;
 87     using result_type        = RetT;           <<  88     typedef RetT                              result_type;
 88     using tuple_type         = std::tuple<Args <<  89     typedef std::tuple<Args...>               tuple_type;
 89                                                    90 
 90 public:                                            91 public:
 91     // pass a free function pointer                92     // pass a free function pointer
 92     template <typename FuncT>                      93     template <typename FuncT>
 93     PackagedTask(FuncT func, Args... args)         94     PackagedTask(FuncT func, Args... args)
 94     : TaskFuture<RetT>{ true, 0 }                  95     : TaskFuture<RetT>{ true, 0 }
 95     , m_ptask{ std::move(func) }                   96     , m_ptask{ std::move(func) }
 96     , m_args{ args... }                            97     , m_args{ args... }
 97     {}                                             98     {}
 98                                                    99 
 99     template <typename FuncT>                     100     template <typename FuncT>
100     PackagedTask(bool _is_native, intmax_t _de    101     PackagedTask(bool _is_native, intmax_t _depth, FuncT func, Args... args)
101     : TaskFuture<RetT>{ _is_native, _depth }      102     : TaskFuture<RetT>{ _is_native, _depth }
102     , m_ptask{ std::move(func) }                  103     , m_ptask{ std::move(func) }
103     , m_args{ args... }                           104     , m_args{ args... }
104     {}                                            105     {}
105                                                   106 
106     ~PackagedTask() override = default;        << 107     virtual ~PackagedTask() = default;
107                                                   108 
108     PackagedTask(const PackagedTask&) = delete    109     PackagedTask(const PackagedTask&) = delete;
109     PackagedTask& operator=(const PackagedTask    110     PackagedTask& operator=(const PackagedTask&) = delete;
110                                                   111 
111     PackagedTask(PackagedTask&&) noexcept = de << 112     PackagedTask(PackagedTask&&) = default;
112     PackagedTask& operator=(PackagedTask&&) no << 113     PackagedTask& operator=(PackagedTask&&) = default;
113                                                   114 
114 public:                                           115 public:
115     // execution operator                         116     // execution operator
116     void        operator()() final { PTL::appl << 117     virtual void operator()() final { mpl::apply(std::move(m_ptask), std::move(m_args)); }
117     future_type get_future() final { return m_ << 118     virtual future_type get_future() final { return m_ptask.get_future(); }
118     void        wait() final { return m_ptask. << 119     virtual void        wait() final { return m_ptask.get_future().wait(); }
119     RetT        get() final { return m_ptask.g << 120     virtual RetT        get() final { return m_ptask.get_future().get(); }
120                                                   121 
121 private:                                          122 private:
122     packaged_task_type m_ptask;                   123     packaged_task_type m_ptask;
123     tuple_type         m_args;                    124     tuple_type         m_args;
124 };                                                125 };
125                                                   126 
126 //============================================    127 //======================================================================================//
127                                                   128 
128 /// \brief The task class is supplied to threa    129 /// \brief The task class is supplied to thread_pool.
129 template <typename RetT, typename... Args>        130 template <typename RetT, typename... Args>
130 class Task : public TaskFuture<RetT>              131 class Task : public TaskFuture<RetT>
131 {                                                 132 {
132 public:                                           133 public:
133     using this_type          = Task<RetT, Args << 134     typedef Task<RetT, Args...>               this_type;
134     using promise_type       = std::promise<Re << 135     typedef std::promise<RetT>                promise_type;
135     using future_type        = std::future<Ret << 136     typedef std::future<RetT>                 future_type;
136     using packaged_task_type = std::packaged_t << 137     typedef std::packaged_task<RetT(Args...)> packaged_task_type;
137     using result_type        = RetT;           << 138     typedef RetT                              result_type;
138     using tuple_type         = std::tuple<Args << 139     typedef std::tuple<Args...>               tuple_type;
139                                                   140 
140 public:                                           141 public:
141     template <typename FuncT>                     142     template <typename FuncT>
142     Task(FuncT func, Args... args)                143     Task(FuncT func, Args... args)
143     : TaskFuture<RetT>{}                          144     : TaskFuture<RetT>{}
144     , m_ptask{ std::move(func) }                  145     , m_ptask{ std::move(func) }
145     , m_args{ args... }                           146     , m_args{ args... }
146     {}                                            147     {}
147                                                   148 
148     template <typename FuncT>                     149     template <typename FuncT>
149     Task(bool _is_native, intmax_t _depth, Fun    150     Task(bool _is_native, intmax_t _depth, FuncT func, Args... args)
150     : TaskFuture<RetT>{ _is_native, _depth }      151     : TaskFuture<RetT>{ _is_native, _depth }
151     , m_ptask{ std::move(func) }                  152     , m_ptask{ std::move(func) }
152     , m_args{ args... }                           153     , m_args{ args... }
153     {}                                            154     {}
154                                                   155 
155     ~Task() override = default;                << 156     virtual ~Task() = default;
156                                                   157 
157     Task(const Task&) = delete;                   158     Task(const Task&) = delete;
158     Task& operator=(const Task&) = delete;        159     Task& operator=(const Task&) = delete;
159                                                   160 
160     Task(Task&&) noexcept = default;           << 161     Task(Task&&)  = default;
161     Task& operator=(Task&&) noexcept = default << 162     Task& operator=(Task&&) = default;
162                                                   163 
163 public:                                           164 public:
164     // execution operator                         165     // execution operator
165     void operator()() final                    << 166     virtual void operator()() final
166     {                                             167     {
167         if(m_ptask.valid())                       168         if(m_ptask.valid())
168             PTL::apply(std::move(m_ptask), std << 169             mpl::apply(std::move(m_ptask), std::move(m_args));
169     }                                             170     }
170     future_type get_future() final { return m_ << 171     virtual future_type get_future() final { return m_ptask.get_future(); }
171     void        wait() final { return m_ptask. << 172     virtual void        wait() final { return m_ptask.get_future().wait(); }
172     RetT        get() final { return m_ptask.g << 173     virtual RetT        get() final { return m_ptask.get_future().get(); }
173                                                   174 
174 private:                                          175 private:
175     packaged_task_type m_ptask{};                 176     packaged_task_type m_ptask{};
176     tuple_type         m_args{};                  177     tuple_type         m_args{};
177 };                                                178 };
178                                                   179 
179 //============================================    180 //======================================================================================//
180                                                   181 
181 /// \brief The task class is supplied to threa    182 /// \brief The task class is supplied to thread_pool.
182 template <typename RetT>                          183 template <typename RetT>
183 class Task<RetT, void> : public TaskFuture<Ret    184 class Task<RetT, void> : public TaskFuture<RetT>
184 {                                                 185 {
185 public:                                           186 public:
186     using this_type          = Task<RetT>;     << 187     typedef Task<RetT>                 this_type;
187     using promise_type       = std::promise<Re << 188     typedef std::promise<RetT>         promise_type;
188     using future_type        = std::future<Ret << 189     typedef std::future<RetT>          future_type;
189     using packaged_task_type = std::packaged_t << 190     typedef std::packaged_task<RetT()> packaged_task_type;
190     using result_type        = RetT;           << 191     typedef RetT                       result_type;
191                                                   192 
192 public:                                           193 public:
193     template <typename FuncT>                     194     template <typename FuncT>
194     Task(FuncT func)                              195     Task(FuncT func)
195     : TaskFuture<RetT>()                          196     : TaskFuture<RetT>()
196     , m_ptask{ std::move(func) }                  197     , m_ptask{ std::move(func) }
197     {}                                            198     {}
198                                                   199 
199     template <typename FuncT>                     200     template <typename FuncT>
200     Task(bool _is_native, intmax_t _depth, Fun    201     Task(bool _is_native, intmax_t _depth, FuncT func)
201     : TaskFuture<RetT>{ _is_native, _depth }      202     : TaskFuture<RetT>{ _is_native, _depth }
202     , m_ptask{ std::move(func) }                  203     , m_ptask{ std::move(func) }
203     {}                                            204     {}
204                                                   205 
205     virtual ~Task() = default;                    206     virtual ~Task() = default;
206                                                   207 
207     Task(const Task&) = delete;                   208     Task(const Task&) = delete;
208     Task& operator=(const Task&) = delete;        209     Task& operator=(const Task&) = delete;
209                                                   210 
210     Task(Task&&) noexcept = default;           << 211     Task(Task&&)  = default;
211     Task& operator=(Task&&) noexcept = default << 212     Task& operator=(Task&&) = default;
212                                                   213 
213 public:                                           214 public:
214     // execution operator                         215     // execution operator
215     virtual void        operator()() final { m    216     virtual void        operator()() final { m_ptask(); }
216     virtual future_type get_future() final { r    217     virtual future_type get_future() final { return m_ptask.get_future(); }
217     virtual void        wait() final { return     218     virtual void        wait() final { return m_ptask.get_future().wait(); }
218     virtual RetT        get() final { return m    219     virtual RetT        get() final { return m_ptask.get_future().get(); }
219                                                   220 
220 private:                                          221 private:
221     packaged_task_type m_ptask{};                 222     packaged_task_type m_ptask{};
222 };                                                223 };
223                                                   224 
224 //============================================    225 //======================================================================================//
225                                                   226 
226 /// \brief The task class is supplied to threa    227 /// \brief The task class is supplied to thread_pool.
227 template <>                                       228 template <>
228 class Task<void, void> : public TaskFuture<voi    229 class Task<void, void> : public TaskFuture<void>
229 {                                                 230 {
230 public:                                           231 public:
231     using RetT               = void;           << 232     typedef void                       RetT;
232     using this_type          = Task<void, void << 233     typedef Task<void, void>           this_type;
233     using promise_type       = std::promise<Re << 234     typedef std::promise<RetT>         promise_type;
234     using future_type        = std::future<Ret << 235     typedef std::future<RetT>          future_type;
235     using packaged_task_type = std::packaged_t << 236     typedef std::packaged_task<RetT()> packaged_task_type;
236     using result_type        = RetT;           << 237     typedef RetT                       result_type;
237                                                   238 
238 public:                                           239 public:
239     template <typename FuncT>                     240     template <typename FuncT>
240     explicit Task(FuncT func)                     241     explicit Task(FuncT func)
241     : TaskFuture<RetT>{}                          242     : TaskFuture<RetT>{}
242     , m_ptask{ std::move(func) }                  243     , m_ptask{ std::move(func) }
243     {}                                            244     {}
244                                                   245 
245     template <typename FuncT>                     246     template <typename FuncT>
246     Task(bool _is_native, intmax_t _depth, Fun    247     Task(bool _is_native, intmax_t _depth, FuncT func)
247     : TaskFuture<RetT>{ _is_native, _depth }      248     : TaskFuture<RetT>{ _is_native, _depth }
248     , m_ptask{ std::move(func) }                  249     , m_ptask{ std::move(func) }
249     {}                                            250     {}
250                                                   251 
251     ~Task() override = default;                << 252     virtual ~Task() = default;
252                                                   253 
253     Task(const Task&) = delete;                   254     Task(const Task&) = delete;
254     Task& operator=(const Task&) = delete;        255     Task& operator=(const Task&) = delete;
255                                                   256 
256     Task(Task&&)  = default;                      257     Task(Task&&)  = default;
257     Task& operator=(Task&&) = default;            258     Task& operator=(Task&&) = default;
258                                                   259 
259 public:                                           260 public:
260     // execution operator                         261     // execution operator
261     void        operator()() final { m_ptask() << 262     virtual void        operator()() final { m_ptask(); }
262     future_type get_future() final { return m_ << 263     virtual future_type get_future() final { return m_ptask.get_future(); }
263     void        wait() final { return m_ptask. << 264     virtual void        wait() final { return m_ptask.get_future().wait(); }
264     RetT        get() final { return m_ptask.g << 265     virtual RetT        get() final { return m_ptask.get_future().get(); }
265                                                   266 
266 private:                                          267 private:
267     packaged_task_type m_ptask{};                 268     packaged_task_type m_ptask{};
268 };                                                269 };
269                                                   270 
270 //============================================    271 //======================================================================================//
271                                                   272 
272 }  // namespace PTL                               273 }  // namespace PTL
273                                                   274