|
|
|
@ -2,69 +2,55 @@
|
|
|
|
|
|
|
|
|
|
#include <components/debug/debuglog.hpp>
|
|
|
|
|
|
|
|
|
|
#include <numeric>
|
|
|
|
|
|
|
|
|
|
namespace SceneUtil
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
void WorkItem::waitTillDone()
|
|
|
|
|
{
|
|
|
|
|
if (mDone > 0)
|
|
|
|
|
if (mDone)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
|
|
|
|
while (mDone == 0)
|
|
|
|
|
std::unique_lock<std::mutex> lock(mMutex);
|
|
|
|
|
while (!mDone)
|
|
|
|
|
{
|
|
|
|
|
mCondition.wait(&mMutex);
|
|
|
|
|
mCondition.wait(lock);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorkItem::signalDone()
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
|
|
|
|
mDone.exchange(1);
|
|
|
|
|
std::unique_lock<std::mutex> lock(mMutex);
|
|
|
|
|
mDone = true;
|
|
|
|
|
}
|
|
|
|
|
mCondition.broadcast();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WorkItem::WorkItem()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WorkItem::~WorkItem()
|
|
|
|
|
{
|
|
|
|
|
mCondition.notify_all();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool WorkItem::isDone() const
|
|
|
|
|
{
|
|
|
|
|
return (mDone > 0);
|
|
|
|
|
return mDone;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WorkQueue::WorkQueue(int workerThreads)
|
|
|
|
|
: mIsReleased(false)
|
|
|
|
|
{
|
|
|
|
|
for (int i=0; i<workerThreads; ++i)
|
|
|
|
|
{
|
|
|
|
|
WorkThread* thread = new WorkThread(this);
|
|
|
|
|
mThreads.push_back(thread);
|
|
|
|
|
thread->startThread();
|
|
|
|
|
}
|
|
|
|
|
mThreads.emplace_back(std::make_unique<WorkThread>(*this));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WorkQueue::~WorkQueue()
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
|
|
|
|
std::unique_lock<std::mutex> lock(mMutex);
|
|
|
|
|
while (!mQueue.empty())
|
|
|
|
|
mQueue.pop_back();
|
|
|
|
|
mIsReleased = true;
|
|
|
|
|
mCondition.broadcast();
|
|
|
|
|
mCondition.notify_all();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (unsigned int i=0; i<mThreads.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
mThreads[i]->join();
|
|
|
|
|
delete mThreads[i];
|
|
|
|
|
}
|
|
|
|
|
mThreads.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorkQueue::addWorkItem(osg::ref_ptr<WorkItem> item, bool front)
|
|
|
|
@ -75,20 +61,20 @@ void WorkQueue::addWorkItem(osg::ref_ptr<WorkItem> item, bool front)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
|
|
|
|
std::unique_lock<std::mutex> lock(mMutex);
|
|
|
|
|
if (front)
|
|
|
|
|
mQueue.push_front(item);
|
|
|
|
|
else
|
|
|
|
|
mQueue.push_back(item);
|
|
|
|
|
mCondition.signal();
|
|
|
|
|
mCondition.notify_one();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<WorkItem> WorkQueue::removeWorkItem()
|
|
|
|
|
{
|
|
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
|
|
|
|
std::unique_lock<std::mutex> lock(mMutex);
|
|
|
|
|
while (mQueue.empty() && !mIsReleased)
|
|
|
|
|
{
|
|
|
|
|
mCondition.wait(&mMutex);
|
|
|
|
|
mCondition.wait(lock);
|
|
|
|
|
}
|
|
|
|
|
if (!mQueue.empty())
|
|
|
|
|
{
|
|
|
|
@ -102,25 +88,26 @@ osg::ref_ptr<WorkItem> WorkQueue::removeWorkItem()
|
|
|
|
|
|
|
|
|
|
unsigned int WorkQueue::getNumItems() const
|
|
|
|
|
{
|
|
|
|
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
|
|
|
|
std::unique_lock<std::mutex> lock(mMutex);
|
|
|
|
|
return mQueue.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int WorkQueue::getNumActiveThreads() const
|
|
|
|
|
{
|
|
|
|
|
unsigned int count = 0;
|
|
|
|
|
for (unsigned int i=0; i<mThreads.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (mThreads[i]->isActive())
|
|
|
|
|
++count;
|
|
|
|
|
}
|
|
|
|
|
return count;
|
|
|
|
|
return std::accumulate(mThreads.begin(), mThreads.end(), 0u,
|
|
|
|
|
[] (auto r, const auto& t) { return r + t->isActive(); });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WorkThread::WorkThread(WorkQueue *workQueue)
|
|
|
|
|
: mWorkQueue(workQueue)
|
|
|
|
|
WorkThread::WorkThread(WorkQueue& workQueue)
|
|
|
|
|
: mWorkQueue(&workQueue)
|
|
|
|
|
, mActive(false)
|
|
|
|
|
, mThread([this] { run(); })
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WorkThread::~WorkThread()
|
|
|
|
|
{
|
|
|
|
|
mThread.join();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void WorkThread::run()
|
|
|
|
|