7 #ifndef PXR_BASE_WORK_DISPATCHER_H
8 #define PXR_BASE_WORK_DISPATCHER_H
21 #include <tbb/blocked_range.h>
22 #include <tbb/concurrent_vector.h>
23 #if TBB_INTERFACE_VERSION_MAJOR >= 12
24 #include <tbb/task_group.h>
30 #include <type_traits>
75 WorkDispatcher &
operator=(WorkDispatcher
const &) =
delete;
89 template <
class Callable,
class A1,
class A2, ...
class AN>
90 void Run(Callable &&
c, A1 &&a1, A2 &&a2, ... AN &&aN);
94 template <
class Callable>
95 inline void Run(Callable &&
c) {
96 #if TBB_INTERFACE_VERSION_MAJOR >= 12
99 _rootTask->spawn(_MakeInvokerTask(std::forward<Callable>(
c)));
103 template <
class Callable,
class A0,
class ... Args>
104 inline void Run(Callable &&
c, A0 &&a0, Args&&...
args) {
105 Run(std::bind(std::forward<Callable>(
c),
106 std::forward<A0>(a0),
107 std::forward<Args>(
args)...));
132 typedef tbb::concurrent_vector<TfErrorTransport> _ErrorTransports;
137 #if TBB_INTERFACE_VERSION_MAJOR >= 12
139 struct _InvokerTask {
140 explicit _InvokerTask(Fn &&fn, _ErrorTransports *err)
141 : _fn(std::move(fn)), _errors(err) {}
143 explicit _InvokerTask(Fn
const &fn, _ErrorTransports *err)
144 : _fn(fn), _errors(err) {}
147 _InvokerTask(_InvokerTask &&other) =
default;
148 _InvokerTask(
const _InvokerTask &other) =
delete;
149 _InvokerTask &
operator=(
const _InvokerTask &other) =
delete;
151 void operator()()
const {
155 WorkDispatcher::_TransportErrors(m, _errors);
159 _ErrorTransports *_errors;
163 struct _InvokerTask :
public tbb::task {
164 explicit _InvokerTask(Fn &&fn, _ErrorTransports *err)
165 : _fn(std::move(fn)), _errors(err) {}
167 explicit _InvokerTask(Fn
const &fn, _ErrorTransports *err)
168 : _fn(fn), _errors(err) {}
170 virtual tbb::task* execute() {
174 const_cast<_InvokerTask
const *
>(
this)->_fn();
176 WorkDispatcher::_TransportErrors(m, _errors);
181 _ErrorTransports *_errors;
187 _MakeInvokerTask(Fn &&fn) {
188 return *
new( _rootTask->allocate_additional_child_of(*_rootTask) )
190 std::forward<Fn>(fn), &_errors);
197 _TransportErrors(
const TfErrorMark &m, _ErrorTransports *errors);
200 tbb::task_group_context _context;
201 #if TBB_INTERFACE_VERSION_MAJOR >= 12
203 class _TaskGroup :
public tbb::task_group {
205 _TaskGroup(tbb::task_group_context& ctx) : tbb::task_group(ctx) {}
206 inline tbb::detail::d1::wait_context& _GetInternalWaitContext();
209 _TaskGroup _taskGroup;
213 tbb::empty_task* _rootTask;
215 std::atomic<bool> _isCancelled;
219 _ErrorTransports _errors;
222 std::atomic_flag _waitCleanupFlag;
229 : _fn(std::move(fn)) {}
252 template <
typename Fn>
256 (std::forward<Fn>(fn));
263 #endif // PXR_BASE_WORK_DISPATCHER_H
Work_DeprecatedMutableTask(Fn const &fn)
void Run(Callable &&c, A0 &&a0, Args &&...args)
WorkDispatcher & operator=(WorkDispatcher const &)=delete
WORK_API bool IsCancelled() const
WORK_API ~WorkDispatcher() noexcept
Wait() for any pending tasks to complete, then destroy the dispatcher.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Work_DeprecatedMutableTask< typename std::remove_reference_t< Fn > > WorkMakeDeprecatedMutableTask(Fn &&fn)
WORK_API WorkDispatcher()
Construct a new dispatcher.
Work_DeprecatedMutableTask(Fn &&fn)
#define PXR_NAMESPACE_CLOSE_SCOPE
**If you just want to fire and args
WORK_API void Wait()
Block until the work started by Run() completes.
Work_DeprecatedMutableTask & operator=(const Work_DeprecatedMutableTask &other)=delete