summaryrefslogtreecommitdiff
path: root/indra/llcommon/llfasttimer.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/llfasttimer.h')
-rwxr-xr-xindra/llcommon/llfasttimer.h67
1 files changed, 39 insertions, 28 deletions
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 1266d87f08..4821d6c386 100755
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -29,37 +29,36 @@
#include "llinstancetracker.h"
#include "lltrace.h"
+#include "lltreeiterators.h"
-#define FAST_TIMER_ON 1
+#define LL_FAST_TIMER_ON 1
#define LL_FASTTIMER_USE_RDTSC 1
-class LLMutex;
-
#define LL_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__);
namespace LLTrace
{
-
-class BlockTimer timeThisBlock(class TimeBlock& timer);
+// use to create blocktimer rvalue to be captured in a reference so that the BlockTimer lives to the end of the block.
+class BlockTimer timeThisBlock(class BlockTimerStatHandle& timer);
class BlockTimer
{
public:
typedef BlockTimer self_t;
- typedef class TimeBlock DeclareTimer;
+ typedef class BlockTimerStatHandle DeclareTimer;
~BlockTimer();
F64Seconds getElapsedTime();
private:
- friend class TimeBlock;
+ friend class BlockTimerStatHandle;
// FIXME: this friendship exists so that each thread can instantiate a root timer,
// which could be a derived class with a public constructor instead, possibly
friend class ThreadRecorder;
- friend BlockTimer timeThisBlock(TimeBlock&);
+ friend BlockTimer timeThisBlock(BlockTimerStatHandle&);
- BlockTimer(TimeBlock& timer);
+ BlockTimer(BlockTimerStatHandle& timer);
#if !defined(MSC_VER) || MSC_VER < 1700
// Visual Studio 2010 has a bug where capturing an object returned by value
// into a local reference requires access to the copy constructor at the call site.
@@ -79,28 +78,28 @@ private:
// (This is most easily done using the macro LL_RECORD_BLOCK_TIME)
// Otherwise, it would be possible to store a BlockTimer on the heap, resulting in non-nested lifetimes,
// which would break the invariants of the timing hierarchy logic
-LL_FORCE_INLINE class BlockTimer timeThisBlock(class TimeBlock& timer)
+LL_FORCE_INLINE class BlockTimer timeThisBlock(class BlockTimerStatHandle& timer)
{
return BlockTimer(timer);
}
// stores a "named" timer instance to be reused via multiple BlockTimer stack instances
-class TimeBlock
-: public StatType<TimeBlockAccumulator>,
- public LLInstanceTracker<TimeBlock>
+class BlockTimerStatHandle
+: public StatType<TimeBlockAccumulator>
{
public:
- TimeBlock(const char* name, TimeBlock* parent = &getRootTimeBlock());
+ typedef LLInstanceTracker<StatType<TimeBlockAccumulator>, std::string> instance_tracker_t;
+ BlockTimerStatHandle(const char* name, const char* description = "");
TimeBlockTreeNode& getTreeNode() const;
- TimeBlock* getParent() const { return getTreeNode().getParent(); }
- void setParent(TimeBlock* parent) { getTreeNode().setParent(parent); }
+ BlockTimerStatHandle* getParent() const { return getTreeNode().getParent(); }
+ void setParent(BlockTimerStatHandle* parent) { getTreeNode().setParent(parent); }
- typedef std::vector<TimeBlock*>::iterator child_iter;
- typedef std::vector<TimeBlock*>::const_iterator child_const_iter;
+ typedef std::vector<BlockTimerStatHandle*>::iterator child_iter;
+ typedef std::vector<BlockTimerStatHandle*>::const_iterator child_const_iter;
child_iter beginChildren();
child_iter endChildren();
- std::vector<TimeBlock*>& getChildren();
+ std::vector<BlockTimerStatHandle*>& getChildren();
StatType<TimeBlockAccumulator::CallCountFacet>& callCount()
{
@@ -112,9 +111,9 @@ public:
return static_cast<StatType<TimeBlockAccumulator::SelfTimeFacet>&>(*(StatType<TimeBlockAccumulator>*)this);
}
- static TimeBlock& getRootTimeBlock();
+ static BlockTimerStatHandle& getRootTimeBlock();
static void pushLog(LLSD sd);
- static void setLogLock(LLMutex* mutex);
+ static void setLogLock(class LLMutex* mutex);
static void writeLog(std::ostream& os);
static void updateTimes();
@@ -144,14 +143,14 @@ public:
//#undef _interlockedbittestandset
//#undef _interlockedbittestandreset
- //inline U32 TimeBlock::getCPUClockCount32()
+ //inline U32 BlockTimerStatHandle::getCPUClockCount32()
//{
// U64 time_stamp = __rdtsc();
// return (U32)(time_stamp >> 8);
//}
//
//// return full timer value, *not* shifted by 8 bits
- //inline U64 TimeBlock::getCPUClockCount64()
+ //inline U64 BlockTimerStatHandle::getCPUClockCount64()
//{
// return __rdtsc();
//}
@@ -279,9 +278,21 @@ public:
static U64 sClockResolution;
};
-LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer)
+// iterators and helper functions for walking the call hierarchy of block timers in different ways
+typedef LLTreeDFSIter<BlockTimerStatHandle, BlockTimerStatHandle::child_const_iter> block_timer_tree_df_iterator_t;
+typedef LLTreeDFSPostIter<BlockTimerStatHandle, BlockTimerStatHandle::child_const_iter> block_timer_tree_df_post_iterator_t;
+typedef LLTreeBFSIter<BlockTimerStatHandle, BlockTimerStatHandle::child_const_iter> block_timer_tree_bf_iterator_t;
+
+block_timer_tree_df_iterator_t begin_block_timer_tree_df(BlockTimerStatHandle& id);
+block_timer_tree_df_iterator_t end_block_timer_tree_df();
+block_timer_tree_df_post_iterator_t begin_block_timer_tree_df_post(BlockTimerStatHandle& id);
+block_timer_tree_df_post_iterator_t end_block_timer_tree_df_post();
+block_timer_tree_bf_iterator_t begin_block_timer_tree_bf(BlockTimerStatHandle& id);
+block_timer_tree_bf_iterator_t end_block_timer_tree_bf();
+
+LL_FORCE_INLINE BlockTimer::BlockTimer(BlockTimerStatHandle& timer)
{
-#if FAST_TIMER_ON
+#if LL_FAST_TIMER_ON
BlockTimerStackRecord* cur_timer_data = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance();
if (!cur_timer_data) return;
TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator();
@@ -296,14 +307,14 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer)
cur_timer_data->mTimeBlock = &timer;
cur_timer_data->mChildTime = 0;
- mStartTime = TimeBlock::getCPUClockCount64();
+ mStartTime = BlockTimerStatHandle::getCPUClockCount64();
#endif
}
LL_FORCE_INLINE BlockTimer::~BlockTimer()
{
-#if FAST_TIMER_ON
- U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime;
+#if LL_FAST_TIMER_ON
+ U64 total_time = BlockTimerStatHandle::getCPUClockCount64() - mStartTime;
BlockTimerStackRecord* cur_timer_data = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance();
if (!cur_timer_data) return;