Added use of Mutex into osg::Stats to better handle multi-threaded usage
This commit is contained in:
parent
02ff109746
commit
810e7291fc
@ -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;
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user