diff options
Diffstat (limited to 'indra/llcommon/lltracerecording.cpp')
-rw-r--r-- | indra/llcommon/lltracerecording.cpp | 428 |
1 files changed, 378 insertions, 50 deletions
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 9a769ff344..c110e64380 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -26,6 +26,7 @@ #include "linden_common.h" #include "lltrace.h" +#include "llfasttimer.h" #include "lltracerecording.h" #include "lltracethreadrecorder.h" #include "llthread.h" @@ -39,29 +40,53 @@ namespace LLTrace Recording::Recording() : mElapsedSeconds(0), - mCounts(new AccumulatorBuffer<CountAccumulator<F64> >()), - mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<F64> >()), - mStackTimers(new AccumulatorBuffer<TimerAccumulator>()) + mCountsFloat(new AccumulatorBuffer<CountAccumulator<F64> >()), + mMeasurementsFloat(new AccumulatorBuffer<MeasurementAccumulator<F64> >()), + mCounts(new AccumulatorBuffer<CountAccumulator<S64> >()), + mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<S64> >()), + mStackTimers(new AccumulatorBuffer<TimeBlockAccumulator>()), + mMemStats(new AccumulatorBuffer<MemStatAccumulator>()) {} +Recording::Recording( const Recording& other ) +{ + llassert(other.mCountsFloat.notNull()); + mSamplingTimer = other.mSamplingTimer; + mElapsedSeconds = other.mElapsedSeconds; + mCountsFloat = other.mCountsFloat; + mMeasurementsFloat = other.mMeasurementsFloat; + mCounts = other.mCounts; + mMeasurements = other.mMeasurements; + mStackTimers = other.mStackTimers; + mMemStats = other.mMemStats; + + LLStopWatchControlsMixin<Recording>::initTo(other.getPlayState()); +} + + Recording::~Recording() -{} +{ + stop(); + llassert(isStopped()); +} void Recording::update() { if (isStarted()) -{ + { LLTrace::get_thread_recorder()->update(this); - mElapsedSeconds = 0.0; mSamplingTimer.reset(); } } void Recording::handleReset() { + mCountsFloat.write()->reset(); + mMeasurementsFloat.write()->reset(); mCounts.write()->reset(); mMeasurements.write()->reset(); mStackTimers.write()->reset(); + mMemStats.write()->reset(); mElapsedSeconds = 0.0; mSamplingTimer.reset(); @@ -76,6 +101,7 @@ void Recording::handleStart() void Recording::handleStop() { mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); + LLTrace::TimeBlock::processTimes(); LLTrace::get_thread_recorder()->deactivate(this); } @@ -83,14 +109,31 @@ void Recording::handleSplitTo(Recording& other) { stop(); other.restart(); + other.mMeasurementsFloat.write()->reset(mMeasurementsFloat); + other.mMeasurements.write()->reset(mMeasurements); + //TODO: figure out how to get seamless handoff of timing stats } - void Recording::makePrimary() { + mCountsFloat.write()->makePrimary(); + mMeasurementsFloat.write()->makePrimary(); mCounts.write()->makePrimary(); mMeasurements.write()->makePrimary(); mStackTimers.write()->makePrimary(); + mMemStats.write()->makePrimary(); + + ThreadRecorder* thread_recorder = get_thread_recorder().get(); + AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = *mStackTimers.write(); + // update stacktimer parent pointers + for (S32 i = 0, end_i = mStackTimers->size(); i < end_i; i++) + { + TimeBlockTreeNode* tree_node = thread_recorder->getTimeBlockTreeNode(i); + if (tree_node) + { + timer_accumulator_buffer[i].mParent = tree_node->mParent; + } + } } bool Recording::isPrimary() const @@ -98,27 +141,234 @@ bool Recording::isPrimary() const return mCounts->isPrimary(); } -void Recording::mergeRecording( const Recording& other ) +void Recording::makeUnique() { + mCountsFloat.makeUnique(); + mMeasurementsFloat.makeUnique(); + mCounts.makeUnique(); + mMeasurements.makeUnique(); + mStackTimers.makeUnique(); + mMemStats.makeUnique(); +} + +void Recording::appendRecording( const Recording& other ) +{ + mCountsFloat.write()->addSamples(*other.mCountsFloat); + mMeasurementsFloat.write()->addSamples(*other.mMeasurementsFloat); mCounts.write()->addSamples(*other.mCounts); mMeasurements.write()->addSamples(*other.mMeasurements); + mMemStats.write()->addSamples(*other.mMemStats); + mStackTimers.write()->addSamples(*other.mStackTimers); mElapsedSeconds += other.mElapsedSeconds; } +void Recording::mergeRecording( const Recording& other) +{ + mCountsFloat.write()->addSamples(*other.mCountsFloat); + mMeasurementsFloat.write()->addSamples(*other.mMeasurementsFloat); + mCounts.write()->addSamples(*other.mCounts); + mMeasurements.write()->addSamples(*other.mMeasurements); + mMemStats.write()->addSamples(*other.mMemStats); +} + +LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat) const +{ + return (F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter / (F64)LLTrace::TimeBlock::countsPerSecond(); +} + +LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const +{ + return (F64)(*mStackTimers)[stat.getIndex()].mSelfTimeCounter / (F64)LLTrace::TimeBlock::countsPerSecond(); +} + + +U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat) const +{ + return (*mStackTimers)[stat.getIndex()].mCalls; +} + +LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator>& stat) const +{ + return (F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); +} + +LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const +{ + return (F64)(*mStackTimers)[stat.getIndex()].mSelfTimeCounter / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); +} + +F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat) const +{ + return (F32)(*mStackTimers)[stat.getIndex()].mCalls / mElapsedSeconds; +} + +LLUnit<LLUnits::Bytes, U32> Recording::getSum(const TraceType<MemStatAccumulator>& stat) const +{ + return (*mMemStats)[stat.getIndex()].mAllocatedCount; +} + +LLUnit<LLUnits::Bytes, F32> Recording::getPerSec(const TraceType<MemStatAccumulator>& stat) const +{ + return (F32)(*mMemStats)[stat.getIndex()].mAllocatedCount / mElapsedSeconds; +} + + +F64 Recording::getSum( const TraceType<CountAccumulator<F64> >& stat ) const +{ + return (*mCountsFloat)[stat.getIndex()].getSum(); +} + +S64 Recording::getSum( const TraceType<CountAccumulator<S64> >& stat ) const +{ + return (*mCounts)[stat.getIndex()].getSum(); +} + +F64 Recording::getSum( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return (F64)(*mMeasurementsFloat)[stat.getIndex()].getSum(); +} + +S64 Recording::getSum( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return (S64)(*mMeasurements)[stat.getIndex()].getSum(); +} + + + +F64 Recording::getPerSec( const TraceType<CountAccumulator<F64> >& stat ) const +{ + F64 sum = (*mCountsFloat)[stat.getIndex()].getSum(); + return (sum != 0.0) + ? (sum / mElapsedSeconds) + : 0.0; +} + +F64 Recording::getPerSec( const TraceType<CountAccumulator<S64> >& stat ) const +{ + S64 sum = (*mCounts)[stat.getIndex()].getSum(); + return (sum != 0) + ? ((F64)sum / mElapsedSeconds) + : 0.0; +} + +U32 Recording::getSampleCount( const TraceType<CountAccumulator<F64> >& stat ) const +{ + return (*mCountsFloat)[stat.getIndex()].getSampleCount(); +} + +U32 Recording::getSampleCount( const TraceType<CountAccumulator<S64> >& stat ) const +{ + return (*mMeasurementsFloat)[stat.getIndex()].getSampleCount(); +} + + +F64 Recording::getPerSec( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + F64 sum = (*mMeasurementsFloat)[stat.getIndex()].getSum(); + return (sum != 0.0) + ? (sum / mElapsedSeconds) + : 0.0; +} + +F64 Recording::getPerSec( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + S64 sum = (*mMeasurements)[stat.getIndex()].getSum(); + return (sum != 0) + ? ((F64)sum / mElapsedSeconds) + : 0.0; +} + +F64 Recording::getMin( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return (*mMeasurementsFloat)[stat.getIndex()].getMin(); +} + +S64 Recording::getMin( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return (*mMeasurements)[stat.getIndex()].getMin(); +} + +F64 Recording::getMax( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return (*mMeasurementsFloat)[stat.getIndex()].getMax(); +} + +S64 Recording::getMax( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return (*mMeasurements)[stat.getIndex()].getMax(); +} + +F64 Recording::getMean( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return (*mMeasurementsFloat)[stat.getIndex()].getMean(); +} + +F64 Recording::getMean( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return (*mMeasurements)[stat.getIndex()].getMean(); +} + +F64 Recording::getStandardDeviation( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return (*mMeasurementsFloat)[stat.getIndex()].getStandardDeviation(); +} + +F64 Recording::getStandardDeviation( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return (*mMeasurements)[stat.getIndex()].getStandardDeviation(); +} + +F64 Recording::getLastValue( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return (*mMeasurementsFloat)[stat.getIndex()].getLastValue(); +} + +S64 Recording::getLastValue( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return (*mMeasurements)[stat.getIndex()].getLastValue(); +} + +U32 Recording::getSampleCount( const TraceType<MeasurementAccumulator<F64> >& stat ) const +{ + return (*mMeasurementsFloat)[stat.getIndex()].getSampleCount(); +} + +U32 Recording::getSampleCount( const TraceType<MeasurementAccumulator<S64> >& stat ) const +{ + return (*mMeasurements)[stat.getIndex()].getSampleCount(); +} + + + /////////////////////////////////////////////////////////////////////// -// Recording +// PeriodicRecording /////////////////////////////////////////////////////////////////////// -PeriodicRecording::PeriodicRecording( S32 num_periods ) +PeriodicRecording::PeriodicRecording( S32 num_periods, EStopWatchState state) : mNumPeriods(num_periods), mCurPeriod(0), mTotalValid(false), mRecordingPeriods( new Recording[num_periods]) { llassert(mNumPeriods > 0); + initTo(state); +} + +PeriodicRecording::PeriodicRecording(PeriodicRecording& other) +: mNumPeriods(other.mNumPeriods), + mCurPeriod(other.mCurPeriod), + mTotalValid(other.mTotalValid), + mTotalRecording(other.mTotalRecording) +{ + mRecordingPeriods = new Recording[mNumPeriods]; + for (S32 i = 0; i < mNumPeriods; i++) + { + mRecordingPeriods[i] = other.mRecordingPeriods[i]; + } } + PeriodicRecording::~PeriodicRecording() { delete[] mRecordingPeriods; @@ -127,18 +377,20 @@ PeriodicRecording::~PeriodicRecording() void PeriodicRecording::nextPeriod() { - EPlayState play_state = getPlayState(); - getCurRecordingPeriod().stop(); + EStopWatchState play_state = getPlayState(); + Recording& old_recording = getCurRecordingPeriod(); mCurPeriod = (mCurPeriod + 1) % mNumPeriods; + old_recording.splitTo(getCurRecordingPeriod()); + switch(play_state) { case STOPPED: + getCurRecordingPeriod().stop(); break; case PAUSED: getCurRecordingPeriod().pause(); break; case STARTED: - getCurRecordingPeriod().start(); break; } // new period, need to recalculate total @@ -152,75 +404,117 @@ Recording& PeriodicRecording::getTotalRecording() mTotalRecording.reset(); for (S32 i = mCurPeriod + 1; i < mCurPeriod + mNumPeriods; i++) { - mTotalRecording.mergeRecording(mRecordingPeriods[i % mNumPeriods]); + mTotalRecording.appendRecording(mRecordingPeriods[i % mNumPeriods]); } } mTotalValid = true; return mTotalRecording; } -void PeriodicRecording::handleStart() +void PeriodicRecording::start() +{ + getCurRecordingPeriod().start(); +} + +void PeriodicRecording::stop() +{ + getCurRecordingPeriod().stop(); +} + +void PeriodicRecording::pause() +{ + getCurRecordingPeriod().pause(); +} + +void PeriodicRecording::resume() +{ + getCurRecordingPeriod().resume(); +} + +void PeriodicRecording::restart() { - getCurRecordingPeriod().handleStart(); + getCurRecordingPeriod().restart(); } -void PeriodicRecording::handleStop() +void PeriodicRecording::reset() { - getCurRecordingPeriod().handleStop(); + getCurRecordingPeriod().reset(); } -void PeriodicRecording::handleReset() +void PeriodicRecording::splitTo(PeriodicRecording& other) { - getCurRecordingPeriod().handleReset(); + getCurRecordingPeriod().splitTo(other.getCurRecordingPeriod()); } -void PeriodicRecording::handleSplitTo( PeriodicRecording& other ) +void PeriodicRecording::splitFrom(PeriodicRecording& other) { - getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod()); + getCurRecordingPeriod().splitFrom(other.getCurRecordingPeriod()); } + /////////////////////////////////////////////////////////////////////// // ExtendableRecording /////////////////////////////////////////////////////////////////////// void ExtendableRecording::extend() { - mAcceptedRecording.mergeRecording(mPotentialRecording); + mAcceptedRecording.appendRecording(mPotentialRecording); mPotentialRecording.reset(); } -void ExtendableRecording::handleStart() +void ExtendableRecording::start() +{ + mPotentialRecording.start(); +} + +void ExtendableRecording::stop() +{ + mPotentialRecording.stop(); +} + +void ExtendableRecording::pause() +{ + mPotentialRecording.pause(); +} + +void ExtendableRecording::resume() +{ + mPotentialRecording.resume(); +} + +void ExtendableRecording::restart() { - mPotentialRecording.handleStart(); + mAcceptedRecording.reset(); + mPotentialRecording.restart(); } -void ExtendableRecording::handleStop() +void ExtendableRecording::reset() { - mPotentialRecording.handleStop(); + mAcceptedRecording.reset(); + mPotentialRecording.reset(); } -void ExtendableRecording::handleReset() +void ExtendableRecording::splitTo(ExtendableRecording& other) { - mAcceptedRecording.handleReset(); - mPotentialRecording.handleReset(); + mPotentialRecording.splitTo(other.mPotentialRecording); } -void ExtendableRecording::handleSplitTo( ExtendableRecording& other ) +void ExtendableRecording::splitFrom(ExtendableRecording& other) { - mPotentialRecording.handleSplitTo(other.mPotentialRecording); + mPotentialRecording.splitFrom(other.mPotentialRecording); } PeriodicRecording& get_frame_recording() { - static PeriodicRecording sRecording(64); - return sRecording; + static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(64, PeriodicRecording::STARTED)); + return *sRecording; } } -void LLVCRControlsMixinCommon::start() +void LLStopWatchControlsMixinCommon::start() { - switch (mPlayState) + switch (mState) { case STOPPED: handleReset(); @@ -232,13 +526,16 @@ void LLVCRControlsMixinCommon::start() case STARTED: handleReset(); break; + default: + llassert(false); + break; } - mPlayState = STARTED; + mState = STARTED; } -void LLVCRControlsMixinCommon::stop() +void LLStopWatchControlsMixinCommon::stop() { - switch (mPlayState) + switch (mState) { case STOPPED: break; @@ -248,13 +545,16 @@ void LLVCRControlsMixinCommon::stop() case STARTED: handleStop(); break; + default: + llassert(false); + break; } - mPlayState = STOPPED; + mState = STOPPED; } -void LLVCRControlsMixinCommon::pause() +void LLStopWatchControlsMixinCommon::pause() { - switch (mPlayState) + switch (mState) { case STOPPED: break; @@ -263,13 +563,16 @@ void LLVCRControlsMixinCommon::pause() case STARTED: handleStop(); break; + default: + llassert(false); + break; } - mPlayState = PAUSED; + mState = PAUSED; } -void LLVCRControlsMixinCommon::resume() +void LLStopWatchControlsMixinCommon::resume() { - switch (mPlayState) + switch (mState) { case STOPPED: handleStart(); @@ -279,13 +582,16 @@ void LLVCRControlsMixinCommon::resume() break; case STARTED: break; + default: + llassert(false); + break; } - mPlayState = STARTED; + mState = STARTED; } -void LLVCRControlsMixinCommon::restart() +void LLStopWatchControlsMixinCommon::restart() { - switch (mPlayState) + switch (mState) { case STOPPED: handleReset(); @@ -298,11 +604,33 @@ void LLVCRControlsMixinCommon::restart() case STARTED: handleReset(); break; + default: + llassert(false); + break; } - mPlayState = STARTED; + mState = STARTED; } -void LLVCRControlsMixinCommon::reset() +void LLStopWatchControlsMixinCommon::reset() { handleReset(); } + +void LLStopWatchControlsMixinCommon::initTo( EStopWatchState state ) +{ + switch(state) + { + case STOPPED: + break; + case PAUSED: + break; + case STARTED: + handleStart(); + break; + default: + llassert(false); + break; + } + + mState = state; +} |