From 1beaedacadc8093c9df612992a873f9c89354bce Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 17 Oct 2013 14:23:56 -0700 Subject: 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 --- indra/llcommon/llfasttimer.cpp | 9 +++++++-- indra/llcommon/llfasttimer.h | 2 +- indra/llcommon/llinstancetracker.h | 27 ++++++++++++++++++++++----- indra/llcommon/lltrace.h | 5 +++-- indra/llcommon/lltracethreadrecorder.cpp | 2 +- 5 files changed, 34 insertions(+), 11 deletions(-) (limited to 'indra') 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::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 { public: - typedef LLInstanceTracker, std::string> instance_tracker_t; BlockTimerStatHandle(const char* name, const char* description = ""); TimeBlockTreeNode& getTreeNode() const; @@ -99,6 +98,7 @@ public: typedef std::vector::const_iterator child_const_iter; child_iter beginChildren(); child_iter endChildren(); + bool hasChildren(); std::vector& getChildren(); StatType& 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 +template class LLInstanceTracker : public LLInstanceTrackerBase { typedef LLInstanceTracker self_t; - typedef typename std::map InstanceMap; + typedef typename std::multimap InstanceMap; struct StaticData: public StaticBase { InstanceMap sMap; @@ -208,7 +214,18 @@ private: void add_(KEY key) { mInstanceKey = key; - getMap_()[key] = static_cast(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(this))); + } } void remove_() { @@ -225,8 +242,8 @@ private: /// explicit specialization for default case where KEY is void /// use a simple std::set -template -class LLInstanceTracker : public LLInstanceTrackerBase +template +class LLInstanceTracker : public LLInstanceTrackerBase { typedef LLInstanceTracker self_t; typedef typename std::set 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 class StatType : public StatBase, - public LLInstanceTracker, std::string> + public LLInstanceTracker, std::string, InstanceTrackerAllowKeyCollisions> { public: + typedef LLInstanceTracker, std::string, InstanceTrackerAllowKeyCollisions> instance_tracker_t; StatType(const char* name, const char* description) - : LLInstanceTracker, std::string>(name), + : instance_tracker_t(name), StatBase(name, description), mAccumulatorIndex(AccumulatorBuffer::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); } -- cgit v1.2.3