Loading...
Searching...
No Matches
dispatcher_impl.h
1//
2// Copyright 2025 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_WORK_TBB_DISPATCHER_IMPL_H
8#define PXR_BASE_WORK_TBB_DISPATCHER_IMPL_H
9
10#include "pxr/pxr.h"
11#include "pxr/base/work/api.h"
12#include "pxr/base/work/workTBB/tbb_version.h"
13
14#include <tbb/concurrent_vector.h>
15#if TBB_INTERFACE_VERSION_MAJOR >= 12
16#include <tbb/task_group.h>
17#else
18#include <tbb/task.h>
19#endif
20
21#include <functional>
22#include <type_traits>
23#include <utility>
24
25PXR_NAMESPACE_OPEN_SCOPE
26
27class WorkImpl_Dispatcher
28{
29public:
31 WORK_API WorkImpl_Dispatcher();
32
34 WORK_API ~WorkImpl_Dispatcher() noexcept;
35
36 WorkImpl_Dispatcher(WorkImpl_Dispatcher const &) = delete;
37 WorkImpl_Dispatcher &operator=(WorkImpl_Dispatcher const &) = delete;
38
39 template <class Callable>
40 inline void Run(Callable &&c) {
41#if TBB_INTERFACE_VERSION_MAJOR >= 12
42 _taskGroup.run(std::forward<Callable>(c));
43#else
44 _rootTask->spawn(
45 *new(_rootTask->allocate_additional_child_of(*_rootTask))
46 _InvokerTaskWrapper<typename std::remove_reference<Callable>::type>(
47 std::forward<Callable>(c)));
48#endif
49 }
50
52 WORK_API void Reset();
53
55 WORK_API void Wait();
56
67 WORK_API void Cancel();
68
69#if TBB_INTERFACE_VERSION_MAJOR < 12
70 template <class Fn>
71 struct _InvokerTaskWrapper : public tbb::task {
72 explicit _InvokerTaskWrapper(Fn &&fn)
73 : _fn(std::move(fn)) {}
74
75 explicit _InvokerTaskWrapper(Fn const &fn)
76 : _fn(fn) {}
77
78 virtual tbb::task* execute() {
79 // In anticipation of OneTBB, ensure that _fn meets OneTBB's
80 // requirement that a task's call operator must be const.
81 const_cast<_InvokerTaskWrapper const *>(this)->_fn();
82 return NULL;
83 }
84 private:
85 Fn _fn;
86 };
87#endif
88 // Task group context to run tasks in.
89 tbb::task_group_context _context;
90#if TBB_INTERFACE_VERSION_MAJOR >= 12
91 // Custom task group that lets us implement thread safe concurrent wait.
92 class _TaskGroup : public tbb::task_group {
93 public:
94 _TaskGroup(tbb::task_group_context& ctx) : tbb::task_group(ctx) {}
95 inline tbb::detail::d1::wait_context& _GetInternalWaitContext();
96 };
97
98 _TaskGroup _taskGroup;
99#else
100 // Root task that allows us to cancel tasks invoked directly by this
101 // dispatcher.
102 tbb::empty_task* _rootTask;
103#endif
104
105};
106
107PXR_NAMESPACE_CLOSE_SCOPE
108
110
111#endif // PXR_BASE_WORK_TBB_DISPATCHER_IMPL_H
STL namespace.