7#ifndef PXR_BASE_WORK_DISPATCHER_H
8#define PXR_BASE_WORK_DISPATCHER_H
14#include "pxr/base/work/api.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>
33PXR_NAMESPACE_OPEN_SCOPE
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
97 _taskGroup.run(_InvokerTask<
typename std::remove_reference<Callable>::type>(std::forward<Callable>(c), &_errors));
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;
186 _InvokerTask<typename std::remove_reference<Fn>::type>&
187 _MakeInvokerTask(Fn &&fn) {
188 return *
new( _rootTask->allocate_additional_child_of(*_rootTask) )
189 _InvokerTask<
typename std::remove_reference<Fn>::type>(
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;
227struct Work_DeprecatedMutableTask {
228 explicit Work_DeprecatedMutableTask(Fn &&fn)
229 : _fn(
std::move(fn)) {}
231 explicit Work_DeprecatedMutableTask(Fn
const &fn)
235 Work_DeprecatedMutableTask
236 (Work_DeprecatedMutableTask &&other) =
default;
237 Work_DeprecatedMutableTask
238 (
const Work_DeprecatedMutableTask &other) =
delete;
239 Work_DeprecatedMutableTask
240 &operator= (
const Work_DeprecatedMutableTask &other) =
delete;
242 void operator()()
const {
252template <
typename Fn>
253Work_DeprecatedMutableTask<typename std::remove_reference_t<Fn>>
254WorkMakeDeprecatedMutableTask(Fn &&fn) {
255 return Work_DeprecatedMutableTask<typename std::remove_reference_t<Fn>>
256 (std::forward<Fn>(fn));
261PXR_NAMESPACE_CLOSE_SCOPE
Class used to record the end of the error-list.
bool IsClean() const
Return true if no new errors were posted in this thread since the last call to SetMark(),...
A work dispatcher runs concurrent tasks.
WORK_API ~WorkDispatcher() noexcept
Wait() for any pending tasks to complete, then destroy the dispatcher.
WORK_API void Cancel()
Cancel remaining work and return immediately.
WORK_API bool IsCancelled() const
Returns true if Cancel() has been called.
WORK_API void Wait()
Block until the work started by Run() completes.
WORK_API WorkDispatcher()
Construct a new dispatcher.
void Run(Callable &&c, A1 &&a1, A2 &&a2,... AN &&aN)
Add work for the dispatcher to run.