summaryrefslogtreecommitdiff
path: root/indra/llcommon/lltracerecording.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/lltracerecording.cpp')
-rw-r--r--indra/llcommon/lltracerecording.cpp428
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;
+}