summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-10-17 14:23:56 -0700
committerRichard Linden <none@none>2013-10-17 14:23:56 -0700
commit1beaedacadc8093c9df612992a873f9c89354bce (patch)
treea056537b11fb577b7dee9ed236a2616eb0989d9d /indra
parent1c26d4265666cd232d38724ad6f1e32fd2dc2d34 (diff)
moved root timer to global variable
added flag to LLInstanceTracker to allow multiple values per key made StatType allow multiple values per key to eliminate block timer related crash
Diffstat (limited to 'indra')
-rwxr-xr-xindra/llcommon/llfasttimer.cpp9
-rwxr-xr-xindra/llcommon/llfasttimer.h2
-rwxr-xr-xindra/llcommon/llinstancetracker.h27
-rw-r--r--indra/llcommon/lltrace.h5
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp2
5 files changed, 34 insertions, 11 deletions
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 2db44adacf..d97fa74c24 100755
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -131,10 +131,10 @@ struct SortTimerByName
}
};
+static BlockTimerStatHandle sRootTimer("root", NULL);
BlockTimerStatHandle& BlockTimerStatHandle::getRootTimeBlock()
{
- static BlockTimerStatHandle root_timer("root", NULL);
- return root_timer;
+ return sRootTimer;
}
void BlockTimerStatHandle::pushLog(LLSD log)
@@ -333,6 +333,11 @@ std::vector<BlockTimerStatHandle*>& BlockTimerStatHandle::getChildren()
return getTreeNode().mChildren;
}
+bool BlockTimerStatHandle::hasChildren()
+{
+ return ! getTreeNode().mChildren.empty();
+}
+
// static
void BlockTimerStatHandle::logStats()
{
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 4821d6c386..614e7fdb4c 100755
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -88,7 +88,6 @@ class BlockTimerStatHandle
: public StatType<TimeBlockAccumulator>
{
public:
- typedef LLInstanceTracker<StatType<TimeBlockAccumulator>, std::string> instance_tracker_t;
BlockTimerStatHandle(const char* name, const char* description = "");
TimeBlockTreeNode& getTreeNode() const;
@@ -99,6 +98,7 @@ public:
typedef std::vector<BlockTimerStatHandle*>::const_iterator child_const_iter;
child_iter beginChildren();
child_iter endChildren();
+ bool hasChildren();
std::vector<BlockTimerStatHandle*>& getChildren();
StatType<TimeBlockAccumulator::CallCountFacet>& callCount()
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index f2b982c4c3..1385475444 100755
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -62,16 +62,22 @@ protected:
LL_COMMON_API void assert_main_thread();
+enum EInstanceTrackerAllowKeyCollisions
+{
+ InstanceTrackerAllowKeyCollisions,
+ InstanceTrackerDisallowKeyCollisions
+};
+
/// This mix-in class adds support for tracking all instances of the specified class parameter T
/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
/// If KEY is not provided, then instances are stored in a simple set
/// @NOTE: see explicit specialization below for default KEY==void case
/// @NOTE: this class is not thread-safe unless used as read-only
-template<typename T, typename KEY = void>
+template<typename T, typename KEY = void, EInstanceTrackerAllowKeyCollisions ALLOW_KEY_COLLISIONS = InstanceTrackerDisallowKeyCollisions>
class LLInstanceTracker : public LLInstanceTrackerBase
{
typedef LLInstanceTracker<T, KEY> self_t;
- typedef typename std::map<KEY, T*> InstanceMap;
+ typedef typename std::multimap<KEY, T*> InstanceMap;
struct StaticData: public StaticBase
{
InstanceMap sMap;
@@ -208,7 +214,18 @@ private:
void add_(KEY key)
{
mInstanceKey = key;
- getMap_()[key] = static_cast<T*>(this);
+ InstanceMap& map = getMap_();
+ InstanceMap::iterator insertion_point_it = map.lower_bound(key);
+ if (ALLOW_KEY_COLLISIONS == InstanceTrackerDisallowKeyCollisions
+ && insertion_point_it != map.end()
+ && insertion_point_it->first == key)
+ {
+ LL_ERRS() << "Key " << key << " already exists in instance map for " << typeid(T).name() << LL_ENDL;
+ }
+ else
+ {
+ map.insert(insertion_point_it, std::make_pair(key, static_cast<T*>(this)));
+ }
}
void remove_()
{
@@ -225,8 +242,8 @@ private:
/// explicit specialization for default case where KEY is void
/// use a simple std::set<T*>
-template<typename T>
-class LLInstanceTracker<T, void> : public LLInstanceTrackerBase
+template<typename T, EInstanceTrackerAllowKeyCollisions ALLOW_KEY_COLLISIONS>
+class LLInstanceTracker<T, void, ALLOW_KEY_COLLISIONS> : public LLInstanceTrackerBase
{
typedef LLInstanceTracker<T, void> self_t;
typedef typename std::set<T*> InstanceSet;
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index cbdf4e4a6f..b499036af2 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -69,11 +69,12 @@ protected:
template<typename ACCUMULATOR>
class StatType
: public StatBase,
- public LLInstanceTracker<StatType<ACCUMULATOR>, std::string>
+ public LLInstanceTracker<StatType<ACCUMULATOR>, std::string, InstanceTrackerAllowKeyCollisions>
{
public:
+ typedef LLInstanceTracker<StatType<ACCUMULATOR>, std::string, InstanceTrackerAllowKeyCollisions> instance_tracker_t;
StatType(const char* name, const char* description)
- : LLInstanceTracker<StatType<ACCUMULATOR>, std::string>(name),
+ : instance_tracker_t(name),
StatBase(name, description),
mAccumulatorIndex(AccumulatorBuffer<ACCUMULATOR>::getDefaultBuffer()->reserveSlot())
{}
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 20e8a0bbaa..7b7da5343d 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -81,7 +81,7 @@ void ThreadRecorder::init()
BlockTimerStatHandle::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1;
claim_alloc(gTraceMemStat, this);
- claim_alloc(gTraceMemStat, sizeof(BlockTimer));
+ claim_alloc(gTraceMemStat, mRootTimer);
claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
}