|
| | JobGraph (ThreadPool &pool, Allocator *allocator) |
| |
| | JobGraph (JobGraph const &)=delete |
| |
| JobGraph & | operator= (JobGraph const &)=delete |
| |
| | ~JobGraph () |
| |
| template<typename Fn > |
| JobHandle | AddJob (StringView name, ExecutionPolicy policy, Fn &&fn) |
| | A single body that runs once on a pool worker (or the main thread under Seq / no workers).
|
| |
| template<typename Fn > |
| JobHandle | AddMain (StringView name, Fn &&fn) |
| | A single body that always runs on the thread calling Wait / PumpMainThread.
|
| |
| template<typename Fn > |
| JobHandle | AddParallelFor (StringView name, ExecutionPolicy policy, size_t count, Fn &&fn) |
| | Index parallel-for body invoked as fn(i) or fn(i, workerId) for each index.
|
| |
template<typename It , typename Fn >
requires std::random_access_iterator<It> |
| JobHandle | AddParallelFor (StringView name, ExecutionPolicy policy, It first, It last, Fn &&fn) |
| | Iterator-range parallel-for (random-access iterators), like the ThreadPool overload.
|
| |
| JobHandle | AddBarrier (StringView name) |
| | A work-less join node that completes once all its producers complete.
|
| |
| template<typename... Producers> |
| void | DependsOn (JobHandle consumer, Producers... producers) |
| | Declares that consumer may only run after every producers has completed.
|
| |
| void | Submit () |
| | Arms the graph and schedules all dependency-free nodes. Call exactly once.
|
| |
| void | Wait (JobHandle target) |
| | Runs ready main-thread nodes on the caller, then blocks until target completes.
|
| |
| void | Wait () |
| | Blocks until the whole graph completes (pumping main-thread nodes on the caller).
|
| |
| void | PumpMainThread () |
| | Runs every currently-ready main-thread node on the caller without blocking.
|
| |
| size_t | MainWorkerId () const noexcept |
| | Worker id handed to main-thread node bodies (== ThreadPool::GetWorkerCount).
|
| |
A small, transient CPU job graph layered on top of ThreadPool.
The pool stays a flat worker executor; JobGraph adds first-class dependency handles so a caller can express a frame's CPU work as nodes + edges instead of hand-placed futures. A node becomes schedulable once all of its producers complete:
Worker / ParallelFor nodes (with ExecutionPolicy::Par and a pool that has workers) dispatch to the pool. A ParallelFor fans out across the workers using a shared cursor + a fork-join latch, exactly like ThreadPool::ParallelForAsync.
Main nodes (and any node forced serial via ExecutionPolicy::Seq, or when the pool has no workers) run on the thread that calls Wait / PumpMainThread, never on a worker. This is the home for main-thread-only steps.
Barrier nodes carry no work; they complete as soon as their producers do, useful as a single join handle to Wait on.
Build (single-threaded) -> Submit -> do other work -> Wait. The graph object must outlive its in-flight work; Wait (and the destructor) block until it drains.
- Note
- Worker ids handed to node bodies follow the pool's contract: pool workers see ids in [0, ThreadPool::GetWorkerCount); main-thread nodes see MainWorkerId() (== worker count), matching ThreadPool::GetParallelForConcurrency so per-worker scratch sized to that concurrency stays race-free.
-
Scope is intentionally small: no cancellation, no result values, no persistent/nested graphs. Build a fresh graph per logical batch.