Loading...
Searching...
No Matches
parallelTaskSync.h
Go to the documentation of this file.
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_EXEC_VDF_PARALLEL_TASK_SYNC_H
8#define PXR_EXEC_VDF_PARALLEL_TASK_SYNC_H
9
11
12#include "pxr/pxr.h"
13
14#include "pxr/exec/vdf/api.h"
16
17#include "pxr/base/work/taskGraph.h"
18
19#include <atomic>
20#include <cstdint>
21#include <memory>
22
23PXR_NAMESPACE_OPEN_SCOPE
24
35{
36public:
40 VdfParallelTaskSync &operator=(const VdfParallelTaskSync &) = delete;
41
45 : _waitlists(1000)
46 , _num(0)
47 , _taskGraph(taskGraph)
48 {}
49
56 VDF_API
57 void Reset(const size_t num);
58
61 enum class State {
62 Done,
63
64 Wait,
66
67 Claimed
69 };
70
78 inline State Claim(const size_t idx, WorkTaskGraph::BaseTask *successor);
79
85 inline void MarkDone(const size_t idx);
86
87private:
88
89 // The different states a task can be in.
90 enum _TaskState : uint8_t {
91 _TaskStateUnclaimed,
92 _TaskStateClaimed,
93 _TaskStateDone
94 };
95
96 // A byte-array indicating the state of each task.
97 std::unique_ptr<std::atomic<uint8_t>[]> _state;
98
99 // A pointer to the waiting queue head for each task.
100 std::unique_ptr<VdfParallelTaskWaitlist::HeadPtr[]> _waiting;
101
102 // The waitlist instance for managing the queues.
103 VdfParallelTaskWaitlist _waitlists;
104
105 // The number of tasks in this graph.
106 size_t _num;
107
108 // The task graph for running pending tasks.
109 WorkTaskGraph *_taskGraph;
110
111};
112
114
117{
118 // Get the current task state.
119 uint8_t state = _state[idx].load(std::memory_order_acquire);
120
121 // If the task has completed, bail out.
122 if (state == _TaskStateDone) {
123 return State::Done;
124 }
125
126 // If the task has not been claimed, yet, attempt to atomically claim it
127 // now. Return if this succeeds.
128 else if (state == _TaskStateUnclaimed &&
129 _state[idx].compare_exchange_strong(state, _TaskStateClaimed)) {
130 return State::Claimed;
131 }
132
133 // If we have to wait, try to enqueue in the waiting list, but bail
134 // out if the task completes while attempting to do so.
135 return _waitlists.WaitOn(&_waiting[idx], successor)
137 : State::Done;
138}
139
140void
142{
143 // Mark the task done in the state array.
144 _state[idx].store(_TaskStateDone, std::memory_order_release);
145
146 // Close the corresponding wait list and notify all waiting tasks.
147 _waitlists.CloseAndNotify(&_waiting[idx], _taskGraph);
148}
149
150PXR_NAMESPACE_CLOSE_SCOPE
151
152#endif
Instances of this class are used to synchronize dynamic, acyclic task graphs, allowing tasks to claim...
VdfParallelTaskSync(const VdfParallelTaskSync &)=delete
Noncopyable.
State
The different states a task can be in.
@ Wait
The task is already done.
@ Claimed
The task is currently running, the claimant must wait for the task to complete.
VDF_API void Reset(const size_t num)
Resets the state of all tasks in the graph.
VdfParallelTaskSync(WorkTaskGraph *taskGraph)
Constructor.
State Claim(const size_t idx, WorkTaskGraph::BaseTask *successor)
Claims the task idx for processing, and returns the new task state.
void MarkDone(const size_t idx)
Mark the task idx as done.
VdfParallelTaskWaitlist.
VDF_API bool WaitOn(HeadPtr *headPtr, WorkTaskGraph::BaseTask *successor)
Registers successor as waiting on the list denoted by headPtr.
VDF_API bool CloseAndNotify(HeadPtr *headPtr, WorkTaskGraph *taskGraph)
Closes the list denoted by headPtr, and notifies any tasks that are waiting on this list.
Base class for a parallel task that emulates tbb::task (deprecated in the oneTBB version upgrade....
Definition: taskGraph.h:106
Instances of this class are used to spawn and wait on a directed graph of tasks, where tasks preserve...
Definition: taskGraph.h:37