Loading...
Searching...
No Matches
taskGraph_defaultImpl.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_TASK_GRAPH_DEFAULT_IMPL_H
8#define PXR_BASE_WORK_TASK_GRAPH_DEFAULT_IMPL_H
9
10#include "pxr/pxr.h"
11
12#include "pxr/base/work/api.h"
14
15#include <atomic>
16#include <utility>
17
18PXR_NAMESPACE_OPEN_SCOPE
19
20// Default implementation for WorkTaskGraph.
21// See documentation on WorkTaskGraph and WorkTaskGraph::BaskTask for API docs.
22
23class WorkTaskGraph_DefaultImpl
24{
25public:
26 WorkTaskGraph_DefaultImpl() = default;
27 ~WorkTaskGraph_DefaultImpl() noexcept = default;
28
29 WorkTaskGraph_DefaultImpl(WorkTaskGraph_DefaultImpl const &) = delete;
30 WorkTaskGraph_DefaultImpl &
31 operator=(WorkTaskGraph_DefaultImpl const &) = delete;
32
33 class BaseTask;
34
35 template <typename F, typename ... Args>
36 F * AllocateTask(Args&&... args);
37
38 template <typename F>
39 inline void RunTask(F * task) {
40 task->_SetTaskGraph(this);
41 _dispatcher.Run(std::ref(*task));
42 }
43
44 WORK_API void Wait();
45
46private:
47 // Work dispatcher for running and synchronizing on tasks.
48 WorkDispatcher _dispatcher;
49};
50
51class WorkTaskGraph_DefaultImpl::BaseTask {
52public:
53 BaseTask() = default;
54 WORK_API virtual ~BaseTask();
55
58 WORK_API void operator()(const int depth = 0,
59 WorkTaskGraph_DefaultImpl * const taskGraph = nullptr) const;
60
61 virtual BaseTask * execute() = 0;
62
63 void AddChildReference() {
64 _childCount.fetch_add(1, std::memory_order_acquire);
65 }
66
67 int RemoveChildReference() {
68 return _childCount.fetch_sub(1, std::memory_order_release) - 1;
69 }
70
71 template <typename F, typename ... Args>
72 F * AllocateChild(Args&&... args) {
73 AddChildReference();
74 F* obj = new F{std::forward<Args>(args)...};
75 obj->_parent = this;
76 return obj;
77 }
78
79protected:
80 void _RecycleAsContinuation() {
81 _recycle = true;
82 }
83
84private:
85 // Befriend the task graph that owns instances of this class.
86 friend class WorkTaskGraph_DefaultImpl;
87
88 // Set the back-pointer to this task's owning task graph.
89 void _SetTaskGraph(WorkTaskGraph_DefaultImpl * const taskGraph) {
90 _taskGraph = taskGraph;
91 }
92
93private:
94 // The task graph that owns this task.
95 WorkTaskGraph_DefaultImpl * _taskGraph = nullptr;
96
97 // The parent/successor of this task.
98 BaseTask * _parent = nullptr;
99
100 // A flag that indicates whether this task is awaiting re-execution.
101 bool _recycle = false;
102
103 // An atomic reference count to track this task's pending children.
104 std::atomic<int> _childCount = 0;
105};
106
107template <typename F, typename ... Args>
108F * WorkTaskGraph_DefaultImpl::AllocateTask(Args&&... args) {
109 return new F{std::forward<Args>(args)...};
110}
111
112PXR_NAMESPACE_CLOSE_SCOPE
113
114#endif
A work dispatcher runs concurrent tasks.
Definition: dispatcher.h:176