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 ]

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