mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
251 lines
6.3 KiB
C++
251 lines
6.3 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkGeoSource.cxx
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
/*-------------------------------------------------------------------------
|
|
Copyright 2008 Sandia Corporation.
|
|
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
the U.S. Government retains certain rights in this software.
|
|
-------------------------------------------------------------------------*/
|
|
#include "vtkGeoSource.h"
|
|
|
|
#include "vtkCollection.h"
|
|
#include "vtkConditionVariable.h"
|
|
#include "vtkDataObject.h"
|
|
#include "vtkGeoImageNode.h"
|
|
#include "vtkGeoTerrainNode.h"
|
|
#include "vtkMultiThreader.h"
|
|
#include "vtkMutexLock.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkSmartPointer.h"
|
|
#include "vtkTimerLog.h"
|
|
|
|
#include <map>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
static VTK_THREAD_RETURN_TYPE vtkGeoSourceThreadStart(void* arg)
|
|
{
|
|
vtkGeoSource* self;
|
|
self = static_cast<vtkGeoSource *>(static_cast<vtkMultiThreader::ThreadInfo *>(arg)->UserData);
|
|
self->WorkerThread();
|
|
return VTK_THREAD_RETURN_VALUE;
|
|
}
|
|
|
|
class vtkGeoSource::implementation {
|
|
public:
|
|
std::map<std::pair<unsigned long, int>, vtkSmartPointer<vtkCollection> > OutputMap;
|
|
std::vector<int> ThreadIds;
|
|
};
|
|
|
|
vtkGeoSource::vtkGeoSource()
|
|
{
|
|
this->InputSet = vtkCollection::New();
|
|
this->InputSetLock = vtkMutexLock::New();
|
|
this->ProcessingSet = vtkCollection::New();
|
|
this->ProcessingSetLock = vtkMutexLock::New();
|
|
this->OutputSetLock = vtkMutexLock::New();
|
|
this->Lock = vtkMutexLock::New();
|
|
this->Condition = vtkConditionVariable::New();
|
|
this->StopThread = false;
|
|
this->Initialized = false;
|
|
this->Implementation = new implementation();
|
|
this->Threader = vtkMultiThreader::New();
|
|
}
|
|
|
|
vtkGeoSource::~vtkGeoSource()
|
|
{
|
|
this->ShutDown();
|
|
this->InputSet->Delete();
|
|
this->ProcessingSet->Delete();
|
|
this->Threader->Delete();
|
|
delete this->Implementation;
|
|
this->InputSetLock->Delete();
|
|
this->ProcessingSetLock->Delete();
|
|
this->OutputSetLock->Delete();
|
|
this->Condition->Delete();
|
|
this->Lock->Delete();
|
|
}
|
|
|
|
void vtkGeoSource::Initialize(int numThreads)
|
|
{
|
|
if(this->Initialized)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int maxThreads = this->Threader->GetGlobalDefaultNumberOfThreads();
|
|
maxThreads = numThreads < maxThreads ? numThreads : maxThreads;
|
|
|
|
for(int i = 0; i < maxThreads; ++i)
|
|
{
|
|
this->Implementation->ThreadIds.push_back(
|
|
this->Threader->SpawnThread(vtkGeoSourceThreadStart, this));
|
|
}
|
|
this->Initialized = true;
|
|
}
|
|
|
|
void vtkGeoSource::ShutDown()
|
|
{
|
|
if (this->Implementation->ThreadIds.size() > 0)
|
|
{
|
|
this->Lock->Lock();
|
|
this->StopThread = true;
|
|
this->Condition->Broadcast();
|
|
this->Lock->Unlock();
|
|
|
|
std::vector<int>::iterator iter;
|
|
for(iter = this->Implementation->ThreadIds.begin();
|
|
iter != this->Implementation->ThreadIds.end();
|
|
++iter)
|
|
{
|
|
this->Threader->TerminateThread(*iter);
|
|
}
|
|
this->Implementation->ThreadIds.clear();
|
|
this->Implementation->OutputMap.clear();
|
|
}
|
|
this->Initialized = false;
|
|
}
|
|
|
|
vtkCollection* vtkGeoSource::GetRequestedNodes(vtkGeoTreeNode* node)
|
|
{
|
|
vtkCollection* c = 0;
|
|
this->OutputSetLock->Lock();
|
|
std::pair<unsigned long, int> p(node->GetId(), node->GetLevel());
|
|
if (this->Implementation->OutputMap.count(p) > 0)
|
|
{
|
|
c = this->Implementation->OutputMap[p];
|
|
if (c)
|
|
{
|
|
c->Register(0);
|
|
this->Implementation->OutputMap[p] = 0;
|
|
}
|
|
}
|
|
this->OutputSetLock->Unlock();
|
|
|
|
return c;
|
|
}
|
|
|
|
void vtkGeoSource::RequestChildren(vtkGeoTreeNode* node)
|
|
{
|
|
if(!this->Initialized)
|
|
{
|
|
vtkErrorMacro("Call Initialize() first in order to spawn worker threads.");
|
|
return;
|
|
}
|
|
|
|
this->InputSetLock->Lock();
|
|
this->InputSet->AddItem(node);
|
|
// Reference Count is 2 at this point. Decrease so that
|
|
// we can delete this copy of the node from the worker
|
|
// thread.
|
|
node->UnRegister(this);
|
|
this->Condition->Broadcast();
|
|
this->InputSetLock->Unlock();
|
|
}
|
|
|
|
void vtkGeoSource::WorkerThread()
|
|
{
|
|
bool isTerrainNode = false;
|
|
while (true)
|
|
{
|
|
this->Lock->Lock();
|
|
|
|
if (this->StopThread)
|
|
{
|
|
|
|
this->Lock->Unlock();
|
|
return;
|
|
}
|
|
|
|
this->Lock->Unlock();
|
|
|
|
this->InputSetLock->Lock();
|
|
|
|
// Try to find something to work on.
|
|
if (this->InputSet->GetNumberOfItems() > 0)
|
|
{
|
|
// Move from input set to processing set
|
|
vtkGeoTreeNode* node = vtkGeoTreeNode::SafeDownCast(this->InputSet->GetItemAsObject(0));
|
|
node->Register(this);
|
|
this->InputSet->RemoveItem(0);
|
|
this->InputSetLock->Unlock();
|
|
|
|
// Create appropriate child instances
|
|
vtkGeoTreeNode* child[4];
|
|
isTerrainNode = vtkGeoTerrainNode::SafeDownCast(node) != NULL ? true : false;
|
|
if (isTerrainNode)
|
|
{
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
child[i] = vtkGeoTerrainNode::New();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
child[i] = vtkGeoImageNode::New();
|
|
}
|
|
}
|
|
|
|
// Fetch the children
|
|
bool success = true;
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
if (!this->FetchChild(node, i, child[i]))
|
|
{
|
|
success = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Move from processing set to output
|
|
this->OutputSetLock->Lock();
|
|
std::pair<unsigned long, int> p(node->GetId(), node->GetLevel());
|
|
this->Implementation->OutputMap[p] =
|
|
vtkSmartPointer<vtkCollection>::New();
|
|
if (success)
|
|
{
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
this->Implementation->OutputMap[p]->AddItem(child[i]);
|
|
}
|
|
}
|
|
this->OutputSetLock->Unlock();
|
|
|
|
|
|
node->Delete();
|
|
node = NULL;
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
child[i]->Delete();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
this->InputSetLock->Unlock();
|
|
|
|
this->Lock->Lock();
|
|
|
|
// No Work, so lets wait till we're signaled again.
|
|
this->Condition->Wait( this->Lock );
|
|
|
|
this->Lock->Unlock();
|
|
}
|
|
}
|
|
}
|
|
|