Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Core/JobSystemWithBarrier.h
9906 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2023 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#pragma once
6
7
#include <Jolt/Core/JobSystem.h>
8
#include <Jolt/Core/Semaphore.h>
9
10
JPH_NAMESPACE_BEGIN
11
12
/// Implementation of the Barrier class for a JobSystem
13
///
14
/// This class can be used to make it easier to create a new JobSystem implementation that integrates with your own job system.
15
/// It will implement all functionality relating to barriers, so the only functions that are left to be implemented are:
16
///
17
/// * JobSystem::GetMaxConcurrency
18
/// * JobSystem::CreateJob
19
/// * JobSystem::FreeJob
20
/// * JobSystem::QueueJob/QueueJobs
21
///
22
/// See instructions in JobSystem for more information on how to implement these.
23
class JPH_EXPORT JobSystemWithBarrier : public JobSystem
24
{
25
public:
26
JPH_OVERRIDE_NEW_DELETE
27
28
/// Constructs barriers
29
/// @see JobSystemWithBarrier::Init
30
explicit JobSystemWithBarrier(uint inMaxBarriers);
31
JobSystemWithBarrier() = default;
32
virtual ~JobSystemWithBarrier() override;
33
34
/// Initialize the barriers
35
/// @param inMaxBarriers Max number of barriers that can be allocated at any time
36
void Init(uint inMaxBarriers);
37
38
// See JobSystem
39
virtual Barrier * CreateBarrier() override;
40
virtual void DestroyBarrier(Barrier *inBarrier) override;
41
virtual void WaitForJobs(Barrier *inBarrier) override;
42
43
private:
44
class BarrierImpl : public Barrier
45
{
46
public:
47
JPH_OVERRIDE_NEW_DELETE
48
49
/// Constructor
50
BarrierImpl();
51
virtual ~BarrierImpl() override;
52
53
// See Barrier
54
virtual void AddJob(const JobHandle &inJob) override;
55
virtual void AddJobs(const JobHandle *inHandles, uint inNumHandles) override;
56
57
/// Check if there are any jobs in the job barrier
58
inline bool IsEmpty() const { return mJobReadIndex == mJobWriteIndex; }
59
60
/// Wait for all jobs in this job barrier, while waiting, execute jobs that are part of this barrier on the current thread
61
void Wait();
62
63
/// Flag to indicate if a barrier has been handed out
64
atomic<bool> mInUse { false };
65
66
protected:
67
/// Called by a Job to mark that it is finished
68
virtual void OnJobFinished(Job *inJob) override;
69
70
/// Jobs queue for the barrier
71
static constexpr uint cMaxJobs = 2048;
72
static_assert(IsPowerOf2(cMaxJobs)); // We do bit operations and require max jobs to be a power of 2
73
atomic<Job *> mJobs[cMaxJobs]; ///< List of jobs that are part of this barrier, nullptrs for empty slots
74
alignas(JPH_CACHE_LINE_SIZE) atomic<uint> mJobReadIndex { 0 }; ///< First job that could be valid (modulo cMaxJobs), can be nullptr if other thread is still working on adding the job
75
alignas(JPH_CACHE_LINE_SIZE) atomic<uint> mJobWriteIndex { 0 }; ///< First job that can be written (modulo cMaxJobs)
76
atomic<int> mNumToAcquire { 0 }; ///< Number of times the semaphore has been released, the barrier should acquire the semaphore this many times (written at the same time as mJobWriteIndex so ok to put in same cache line)
77
Semaphore mSemaphore; ///< Semaphore used by finishing jobs to signal the barrier that they're done
78
};
79
80
/// Array of barriers (we keep them constructed all the time since constructing a semaphore/mutex is not cheap)
81
uint mMaxBarriers = 0; ///< Max amount of barriers
82
BarrierImpl * mBarriers = nullptr; ///< List of the actual barriers
83
};
84
85
JPH_NAMESPACE_END
86
87