From 5581909a4d19db97304449f66404ff99a0429d3f Mon Sep 17 00:00:00 2001 From: mtamis Date: Tue, 28 Feb 2017 18:24:59 +0100 Subject: Add visual samples. --- NvCloth/samples/SampleBase/utils/JobManager.cpp | 136 ++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 NvCloth/samples/SampleBase/utils/JobManager.cpp (limited to 'NvCloth/samples/SampleBase/utils/JobManager.cpp') diff --git a/NvCloth/samples/SampleBase/utils/JobManager.cpp b/NvCloth/samples/SampleBase/utils/JobManager.cpp new file mode 100644 index 0000000..093db60 --- /dev/null +++ b/NvCloth/samples/SampleBase/utils/JobManager.cpp @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2008-2017, NVIDIA CORPORATION. All rights reserved. +* +* NVIDIA CORPORATION and its licensors retain all intellectual property +* and proprietary rights in and to this software, related documentation +* and any modifications thereto. Any use, reproduction, disclosure or +* distribution of this software and related documentation without an express +* license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "JobManager.h" +#define _USE_MATH_DEFINES +#include +#include + +void Job::Initialize(JobManager* parent, std::function function, int refcount) +{ + mFunction = function; + mParent = parent; + Reset(refcount); +} + +Job::Job(const Job& job) +{ + mFunction = job.mFunction; + mParent = job.mParent; + mRefCount.store(job.mRefCount); + mFinished = job.mFinished; +} + +void Job::Reset(int refcount) +{ + mRefCount = refcount; + mFinished = false; +} + +void Job::Execute() +{ + if (mFunction) + mFunction(this); + else + ExecuteInternal(); + + mFinishedLock.lock(); + mFinished = true; + mFinishedLock.unlock(); + mFinishedEvent.notify_one(); +} + +void Job::AddReference() +{ + mRefCount++; +} +void Job::RemoveReference() +{ + if (0 == --mRefCount) + { + mParent->Submit(this); + } +} + +void Job::Wait() +{ + std::unique_lock lock(mFinishedLock); + mFinishedEvent.wait(lock, [this](){return mFinished;} ); + return; +} + +void JobManager::WorkerEntryPoint(JobManager* parrent) +{ + while (true) + { + Job* job; + { + std::unique_lock lock(parrent->mJobQueueLock); + while (parrent->mJobQueue.size() == 0 && !parrent->mQuit) + parrent->mJobQueueEvent.wait(lock); + + if (parrent->mQuit) + return; + + job = parrent->mJobQueue.front(); + parrent->mJobQueue.pop(); + } + job->Execute(); + } +} + +void JobManager::Submit(Job* job) +{ + mJobQueueLock.lock(); + mJobQueue.push(job); + mJobQueueLock.unlock(); + mJobQueueEvent.notify_one(); +} + +void MultithreadedSolverHelper::Initialize(nv::cloth::Solver* solver, JobManager* jobManager) +{ + mSolver = solver; + mJobManager = jobManager; + mEndSimulationJob.Initialize(mJobManager, [this](Job*) { + mSolver->endSimulation(); + }); + + mStartSimulationJob.Initialize(mJobManager, [this](Job*) { + mSolver->beginSimulation(mDt); + for(int j = 0; j < mSolver->getSimulationChunkCount(); j++) + mSimulationChunkJobs[j].RemoveReference(); + }); +} + +void MultithreadedSolverHelper::StartSimulation(float dt) +{ + mDt = dt; + + if (mSolver->getSimulationChunkCount() != mSimulationChunkJobs.size()) + { + mSimulationChunkJobs.resize(mSolver->getSimulationChunkCount(), Job()); + for (int j = 0; j < mSolver->getSimulationChunkCount(); j++) + mSimulationChunkJobs[j].Initialize(mJobManager, [this, j](Job*) {mSolver->simulateChunk(j); mEndSimulationJob.RemoveReference(); }); + } + else + { + for (int j = 0; j < mSolver->getSimulationChunkCount(); j++) + mSimulationChunkJobs[j].Reset(); + } + mStartSimulationJob.Reset(); + mEndSimulationJob.Reset(mSolver->getSimulationChunkCount()); + mStartSimulationJob.RemoveReference(); + +} + +void MultithreadedSolverHelper::WaitForSimulation() +{ + mEndSimulationJob.Wait(); +} \ No newline at end of file -- cgit v1.2.3