Hello all,
On 02/07/2011 06:04 PM, Gerrit Voß wrote:
if these are only headers and one can use the 1.36 version with the rest
of 1.33 (have not tried it) put it into Source/External and include it
from there on these platforms. We do this with the google hash_map
implementation and I pulled the circular buffers from a later boost
version within the complex scene manager.
hmm, that would be an option, but I wasn't set up to test this right
away (running Fedora 13 here), so I gave the OSGDeprecatedCPP.h a try,
see attached patch.
With that and the slightly modified (only added CL clearing) test
program Aron sent, I get constant memory consumption as reported by top
(left it running for 5+ minutes), so I guess it at least does not have
explosive memory consumption.
The patch is very lightly tested and I think it's possible that there
may be some code path (probably in the cluster code) that relies more
strongly on the factory store being sorted than it should ;)
Feedback/comments welcome.
Cheers,
Carsten
diff --git a/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.cpp
b/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.cpp
index f67b893..17ff8ec 100644
--- a/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.cpp
+++ b/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.cpp
@@ -78,10 +78,12 @@ for OSG::FieldContainerFactory.
FieldContainerFactoryBase::FieldContainerFactoryBase(void) :
Inherited ("FieldContainerFactory"),
_pStoreLock (NULL ),
- _vContainerStore( ),
+ _nextContainerId(0 ),
+ _containerStore ( ),
_pMapper (NULL )
{
- _vContainerStore.push_back(NULL);
+ _containerStore.insert(
+ ContainerStore::value_type(_nextContainerId++, NULL));
}
FieldContainerFactoryBase::FieldContainerFactoryBase(
@@ -89,10 +91,12 @@ FieldContainerFactoryBase::FieldContainerFactoryBase(
Inherited (szFactoryName),
_pStoreLock (NULL ),
- _vContainerStore( ),
+ _nextContainerId(0 ),
+ _containerStore ( ),
_pMapper (NULL )
{
- _vContainerStore.push_back(NULL);
+ _containerStore.insert(
+ ContainerStore::value_type(_nextContainerId++, NULL));
}
/*-------------------------------------------------------------------------*/
@@ -110,8 +114,8 @@ bool FieldContainerFactoryBase::initialize(void)
if(this->_bInitialized == true)
return true;
- _pStoreLock = ThreadManager::the()->getLock("ContainerFactory::slock",
- false);
+ _pStoreLock = ThreadManager::the()->getLock(
+ "ContainerFactory::_pStorelock", false);
PINFO << "Got store lock " << _pStoreLock.get() << std::endl;
@@ -134,32 +138,33 @@ bool FieldContainerFactoryBase::terminate(void)
this->_bInitialized = false;
#ifdef OSG_DEBUG
- ContainerStoreIt sI = _vContainerStore.begin();
- ContainerStoreIt sE = _vContainerStore.end ();
+ ContainerStoreConstIt sI = _containerStore.begin();
+ ContainerStoreConstIt sE = _containerStore.end ();
- for(UInt32 i = 0; sI != sE; ++sI, ++i)
+ for(; sI != sE; ++sI)
{
- if((*sI) != NULL)
+ if((*sI).second != NULL)
{
FWARNING(("FieldContainerFactoryBase::terminate: "
- "Entry [%d] is not NULL ([%p]). \n", i, *sI));
+ "Entry [%d] is not NULL ([%p]). \n",
+ (*sI).first, (*sI).second));
- for(UInt32 j = 0; j < (*sI)->getNumAspects(); ++j)
+ for(UInt32 j = 0; j < (*sI).second->getNumAspects(); ++j)
{
- if((*sI)->getPtr(j) != NULL)
+ if((*sI).second->getPtr(j) != NULL)
{
FWARNING((" [%d] [%p] [%s] [%d %d]\n",
j,
- (*sI)->getPtr(j),
- (*sI)->getPtr(j)->getType().getCName(),
- (*sI)->getPtr(j)->getRefCount(),
- (*sI)->getPtr(j)->getWeakRefCount() ));
+ (*sI).second->getPtr(j),
+ (*sI).second->getPtr(j)->getType().getCName(),
+ (*sI).second->getPtr(j)->getRefCount(),
+ (*sI).second->getPtr(j)->getWeakRefCount() ));
}
else
{
FWARNING((" [%d] [%p] [] [N/A N/A]\n",
j,
- (*sI)->getPtr(j)));
+ (*sI).second->getPtr(j)));
}
}
}
@@ -182,22 +187,51 @@ UInt32 FieldContainerFactoryBase::registerContainer(
VALGRIND_CHECK_VALUE_IS_DEFINED(pContainer);
#endif
- UInt32 returnValue = 0;
-
_pStoreLock->acquire();
+ UInt32 returnValue = _nextContainerId++;
+
#ifdef OSG_MT_CPTR_ASPECT
ContainerHandlerP pHandler = NULL;
if(pContainer != NULL)
pHandler = pContainer->getAspectStore();
- _vContainerStore.push_back(pHandler);
+ _containerStore.insert(
+ ContainerStore::value_type(returnValue, pHandler));
#else
- _vContainerStore.push_back(pContainer);
+ _containerStore.insert(
+ ContainerStore::value_type(returnValue, pContainer));
#endif
- returnValue = _vContainerStore.size() - 1;
+ _pStoreLock->release();
+
+ return returnValue;
+}
+
+bool FieldContainerFactoryBase::deregisterContainer(const UInt32 uiContainerId)
+{
+ bool returnValue = false;
+
+ _pStoreLock->acquire();
+
+ ContainerStoreIt sI = _containerStore.find(uiContainerId);
+
+ if(sI != _containerStore.end())
+ {
+ _containerStore.erase(sI);
+ }
+#ifdef OSG_DEBUG
+ else
+ {
+ SWARNING << "FieldContainerFactory::unregisterContainer: "
+ << "id '" << uiContainerId << "' not found in "
+ << "container store!"
+ << std::endl;
+
+ returnValue = true;
+ }
+#endif
_pStoreLock->release();
@@ -220,20 +254,19 @@ Int32
FieldContainerFactoryBase::findContainer(ContainerPtr ptr) const
{
_pStoreLock->acquire();
- ContainerStore::const_iterator it, end;
- Int32 id = 0;
- Int32 returnValue = -1;
+ ContainerStoreConstIt sI = _containerStore.begin();
+ ContainerStoreConstIt sE = _containerStore.end ();
+ Int32 returnValue = -1;
- for(it = _vContainerStore.begin(), end = _vContainerStore.end();
- it != end; ++it, ++id)
+ for(; sI != sE; ++sI)
{
#ifdef OSG_MT_CPTR_ASPECT
- if((*it)->getPtr() == ptr)
+ if((*sI).second->getPtr() == ptr)
#else
- if(*it == ptr)
+ if((*sI).second == ptr)
#endif
{
- returnValue = id;
+ returnValue = (*sI).first;
break;
}
}
@@ -250,32 +283,33 @@ void FieldContainerFactoryBase::dump(void)
{
_pStoreLock->acquire();
- ContainerStoreIt sI = _vContainerStore.begin();
- ContainerStoreIt sE = _vContainerStore.end ();
+ ContainerStoreConstIt sI = _containerStore.begin();
+ ContainerStoreConstIt sE = _containerStore.end ();
- for(UInt32 i = 0; sI != sE; ++sI, ++i)
+ for(; sI != sE; ++sI)
{
- if((*sI) != NULL)
+ if((*sI).second != NULL)
{
FWARNING(("FieldContainerFactoryBase::dump: "
- "Entry [%d] is not NULL ([%p]). \n", i, *sI));
+ "Entry [%d] is not NULL ([%p]). \n",
+ (*sI).first, (*sI).second));
- for(UInt32 j = 0; j < (*sI)->getNumAspects(); ++j)
+ for(UInt32 j = 0; j < (*sI).second->getNumAspects(); ++j)
{
- if((*sI)->getPtr(j) != NULL)
+ if((*sI).second->getPtr(j) != NULL)
{
FWARNING((" [%d] [%p] [%s] [%d %d]\n",
j,
- (*sI)->getPtr(j),
- (*sI)->getPtr(j)->getType().getCName(),
- (*sI)->getPtr(j)->getRefCount(),
- (*sI)->getPtr(j)->getWeakRefCount() ));
+ (*sI).second->getPtr(j),
+ (*sI).second->getPtr(j)->getType().getCName(),
+ (*sI).second->getPtr(j)->getRefCount(),
+ (*sI).second->getPtr(j)->getWeakRefCount() ));
}
else
{
FWARNING((" [%d] [%p] [] [N/A N/A]\n",
j,
- (*sI)->getPtr(j)));
+ (*sI).second->getPtr(j)));
}
}
}
diff --git a/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.h
b/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.h
index c222da5..d9c47c0 100644
--- a/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.h
+++ b/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.h
@@ -43,6 +43,7 @@
#endif
#include "OSGBaseTypes.h"
+#include "OSGDeprecatedCPP.h"
#include "OSGSingletonHolder.h"
#include "OSGContainerForwards.h"
#include "OSGTypeBase.h"
@@ -50,7 +51,6 @@
#include "OSGAspectStore.h"
#include "OSGContainerIdMapper.h"
-//#include "OSGFieldContainer.h"
#include <deque>
@@ -130,8 +130,9 @@ class OSG_BASE_DLLMAPPING FieldContainerFactoryBase :
typedef FieldContainer *ContainerHandlerP;
#endif
- typedef std::deque<ContainerHandlerP> ContainerStore;
- typedef ContainerStore::iterator ContainerStoreIt;
+ typedef OSG_HASH_MAP(UInt32, ContainerHandlerP) ContainerStore;
+ typedef ContainerStore::iterator ContainerStoreIt;
+ typedef ContainerStore::const_iterator ContainerStoreConstIt;
/*---------------------------------------------------------------------*/
/*! \name dcast */
@@ -246,7 +247,8 @@ class OSG_BASE_DLLMAPPING FieldContainerFactoryBase :
LockRefPtr _pStoreLock;
- ContainerStore _vContainerStore;
+ UInt32 _nextContainerId;
+ ContainerStore _containerStore;
/*! Currently active field container mapper. */
ContainerIdMapper *_pMapper;
diff --git a/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.inl
b/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.inl
index f66fb1a..c000563 100644
--- a/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.inl
+++ b/Source/Base/FieldContainer/Base/OSGFieldContainerFactory.inl
@@ -52,7 +52,7 @@ UInt32 FieldContainerFactoryBase::getNumContainers(void) const
_pStoreLock->acquire();
- returnValue = _vContainerStore.size();
+ returnValue = _nextContainerId;
_pStoreLock->release();
@@ -67,16 +67,15 @@ FieldContainerFactoryBase::ContainerPtr
_pStoreLock->acquire();
- if(uiContainerId < _vContainerStore.size())
+ ContainerStoreConstIt sI = _containerStore.find(uiContainerId);
+
+ if(sI != _containerStore.end())
{
- if(_vContainerStore[uiContainerId] != NULL)
- {
#ifdef OSG_MT_CPTR_ASPECT
- returnValue = _vContainerStore[uiContainerId]->getPtr();
+ returnValue = (*sI).second->getPtr();
#else
- returnValue = _vContainerStore[uiContainerId];
+ returnValue = (*sI).second;
#endif
- }
}
_pStoreLock->release();
@@ -92,9 +91,11 @@ FieldContainerFactoryBase::ContainerHandlerP
_pStoreLock->acquire();
- if(uiContainerId < _vContainerStore.size())
+ ContainerStoreConstIt sI = _containerStore.find(uiContainerId);
+
+ if(sI != _containerStore.end())
{
- returnValue = _vContainerStore[uiContainerId];
+ returnValue = (*sI).second;
}
_pStoreLock->release();
@@ -123,33 +124,5 @@ FieldContainerFactoryBase::ContainerPtr
}
}
-
-inline
-bool FieldContainerFactoryBase::deregisterContainer(const UInt32 uiContainerId)
-{
- bool returnValue = false;
-
- _pStoreLock->acquire();
-
- if(uiContainerId < _vContainerStore.size())
- {
- _vContainerStore[uiContainerId] = NULL;
- }
-#ifdef OSG_DEBUG
- else
- {
- FWARNING(("FieldContainerFactory::unregisterFieldContainer:"
- "id %d inconsistent with store size %"PRISize"!\n",
- uiContainerId,
- _vContainerStore.size()));
- returnValue = true;
- }
-#endif
-
- _pStoreLock->release();
-
- return returnValue;
-}
-
OSG_END_NAMESPACE
#include <iostream>
#include <string>
#include <vector>
#include "OSGConfig.h"
#include "OSGNode.h"
void run()
{
std::cout << "Starting test" << std::endl;
int num_reps = 0;
std::vector<OSG::NodeRecPtr> nodes;
for (int idx = 0; idx < 50000; ++idx)
{
OSG::NodeRecPtr node(OSG::Node::create());
nodes.push_back(node);
if (0 == idx % 500)
{
std::cout << "Adding node: " << idx << std::endl;
}
}
// Clear all nodes.
nodes.clear();
// nodes.swap(std::vector<OSG::NodeRecPtr>());
OSG::commitChangesAndClear();
}
int main(int argc, char** argv)
{
OSG::osgInit(argc, argv);
while (true)
{
run();
}
OSG::osgExit();
return 0;
}
------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Opensg-users mailing list
Opensg-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensg-users