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
13// Blocked range is not used in this file, but this header happens to pull in
14// the TBB version header in a way that works in all TBB versions.
15#include <tbb/blocked_range.h>
16#include <tbb/concurrent_vector.h>
17#if TBB_INTERFACE_VERSION_MAJOR >= 12
18#include <tbb/task_group.h>
19#else
20#include <tbb/task.h>
21#endif
22
23#include <functional>
24#include <type_traits>
25#include <utility>
26
27PXR_NAMESPACE_OPEN_SCOPE
28
29class WorkImpl_Dispatcher
30{
31public:
33 WORK_API WorkImpl_Dispatcher();
34
36 WORK_API ~WorkImpl_Dispatcher() noexcept;
37
38 WorkImpl_Dispatcher(WorkImpl_Dispatcher const &) = delete;
39 WorkImpl_Dispatcher &operator=(WorkImpl_Dispatcher const &) = delete;
40
41 template <class Callable>
42 inline void Run(Callable &&c) {
43#if TBB_INTERFACE_VERSION_MAJOR >= 12
44 _taskGroup.run(std::forward<Callable>(c));
45#else
46 _rootTask->spawn(
47 *new(_rootTask->allocate_additional_child_of(*_rootTask))
48 _InvokerTaskWrapper<typename std::remove_reference<Callable>::type>(
49 std::forward<Callable>(c)));
50#endif
51 }
52
54 WORK_API void Reset();
55
57 WORK_API void Wait();
58
69 WORK_API void Cancel();
70
71#if TBB_INTERFACE_VERSION_MAJOR < 12
72 template <class Fn>
73 struct _InvokerTaskWrapper : public tbb::task {
74 explicit _InvokerTaskWrapper(Fn &&fn)
75 : _fn(std::move(fn)) {}
76
77 explicit _InvokerTaskWrapper(Fn const &fn)
78 : _fn(fn) {}
79
80 virtual tbb::task* execute() {
81 // In anticipation of OneTBB, ensure that _fn meets OneTBB's
82 // requirement that a task's call operator must be const.
83 const_cast<_InvokerTaskWrapper const *>(this)->_fn();
84 return NULL;
85 }
86 private:
87 Fn _fn;
88 };
89#endif
90 // Task group context to run tasks in.
91 tbb::task_group_context _context;
92#if TBB_INTERFACE_VERSION_MAJOR >= 12
93 // Custom task group that lets us implement thread safe concurrent wait.
94 class _TaskGroup : public tbb::task_group {
95 public:
96 _TaskGroup(tbb::task_group_context& ctx) : tbb::task_group(ctx) {}
97 inline tbb::detail::d1::wait_context& _GetInternalWaitContext();
98 };
99
100 _TaskGroup _taskGroup;
101#else
102 // Root task that allows us to cancel tasks invoked directly by this
103 // dispatcher.
104 tbb::empty_task* _rootTask;
105#endif
106
107};
108
109PXR_NAMESPACE_CLOSE_SCOPE
110
112
113#endif // PXR_BASE_WORK_TBB_DISPATCHER_IMPL_H
STL namespace.