diff options
author | Richard Linden <none@none> | 2013-10-24 14:39:19 -0700 |
---|---|---|
committer | Richard Linden <none@none> | 2013-10-24 14:39:19 -0700 |
commit | d13f26a6fcde03f5464e986b204b2fbb5848d861 (patch) | |
tree | abebd18faa3bd63c75cf35bf0e6742e1f13d36f2 /indra/llcommon | |
parent | dc60a7564abf16cbf269e47cfc33ed00c6bb0870 (diff) | |
parent | ab43be5ddb50198304de1ae0e82b641c7d343449 (diff) |
Merge
Diffstat (limited to 'indra/llcommon')
-rwxr-xr-x | indra/llcommon/llfasttimer.cpp | 48 | ||||
-rwxr-xr-x | indra/llcommon/llfasttimer.h | 162 | ||||
-rwxr-xr-x | indra/llcommon/llmetricperformancetester.cpp | 4 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.cpp | 8 | ||||
-rw-r--r-- | indra/llcommon/lltracethreadrecorder.cpp | 8 |
5 files changed, 116 insertions, 114 deletions
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 4744be7236..9b093e8936 100755 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -60,14 +60,14 @@ namespace LLTrace ////////////////////////////////////////////////////////////////////////////// // statics -bool BlockTimerStatHandle::sLog = false; -std::string BlockTimerStatHandle::sLogName = ""; -bool BlockTimerStatHandle::sMetricLog = false; +bool BlockTimer::sLog = false; +std::string BlockTimer::sLogName = ""; +bool BlockTimer::sMetricLog = false; #if LL_LINUX || LL_SOLARIS -U64 BlockTimerStatHandle::sClockResolution = 1000000000; // Nanosecond resolution +U64 BlockTimer::sClockResolution = 1000000000; // Nanosecond resolution #else -U64 BlockTimerStatHandle::sClockResolution = 1000000; // Microsecond resolution +U64 BlockTimer::sClockResolution = 1000000; // Microsecond resolution #endif static LLMutex* sLogLock = NULL; @@ -132,19 +132,19 @@ struct SortTimerByName }; static BlockTimerStatHandle sRootTimer("root", NULL); -BlockTimerStatHandle& BlockTimerStatHandle::getRootTimeBlock() +BlockTimerStatHandle& BlockTimer::getRootTimeBlock() { return sRootTimer; } -void BlockTimerStatHandle::pushLog(LLSD log) +void BlockTimer::pushLog(LLSD log) { LLMutexLock lock(sLogLock); sLogQueue.push(log); } -void BlockTimerStatHandle::setLogLock(LLMutex* lock) +void BlockTimer::setLogLock(LLMutex* lock) { sLogLock = lock; } @@ -152,12 +152,12 @@ void BlockTimerStatHandle::setLogLock(LLMutex* lock) //static #if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) -U64 BlockTimerStatHandle::countsPerSecond() +U64 BlockTimer::countsPerSecond() { return sClockResolution; } #else // windows or x86-mac or x86-linux or x86-solaris -U64 BlockTimerStatHandle::countsPerSecond() +U64 BlockTimer::countsPerSecond() { #if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS //getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz @@ -191,18 +191,18 @@ TimeBlockTreeNode& BlockTimerStatHandle::getTreeNode() const } -void BlockTimerStatHandle::bootstrapTimerTree() +void BlockTimer::bootstrapTimerTree() { for (BlockTimerStatHandle::instance_tracker_t::instance_iter it = BlockTimerStatHandle::instance_tracker_t::beginInstances(), end_it = BlockTimerStatHandle::instance_tracker_t::endInstances(); it != end_it; ++it) { BlockTimerStatHandle& timer = static_cast<BlockTimerStatHandle&>(*it); - if (&timer == &BlockTimerStatHandle::getRootTimeBlock()) continue; + if (&timer == &BlockTimer::getRootTimeBlock()) continue; // bootstrap tree construction by attaching to last timer to be on stack // when this timer was called - if (timer.getParent() == &BlockTimerStatHandle::getRootTimeBlock()) + if (timer.getParent() == &BlockTimer::getRootTimeBlock()) { TimeBlockAccumulator& accumulator = timer.getCurrentAccumulator(); @@ -220,9 +220,9 @@ void BlockTimerStatHandle::bootstrapTimerTree() // bump timers up tree if they have been flagged as being in the wrong place // do this in a bottom up order to promote descendants first before promoting ancestors // this preserves partial order derived from current frame's observations -void BlockTimerStatHandle::incrementalUpdateTimerTree() +void BlockTimer::incrementalUpdateTimerTree() { - for(block_timer_tree_df_post_iterator_t it = begin_block_timer_tree_df_post(BlockTimerStatHandle::getRootTimeBlock()); + for(block_timer_tree_df_post_iterator_t it = begin_block_timer_tree_df_post(BlockTimer::getRootTimeBlock()); it != end_block_timer_tree_df_post(); ++it) { @@ -236,7 +236,7 @@ void BlockTimerStatHandle::incrementalUpdateTimerTree() } // skip root timer - if (timerp != &BlockTimerStatHandle::getRootTimeBlock()) + if (timerp != &BlockTimer::getRootTimeBlock()) { TimeBlockAccumulator& accumulator = timerp->getCurrentAccumulator(); @@ -260,7 +260,7 @@ void BlockTimerStatHandle::incrementalUpdateTimerTree() } -void BlockTimerStatHandle::updateTimes() +void BlockTimer::updateTimes() { // walk up stack of active timers and accumulate current time while leaving timing structures active BlockTimerStackRecord* stack_record = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance(); @@ -292,7 +292,7 @@ static LLTrace::BlockTimerStatHandle FTM_PROCESS_TIMES("Process FastTimer Times" // not thread safe, so only call on main thread //static -void BlockTimerStatHandle::processTimes() +void BlockTimer::processTimes() { LL_RECORD_BLOCK_TIME(FTM_PROCESS_TIMES); get_clock_count(); // good place to calculate clock frequency @@ -339,7 +339,7 @@ bool BlockTimerStatHandle::hasChildren() } // static -void BlockTimerStatHandle::logStats() +void BlockTimer::logStats() { // get ready for next frame if (sLog) @@ -388,13 +388,13 @@ void BlockTimerStatHandle::logStats() } //static -void BlockTimerStatHandle::dumpCurTimes() +void BlockTimer::dumpCurTimes() { LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); // walk over timers in depth order and output timings - for(block_timer_tree_df_iterator_t it = begin_timer_tree(BlockTimerStatHandle::getRootTimeBlock()); + for(block_timer_tree_df_iterator_t it = begin_timer_tree(BlockTimer::getRootTimeBlock()); it != end_timer_tree(); ++it) { @@ -422,7 +422,7 @@ void BlockTimerStatHandle::dumpCurTimes() } //static -void BlockTimerStatHandle::writeLog(std::ostream& os) +void BlockTimer::writeLog(std::ostream& os) { while (!sLogQueue.empty()) { @@ -478,9 +478,9 @@ void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other ) F64Seconds BlockTimer::getElapsedTime() { - U64 total_time = BlockTimerStatHandle::getCPUClockCount64() - mStartTime; + U64 total_time = getCPUClockCount64() - mStartTime; - return F64Seconds((F64)total_time / (F64)BlockTimerStatHandle::countsPerSecond()); + return F64Seconds((F64)total_time / (F64)BlockTimer::countsPerSecond()); } diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 614e7fdb4c..2370253078 100755 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -51,77 +51,7 @@ public: F64Seconds getElapsedTime(); -private: - 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(BlockTimerStatHandle&); - - 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. - // This appears to be fixed in 2012. -public: -#endif - // no-copy - BlockTimer(const BlockTimer& other) {}; - -private: - U64 mStartTime; - BlockTimerStackRecord mParentTimerData; -}; - -// this dummy function assists in allocating a block timer with stack-based lifetime. -// this is done by capturing the return value in a stack-allocated const reference variable. -// (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 BlockTimerStatHandle& timer) -{ - return BlockTimer(timer); -} - -// stores a "named" timer instance to be reused via multiple BlockTimer stack instances -class BlockTimerStatHandle -: public StatType<TimeBlockAccumulator> -{ -public: - BlockTimerStatHandle(const char* name, const char* description = ""); - - TimeBlockTreeNode& getTreeNode() const; - BlockTimerStatHandle* getParent() const { return getTreeNode().getParent(); } - void setParent(BlockTimerStatHandle* parent) { getTreeNode().setParent(parent); } - - typedef std::vector<BlockTimerStatHandle*>::iterator child_iter; - 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() - { - return static_cast<StatType<TimeBlockAccumulator::CallCountFacet>&>(*(StatType<TimeBlockAccumulator>*)this); - } - - StatType<TimeBlockAccumulator::SelfTimeFacet>& selfTime() - { - return static_cast<StatType<TimeBlockAccumulator::SelfTimeFacet>&>(*(StatType<TimeBlockAccumulator>*)this); - } - - static BlockTimerStatHandle& getRootTimeBlock(); - static void pushLog(LLSD sd); - static void setLogLock(class LLMutex* mutex); - static void writeLog(std::ostream& os); - static void updateTimes(); - - // dumps current cumulative frame stats to log - // call nextFrame() to reset timers - static void dumpCurTimes(); - - ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// // // Important note: These implementations must be FAST! // @@ -143,14 +73,14 @@ public: //#undef _interlockedbittestandset //#undef _interlockedbittestandreset - //inline U32 BlockTimerStatHandle::getCPUClockCount32() + //inline U32 getCPUClockCount32() //{ // U64 time_stamp = __rdtsc(); // return (U32)(time_stamp >> 8); //} // //// return full timer value, *not* shifted by 8 bits - //inline U64 BlockTimerStatHandle::getCPUClockCount64() + //inline U64 getCPUClockCount64() //{ // return __rdtsc(); //} @@ -257,6 +187,12 @@ public: #endif + static BlockTimerStatHandle& getRootTimeBlock(); + static void pushLog(LLSD sd); + static void setLogLock(class LLMutex* mutex); + static void writeLog(std::ostream& os); + static void updateTimes(); + static U64 countsPerSecond(); // updates cumulative times and hierarchy, @@ -269,13 +205,79 @@ public: // call this once a frame to periodically log timers static void logStats(); - bool mCollapsed; // don't show children + // dumps current cumulative frame stats to log + // call nextFrame() to reset timers + static void dumpCurTimes(); + +private: + 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(BlockTimerStatHandle&); + + 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. + // This appears to be fixed in 2012. +public: +#endif + // no-copy + BlockTimer(const BlockTimer& other) {}; + +private: + U64 mStartTime; + BlockTimerStackRecord mParentTimerData; +public: // statics - static std::string sLogName; - static bool sMetricLog, - sLog; - static U64 sClockResolution; + static std::string sLogName; + static bool sMetricLog, + sLog; + static U64 sClockResolution; + +}; + +// this dummy function assists in allocating a block timer with stack-based lifetime. +// this is done by capturing the return value in a stack-allocated const reference variable. +// (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 BlockTimerStatHandle& timer) +{ + return BlockTimer(timer); +} + +// stores a "named" timer instance to be reused via multiple BlockTimer stack instances +class BlockTimerStatHandle +: public StatType<TimeBlockAccumulator> +{ +public: + BlockTimerStatHandle(const char* name, const char* description = ""); + + TimeBlockTreeNode& getTreeNode() const; + BlockTimerStatHandle* getParent() const { return getTreeNode().getParent(); } + void setParent(BlockTimerStatHandle* parent) { getTreeNode().setParent(parent); } + + typedef std::vector<BlockTimerStatHandle*>::iterator child_iter; + 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() + { + return static_cast<StatType<TimeBlockAccumulator::CallCountFacet>&>(*(StatType<TimeBlockAccumulator>*)this); + } + + StatType<TimeBlockAccumulator::SelfTimeFacet>& selfTime() + { + return static_cast<StatType<TimeBlockAccumulator::SelfTimeFacet>&>(*(StatType<TimeBlockAccumulator>*)this); + } + + bool mCollapsed; // don't show children }; // iterators and helper functions for walking the call hierarchy of block timers in different ways @@ -307,14 +309,14 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(BlockTimerStatHandle& timer) cur_timer_data->mTimeBlock = &timer; cur_timer_data->mChildTime = 0; - mStartTime = BlockTimerStatHandle::getCPUClockCount64(); + mStartTime = getCPUClockCount64(); #endif } LL_FORCE_INLINE BlockTimer::~BlockTimer() { #if LL_FAST_TIMER_ON - U64 total_time = BlockTimerStatHandle::getCPUClockCount64() - mStartTime; + U64 total_time = getCPUClockCount64() - mStartTime; BlockTimerStackRecord* cur_timer_data = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance(); if (!cur_timer_data) return; diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 7963485456..1fc821d9a9 100755 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -91,7 +91,7 @@ LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::s // Return TRUE if this metric is requested or if the general default "catch all" metric is requested BOOL LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name) { - return (LLTrace::BlockTimerStatHandle::sMetricLog && ((LLTrace::BlockTimerStatHandle::sLogName == name) || (LLTrace::BlockTimerStatHandle::sLogName == DEFAULT_METRIC_NAME))); + return (LLTrace::BlockTimer::sMetricLog && ((LLTrace::BlockTimer::sLogName == name) || (LLTrace::BlockTimer::sLogName == DEFAULT_METRIC_NAME))); } /*static*/ @@ -194,7 +194,7 @@ void LLMetricPerformanceTesterBasic::preOutputTestResults(LLSD* sd) void LLMetricPerformanceTesterBasic::postOutputTestResults(LLSD* sd) { - LLTrace::BlockTimerStatHandle::pushLog(*sd); + LLTrace::BlockTimer::pushLog(*sd); } void LLMetricPerformanceTesterBasic::outputTestResults() diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 95d26f96c0..dbf6771e66 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -163,7 +163,7 @@ F64Seconds Recording::getSum(const StatType<TimeBlockAccumulator>& stat) const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; const TimeBlockAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mStackTimers[stat.getIndex()] : NULL; return F64Seconds((F64)(accumulator.mTotalTimeCounter) + (F64)(active_accumulator ? active_accumulator->mTotalTimeCounter : 0)) - / (F64)LLTrace::BlockTimerStatHandle::countsPerSecond(); + / (F64)LLTrace::BlockTimer::countsPerSecond(); } F64Seconds Recording::getSum(const StatType<TimeBlockAccumulator::SelfTimeFacet>& stat) @@ -171,7 +171,7 @@ F64Seconds Recording::getSum(const StatType<TimeBlockAccumulator::SelfTimeFacet> update(); const TimeBlockAccumulator& accumulator = mBuffers->mStackTimers[stat.getIndex()]; const TimeBlockAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mStackTimers[stat.getIndex()] : NULL; - return F64Seconds((F64)(accumulator.mSelfTimeCounter) + (F64)(active_accumulator ? active_accumulator->mSelfTimeCounter : 0) / (F64)LLTrace::BlockTimerStatHandle::countsPerSecond()); + return F64Seconds((F64)(accumulator.mSelfTimeCounter) + (F64)(active_accumulator ? active_accumulator->mSelfTimeCounter : 0) / (F64)LLTrace::BlockTimer::countsPerSecond()); } @@ -190,7 +190,7 @@ F64Seconds Recording::getPerSec(const StatType<TimeBlockAccumulator>& stat) const TimeBlockAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mStackTimers[stat.getIndex()] : NULL; return F64Seconds((F64)(accumulator.mTotalTimeCounter + (active_accumulator ? active_accumulator->mTotalTimeCounter : 0)) - / ((F64)LLTrace::BlockTimerStatHandle::countsPerSecond() * mElapsedSeconds.value())); + / ((F64)LLTrace::BlockTimer::countsPerSecond() * mElapsedSeconds.value())); } F64Seconds Recording::getPerSec(const StatType<TimeBlockAccumulator::SelfTimeFacet>& stat) @@ -200,7 +200,7 @@ F64Seconds Recording::getPerSec(const StatType<TimeBlockAccumulator::SelfTimeFac const TimeBlockAccumulator* active_accumulator = mActiveBuffers ? &mActiveBuffers->mStackTimers[stat.getIndex()] : NULL; return F64Seconds((F64)(accumulator.mSelfTimeCounter + (active_accumulator ? active_accumulator->mSelfTimeCounter : 0)) - / ((F64)LLTrace::BlockTimerStatHandle::countsPerSecond() * mElapsedSeconds.value())); + / ((F64)LLTrace::BlockTimer::countsPerSecond() * mElapsedSeconds.value())); } F32 Recording::getPerSec(const StatType<TimeBlockAccumulator::CallCountFacet>& stat) diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index a70e94e4b1..aec36ef2c4 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -50,7 +50,7 @@ void ThreadRecorder::init() LLThreadLocalSingletonPointer<BlockTimerStackRecord>::setInstance(&mBlockTimerStackRecord); //NB: the ordering of initialization in this function is very fragile due to a large number of implicit dependencies set_thread_recorder(this); - BlockTimerStatHandle& root_time_block = BlockTimerStatHandle::getRootTimeBlock(); + BlockTimerStatHandle& root_time_block = BlockTimer::getRootTimeBlock(); BlockTimerStackRecord* timer_stack = LLThreadLocalSingletonPointer<BlockTimerStackRecord>::getInstance(); timer_stack->mTimeBlock = &root_time_block; @@ -78,7 +78,7 @@ void ThreadRecorder::init() mRootTimer = new BlockTimer(root_time_block); timer_stack->mActiveTimer = mRootTimer; - BlockTimerStatHandle::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; + BlockTimer::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; claim_alloc(gTraceMemStat, this); claim_alloc(gTraceMemStat, mRootTimer); @@ -138,7 +138,7 @@ AccumulatorBufferGroup* ThreadRecorder::activate( AccumulatorBufferGroup* record { AccumulatorBufferGroup& prev_active_recording = mActiveRecordings.back()->mPartialRecording; prev_active_recording.sync(); - BlockTimerStatHandle::updateTimes(); + BlockTimer::updateTimes(); prev_active_recording.handOffTo(active_recording->mPartialRecording); } mActiveRecordings.push_back(active_recording); @@ -152,7 +152,7 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( if (mActiveRecordings.empty()) return mActiveRecordings.end(); mActiveRecordings.back()->mPartialRecording.sync(); - BlockTimerStatHandle::updateTimes(); + BlockTimer::updateTimes(); active_recording_list_t::reverse_iterator it, end_it; for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend(); |