Loading...
Searching...
No Matches
taskGraph_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_TASK_GRAPH_IMPL_H
8#define PXR_BASE_WORK_TBB_TASK_GRAPH_IMPL_H
9
10#include "pxr/pxr.h"
11#include "pxr/base/work/api.h"
12
13// The TBB version macro is located in different headers in legacy TBB
14// (tbb/tbb_stddef.h) and oneTBB (tbb/version.h)
15#if __has_include(<tbb/tbb_stddef.h>)
16#include <tbb/tbb_stddef.h>
17#elif __has_include(<tbb/version.h>)
18#include <tbb/version.h>
19#endif
20
21#ifndef TBB_INTERFACE_VERSION_MAJOR
22#error "TBB version macro TBB_INTERFACE_VERSION_MAJOR not found"
23#endif
24
25#if TBB_INTERFACE_VERSION_MAJOR < 12
26
27// Under legacy TBB we implement the task graph using tbb::task.
28//
29// tbb::task does not exist in oneTBB, so we fall back to WorkTaskGraph's
30// default implementation by not defining the WorkImpl_TaskGraph customization.
31#define WORK_IMPL_HAS_TASK_GRAPH
32
33#include <tbb/task.h>
34
35PXR_NAMESPACE_OPEN_SCOPE
36
37class WorkImpl_TaskGraph
38{
39public:
40 WORK_API WorkImpl_TaskGraph();
41 WORK_API ~WorkImpl_TaskGraph() noexcept;
42
43 WorkImpl_TaskGraph(WorkImpl_TaskGraph const &) = delete;
44 WorkImpl_TaskGraph &operator=(WorkImpl_TaskGraph const &) = delete;
45
46 class BaseTask;
47
48 template <typename F, typename ... Args>
49 F * AllocateTask(Args&&... args);
50
51 template <typename F>
52 inline void RunTask(F * task) {
53 tbb::task::spawn(*task);
54 }
55
56 WORK_API void Wait();
57
58private:
59 // Task group context for initializing the root task.
60 tbb::task_group_context _context;
61
62 // Root task that serves as an anchor to allocate additional children
63 // during execution.
64 tbb::empty_task *_rootTask;
65};
66
67class WorkImpl_TaskGraph::BaseTask : public tbb::task {
68public:
69 BaseTask() = default;
70 WORK_API virtual ~BaseTask();
71
72 void AddChildReference() {
73 increment_ref_count();
74 }
75
76 int RemoveChildReference() {
77 return decrement_ref_count();
78 }
79
80 template <typename F, typename... Args>
81 F * AllocateChild(Args &&...args) {
82 return new (tbb::task::allocate_additional_child_of(*this))
83 F{std::forward<Args>(args)...};
84 }
85
86protected:
87 void _RecycleAsContinuation() {
88 recycle_as_safe_continuation();
89 }
90
91};
92
93template <typename F, typename ... Args>
94F * WorkImpl_TaskGraph::AllocateTask(Args&&... args) {
95 return new (tbb::task::allocate_additional_child_of(*_rootTask))
96 F{std::forward<Args>(args)...};
97}
98
99PXR_NAMESPACE_CLOSE_SCOPE
100
101#endif // TBB_INTERFACE_VERSION_MAJOR < 12
102
103#endif // PXR_BASE_WORK_TBB_TASK_GRAPH_IMPL_H