From 810e7291fc93e25700d3ff8b1e7df57374f4dae6 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 14 Feb 2007 16:24:49 +0000 Subject: [PATCH] Added use of Mutex into osg::Stats to better handle multi-threaded usage --- include/osg/Stats | 35 +++++++++++++++++++++++++++++++---- src/osg/Stats.cpp | 23 +++++++++++++++++------ 2 files changed, 48 insertions(+), 10 deletions(-) diff --git a/include/osg/Stats b/include/osg/Stats index 51a579e75..8075731fc 100644 --- a/include/osg/Stats +++ b/include/osg/Stats @@ -15,6 +15,8 @@ #define OSG_STATS 1 #include +#include +#include #include #include @@ -43,13 +45,28 @@ class OSG_EXPORT Stats : public osg::Referenced typedef std::vector AttributeMapList; bool setAttribute(int frameNumber, const std::string& attributeName, double value); - bool getAttribute(int frameNumber, const std::string& attributeName, double& value) const; + + inline bool getAttribute(int frameNumber, const std::string& attributeName, double& value) const + { + OpenThreads::ScopedLock lock(_mutex); + return getAttributeNoMutex(frameNumber, attributeName, value); + } bool getAveragedAttribute(const std::string& attributeName, double& value, bool averageInInverseSpace=false) const; + bool getAveragedAttribute(int startFrameNumber, int endFrameNumber, const std::string& attributeName, double& value, bool averageInInverseSpace=false) const; - AttributeMap& getAttributeMap(int frameNumber); - const AttributeMap& getAttributeMap(int frameNumber) const; + inline AttributeMap& getAttributeMap(int frameNumber) + { + OpenThreads::ScopedLock lock(_mutex); + return getAttributeMapNoMutex(frameNumber); + } + + inline const AttributeMap& getAttributeMap(int frameNumber) const + { + OpenThreads::ScopedLock lock(_mutex); + return getAttributeMapNoMutex(frameNumber); + } typedef std::map CollectMap; @@ -57,17 +74,25 @@ class OSG_EXPORT Stats : public osg::Referenced inline bool collectStats(const std::string& str) const { + OpenThreads::ScopedLock lock(_mutex); + CollectMap::const_iterator itr = _collectMap.find(str); return (itr != _collectMap.end()) ? itr->second : false; } - void report(std::ostream& out, const char* indent=0) const ; + void report(std::ostream& out, const char* indent=0) const; void report(std::ostream& out, unsigned int frameNumber, const char* indent=0) const; protected: virtual ~Stats() {} + bool getAttributeNoMutex(int frameNumber, const std::string& attributeName, double& value) const; + + Stats::AttributeMap& Stats::getAttributeMapNoMutex(int frameNumber); + const AttributeMap& getAttributeMapNoMutex(int frameNumber) const; + + int getIndex(int frameNumber) const { // reject frame that are in the future @@ -82,6 +107,8 @@ class OSG_EXPORT Stats : public osg::Referenced std::string _name; + mutable OpenThreads::Mutex _mutex; + int _baseFrameNumber; int _latestFrameNumber; diff --git a/src/osg/Stats.cpp b/src/osg/Stats.cpp index 34d465b93..355f1e045 100644 --- a/src/osg/Stats.cpp +++ b/src/osg/Stats.cpp @@ -31,6 +31,8 @@ Stats::Stats(const std::string& name, unsigned int numberOfFrames): void Stats::allocate(unsigned int numberOfFrames) { + OpenThreads::ScopedLock lock(_mutex); + _baseFrameNumber = 0; _latestFrameNumber = 0; _attributeMapList.clear(); @@ -41,6 +43,9 @@ void Stats::allocate(unsigned int numberOfFrames) bool Stats::setAttribute(int frameNumber, const std::string& attributeName, double value) { if (frameNumber lock(_mutex); + if (frameNumber>_latestFrameNumber) { // need to advance @@ -74,7 +79,7 @@ bool Stats::setAttribute(int frameNumber, const std::string& attributeName, doub return true; } -bool Stats::getAttribute(int frameNumber, const std::string& attributeName, double& value) const +bool Stats::getAttributeNoMutex(int frameNumber, const std::string& attributeName, double& value) const { int index = getIndex(frameNumber); if (index<0) return false; @@ -98,13 +103,15 @@ bool Stats::getAveragedAttribute(int startFrameNumber, int endFrameNumber, const { std::swap(endFrameNumber, startFrameNumber); } + + OpenThreads::ScopedLock lock(_mutex); double total = 0.0; double numValidSamples = 0.0; for(int i = startFrameNumber; i<=endFrameNumber; ++i) { double v = 0.0; - if (getAttribute(i,attributeName,v)) + if (getAttributeNoMutex(i,attributeName,v)) { if (averageInInverseSpace) total += 1.0/v; else total += v; @@ -120,7 +127,7 @@ bool Stats::getAveragedAttribute(int startFrameNumber, int endFrameNumber, const else return false; } -Stats::AttributeMap& Stats::getAttributeMap(int frameNumber) +Stats::AttributeMap& Stats::getAttributeMapNoMutex(int frameNumber) { int index = getIndex(frameNumber); if (index<0) return _invalidAttributeMap; @@ -128,7 +135,7 @@ Stats::AttributeMap& Stats::getAttributeMap(int frameNumber) return _attributeMapList[index]; } -const Stats::AttributeMap& Stats::getAttributeMap(int frameNumber) const +const Stats::AttributeMap& Stats::getAttributeMapNoMutex(int frameNumber) const { int index = getIndex(frameNumber); if (index<0) return _invalidAttributeMap; @@ -138,12 +145,14 @@ const Stats::AttributeMap& Stats::getAttributeMap(int frameNumber) const void Stats::report(std::ostream& out, const char* indent) const { + OpenThreads::ScopedLock lock(_mutex); + if (indent) out< lock(_mutex); + if (indent) out<