Path: blob/master/thirdparty/jolt_physics/Jolt/Core/JobSystemWithBarrier.h
9906 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2023 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Core/JobSystem.h>7#include <Jolt/Core/Semaphore.h>89JPH_NAMESPACE_BEGIN1011/// Implementation of the Barrier class for a JobSystem12///13/// This class can be used to make it easier to create a new JobSystem implementation that integrates with your own job system.14/// It will implement all functionality relating to barriers, so the only functions that are left to be implemented are:15///16/// * JobSystem::GetMaxConcurrency17/// * JobSystem::CreateJob18/// * JobSystem::FreeJob19/// * JobSystem::QueueJob/QueueJobs20///21/// See instructions in JobSystem for more information on how to implement these.22class JPH_EXPORT JobSystemWithBarrier : public JobSystem23{24public:25JPH_OVERRIDE_NEW_DELETE2627/// Constructs barriers28/// @see JobSystemWithBarrier::Init29explicit JobSystemWithBarrier(uint inMaxBarriers);30JobSystemWithBarrier() = default;31virtual ~JobSystemWithBarrier() override;3233/// Initialize the barriers34/// @param inMaxBarriers Max number of barriers that can be allocated at any time35void Init(uint inMaxBarriers);3637// See JobSystem38virtual Barrier * CreateBarrier() override;39virtual void DestroyBarrier(Barrier *inBarrier) override;40virtual void WaitForJobs(Barrier *inBarrier) override;4142private:43class BarrierImpl : public Barrier44{45public:46JPH_OVERRIDE_NEW_DELETE4748/// Constructor49BarrierImpl();50virtual ~BarrierImpl() override;5152// See Barrier53virtual void AddJob(const JobHandle &inJob) override;54virtual void AddJobs(const JobHandle *inHandles, uint inNumHandles) override;5556/// Check if there are any jobs in the job barrier57inline bool IsEmpty() const { return mJobReadIndex == mJobWriteIndex; }5859/// Wait for all jobs in this job barrier, while waiting, execute jobs that are part of this barrier on the current thread60void Wait();6162/// Flag to indicate if a barrier has been handed out63atomic<bool> mInUse { false };6465protected:66/// Called by a Job to mark that it is finished67virtual void OnJobFinished(Job *inJob) override;6869/// Jobs queue for the barrier70static constexpr uint cMaxJobs = 2048;71static_assert(IsPowerOf2(cMaxJobs)); // We do bit operations and require max jobs to be a power of 272atomic<Job *> mJobs[cMaxJobs]; ///< List of jobs that are part of this barrier, nullptrs for empty slots73alignas(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 job74alignas(JPH_CACHE_LINE_SIZE) atomic<uint> mJobWriteIndex { 0 }; ///< First job that can be written (modulo cMaxJobs)75atomic<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)76Semaphore mSemaphore; ///< Semaphore used by finishing jobs to signal the barrier that they're done77};7879/// Array of barriers (we keep them constructed all the time since constructing a semaphore/mutex is not cheap)80uint mMaxBarriers = 0; ///< Max amount of barriers81BarrierImpl * mBarriers = nullptr; ///< List of the actual barriers82};8384JPH_NAMESPACE_END858687