Added use of Mutex into osg::Stats to better handle multi-threaded usage

This commit is contained in:
Robert Osfield 2007-02-14 16:24:49 +00:00
parent 02ff109746
commit 810e7291fc
2 changed files with 48 additions and 10 deletions

View File

@ -15,6 +15,8 @@
#define OSG_STATS 1 #define OSG_STATS 1
#include <osg/Referenced> #include <osg/Referenced>
#include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock>
#include <string> #include <string>
#include <map> #include <map>
@ -43,13 +45,28 @@ class OSG_EXPORT Stats : public osg::Referenced
typedef std::vector<AttributeMap> AttributeMapList; typedef std::vector<AttributeMap> AttributeMapList;
bool setAttribute(int frameNumber, const std::string& attributeName, double value); 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<OpenThreads::Mutex> lock(_mutex);
return getAttributeNoMutex(frameNumber, attributeName, value);
}
bool getAveragedAttribute(const std::string& attributeName, double& value, bool averageInInverseSpace=false) const; 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; bool getAveragedAttribute(int startFrameNumber, int endFrameNumber, const std::string& attributeName, double& value, bool averageInInverseSpace=false) const;
AttributeMap& getAttributeMap(int frameNumber); inline AttributeMap& getAttributeMap(int frameNumber)
const AttributeMap& getAttributeMap(int frameNumber) const; {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
return getAttributeMapNoMutex(frameNumber);
}
inline const AttributeMap& getAttributeMap(int frameNumber) const
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
return getAttributeMapNoMutex(frameNumber);
}
typedef std::map<std::string, bool> CollectMap; typedef std::map<std::string, bool> CollectMap;
@ -57,17 +74,25 @@ class OSG_EXPORT Stats : public osg::Referenced
inline bool collectStats(const std::string& str) const inline bool collectStats(const std::string& str) const
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
CollectMap::const_iterator itr = _collectMap.find(str); CollectMap::const_iterator itr = _collectMap.find(str);
return (itr != _collectMap.end()) ? itr->second : false; 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; void report(std::ostream& out, unsigned int frameNumber, const char* indent=0) const;
protected: protected:
virtual ~Stats() {} 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 int getIndex(int frameNumber) const
{ {
// reject frame that are in the future // reject frame that are in the future
@ -82,6 +107,8 @@ class OSG_EXPORT Stats : public osg::Referenced
std::string _name; std::string _name;
mutable OpenThreads::Mutex _mutex;
int _baseFrameNumber; int _baseFrameNumber;
int _latestFrameNumber; int _latestFrameNumber;

View File

@ -31,6 +31,8 @@ Stats::Stats(const std::string& name, unsigned int numberOfFrames):
void Stats::allocate(unsigned int numberOfFrames) void Stats::allocate(unsigned int numberOfFrames)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
_baseFrameNumber = 0; _baseFrameNumber = 0;
_latestFrameNumber = 0; _latestFrameNumber = 0;
_attributeMapList.clear(); _attributeMapList.clear();
@ -41,6 +43,9 @@ void Stats::allocate(unsigned int numberOfFrames)
bool Stats::setAttribute(int frameNumber, const std::string& attributeName, double value) bool Stats::setAttribute(int frameNumber, const std::string& attributeName, double value)
{ {
if (frameNumber<getEarliestFrameNumber()) return false; if (frameNumber<getEarliestFrameNumber()) return false;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (frameNumber>_latestFrameNumber) if (frameNumber>_latestFrameNumber)
{ {
// need to advance // need to advance
@ -74,7 +79,7 @@ bool Stats::setAttribute(int frameNumber, const std::string& attributeName, doub
return true; 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); int index = getIndex(frameNumber);
if (index<0) return false; if (index<0) return false;
@ -98,13 +103,15 @@ bool Stats::getAveragedAttribute(int startFrameNumber, int endFrameNumber, const
{ {
std::swap(endFrameNumber, startFrameNumber); std::swap(endFrameNumber, startFrameNumber);
} }
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
double total = 0.0; double total = 0.0;
double numValidSamples = 0.0; double numValidSamples = 0.0;
for(int i = startFrameNumber; i<=endFrameNumber; ++i) for(int i = startFrameNumber; i<=endFrameNumber; ++i)
{ {
double v = 0.0; double v = 0.0;
if (getAttribute(i,attributeName,v)) if (getAttributeNoMutex(i,attributeName,v))
{ {
if (averageInInverseSpace) total += 1.0/v; if (averageInInverseSpace) total += 1.0/v;
else total += v; else total += v;
@ -120,7 +127,7 @@ bool Stats::getAveragedAttribute(int startFrameNumber, int endFrameNumber, const
else return false; else return false;
} }
Stats::AttributeMap& Stats::getAttributeMap(int frameNumber) Stats::AttributeMap& Stats::getAttributeMapNoMutex(int frameNumber)
{ {
int index = getIndex(frameNumber); int index = getIndex(frameNumber);
if (index<0) return _invalidAttributeMap; if (index<0) return _invalidAttributeMap;
@ -128,7 +135,7 @@ Stats::AttributeMap& Stats::getAttributeMap(int frameNumber)
return _attributeMapList[index]; return _attributeMapList[index];
} }
const Stats::AttributeMap& Stats::getAttributeMap(int frameNumber) const const Stats::AttributeMap& Stats::getAttributeMapNoMutex(int frameNumber) const
{ {
int index = getIndex(frameNumber); int index = getIndex(frameNumber);
if (index<0) return _invalidAttributeMap; 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 void Stats::report(std::ostream& out, const char* indent) const
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (indent) out<<indent; if (indent) out<<indent;
out<<"Stats "<<_name<<std::endl; out<<"Stats "<<_name<<std::endl;
for(int i = getEarliestFrameNumber(); i<= getLatestFrameNumber(); ++i) for(int i = getEarliestFrameNumber(); i<= getLatestFrameNumber(); ++i)
{ {
out<<" FrameNumber "<<i<<std::endl; out<<" FrameNumber "<<i<<std::endl;
const osg::Stats::AttributeMap& attributes = getAttributeMap(i); const osg::Stats::AttributeMap& attributes = getAttributeMapNoMutex(i);
for(osg::Stats::AttributeMap::const_iterator itr = attributes.begin(); for(osg::Stats::AttributeMap::const_iterator itr = attributes.begin();
itr != attributes.end(); itr != attributes.end();
++itr) ++itr)
@ -157,9 +166,11 @@ void Stats::report(std::ostream& out, const char* indent) const
void Stats::report(std::ostream& out, unsigned int frameNumber, const char* indent) const void Stats::report(std::ostream& out, unsigned int frameNumber, const char* indent) const
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (indent) out<<indent; if (indent) out<<indent;
out<<"Stats "<<_name<<" FrameNumber "<<frameNumber<<std::endl; out<<"Stats "<<_name<<" FrameNumber "<<frameNumber<<std::endl;
const osg::Stats::AttributeMap& attributes = getAttributeMap(frameNumber); const osg::Stats::AttributeMap& attributes = getAttributeMapNoMutex(frameNumber);
for(osg::Stats::AttributeMap::const_iterator itr = attributes.begin(); for(osg::Stats::AttributeMap::const_iterator itr = attributes.begin();
itr != attributes.end(); itr != attributes.end();
++itr) ++itr)