Automated merge with ssh://hg.lindenlab.com/richard/viewer-interesting
commit
f5852ff448
|
|
@ -353,7 +353,7 @@ namespace LLTrace
|
|||
template<typename UNIT_T>
|
||||
void sample(UNIT_T value)
|
||||
{
|
||||
base_measurement_t::sample(value.get());
|
||||
base_measurement_t::sample(value.value());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -386,7 +386,7 @@ namespace LLTrace
|
|||
template<typename UNIT_T>
|
||||
void add(UNIT_T value)
|
||||
{
|
||||
getPrimaryAccumulator().add(value.get());
|
||||
getPrimaryAccumulator().add(value.value());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ namespace LLTrace
|
|||
|
||||
Recording::Recording()
|
||||
: mElapsedSeconds(0),
|
||||
mIsStarted(false),
|
||||
mRates(new AccumulatorBuffer<RateAccumulator<F32> >()),
|
||||
mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<F32> >()),
|
||||
mStackTimers(new AccumulatorBuffer<TimerAccumulator>())
|
||||
|
|
@ -47,13 +46,7 @@ Recording::Recording()
|
|||
Recording::~Recording()
|
||||
{}
|
||||
|
||||
void Recording::start()
|
||||
{
|
||||
reset();
|
||||
resume();
|
||||
}
|
||||
|
||||
void Recording::reset()
|
||||
void Recording::handleReset()
|
||||
{
|
||||
mRates.write()->reset();
|
||||
mMeasurements.write()->reset();
|
||||
|
|
@ -73,24 +66,22 @@ void Recording::update()
|
|||
}
|
||||
}
|
||||
|
||||
void Recording::resume()
|
||||
void Recording::handleStart()
|
||||
{
|
||||
if (!mIsStarted)
|
||||
{
|
||||
mSamplingTimer.reset();
|
||||
LLTrace::get_thread_recorder()->activate(this);
|
||||
mIsStarted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Recording::stop()
|
||||
{
|
||||
if (mIsStarted)
|
||||
void Recording::handleStop()
|
||||
{
|
||||
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
|
||||
LLTrace::get_thread_recorder()->deactivate(this);
|
||||
mIsStarted = false;
|
||||
}
|
||||
|
||||
void Recording::handleSplitTo(Recording& other)
|
||||
{
|
||||
stop();
|
||||
other.restart();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,147 @@
|
|||
#include "llpointer.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
template<typename DERIVED>
|
||||
class LL_COMMON_API LLVCRControlsMixinInterface
|
||||
{
|
||||
public:
|
||||
virtual ~LLVCRControlsMixinInterface() {}
|
||||
// trigger data accumulation (without reset)
|
||||
virtual void handleStart() = 0;
|
||||
// stop data accumulation, should put object in queryable state
|
||||
virtual void handleStop() = 0;
|
||||
// clear accumulated values, can be called while started
|
||||
virtual void handleReset() = 0;
|
||||
// atomically stop this object while starting the other
|
||||
// no data can be missed in between stop and start
|
||||
virtual void handleSplitTo(DERIVED& other) = 0;
|
||||
};
|
||||
|
||||
template<typename DERIVED>
|
||||
class LL_COMMON_API LLVCRControlsMixin
|
||||
: private LLVCRControlsMixinInterface<DERIVED>
|
||||
{
|
||||
public:
|
||||
enum EPlayState
|
||||
{
|
||||
STOPPED,
|
||||
PAUSED,
|
||||
STARTED
|
||||
};
|
||||
|
||||
void start()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
handleReset();
|
||||
handleStart();
|
||||
break;
|
||||
case PAUSED:
|
||||
handleStart();
|
||||
break;
|
||||
case STARTED:
|
||||
handleReset();
|
||||
break;
|
||||
}
|
||||
mPlayState = STARTED;
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
break;
|
||||
case PAUSED:
|
||||
handleStop();
|
||||
break;
|
||||
case STARTED:
|
||||
break;
|
||||
}
|
||||
mPlayState = STOPPED;
|
||||
}
|
||||
|
||||
void pause()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
break;
|
||||
case PAUSED:
|
||||
break;
|
||||
case STARTED:
|
||||
handleStop();
|
||||
break;
|
||||
}
|
||||
mPlayState = PAUSED;
|
||||
}
|
||||
|
||||
void resume()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
handleStart();
|
||||
break;
|
||||
case PAUSED:
|
||||
handleStart();
|
||||
break;
|
||||
case STARTED:
|
||||
break;
|
||||
}
|
||||
mPlayState = STARTED;
|
||||
}
|
||||
|
||||
void restart()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
handleReset();
|
||||
handleStart();
|
||||
break;
|
||||
case PAUSED:
|
||||
handleReset();
|
||||
handleStart();
|
||||
break;
|
||||
case STARTED:
|
||||
handleReset();
|
||||
break;
|
||||
}
|
||||
mPlayState = STARTED;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
handleReset();
|
||||
}
|
||||
|
||||
void splitTo(DERIVED& other)
|
||||
{
|
||||
onSplitTo(other);
|
||||
}
|
||||
|
||||
void splitFrom(DERIVED& other)
|
||||
{
|
||||
other.onSplitTo(*this);
|
||||
}
|
||||
|
||||
bool isStarted() { return mPlayState == STARTED; }
|
||||
bool isPaused() { return mPlayState == PAUSED; }
|
||||
bool isStopped() { return mPlayState == STOPPED; }
|
||||
EPlayState getPlayState() { return mPlayState; }
|
||||
|
||||
protected:
|
||||
|
||||
LLVCRControlsMixin()
|
||||
: mPlayState(STOPPED)
|
||||
{}
|
||||
|
||||
private:
|
||||
EPlayState mPlayState;
|
||||
};
|
||||
|
||||
namespace LLTrace
|
||||
{
|
||||
template<typename T, typename IS_UNIT> class Rate;
|
||||
|
|
@ -43,7 +184,7 @@ namespace LLTrace
|
|||
template<typename T> class MeasurementAccumulator;
|
||||
class TimerAccumulator;
|
||||
|
||||
class LL_COMMON_API Recording
|
||||
class LL_COMMON_API Recording : public LLVCRControlsMixin<Recording>
|
||||
{
|
||||
public:
|
||||
Recording();
|
||||
|
|
@ -53,18 +194,12 @@ namespace LLTrace
|
|||
void makePrimary();
|
||||
bool isPrimary();
|
||||
|
||||
void start();
|
||||
void stop();
|
||||
void resume();
|
||||
|
||||
void mergeSamples(const Recording& other);
|
||||
void mergeDeltas(const Recording& baseline, const Recording& target);
|
||||
|
||||
void reset();
|
||||
void update();
|
||||
|
||||
bool isStarted() { return mIsStarted; }
|
||||
|
||||
|
||||
// Rate accessors
|
||||
F32 getSum(const Rate<F32, void>& stat);
|
||||
F32 getPerSec(const Rate<F32, void>& stat);
|
||||
|
|
@ -90,6 +225,14 @@ namespace LLTrace
|
|||
F64 getSampleTime() { return mElapsedSeconds; }
|
||||
|
||||
private:
|
||||
friend class PeriodicRecording;
|
||||
// implementation for LLVCRControlsMixin
|
||||
/*virtual*/ void handleStart();
|
||||
/*virtual*/ void handleStop();
|
||||
/*virtual*/ void handleReset();
|
||||
/*virtual*/ void handleSplitTo(Recording& other);
|
||||
|
||||
|
||||
friend class ThreadRecorder;
|
||||
// returns data for current thread
|
||||
class ThreadRecorder* getThreadRecorder();
|
||||
|
|
@ -98,14 +241,99 @@ namespace LLTrace
|
|||
LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<F32> > > mMeasurements;
|
||||
LLCopyOnWritePointer<AccumulatorBuffer<TimerAccumulator> > mStackTimers;
|
||||
|
||||
bool mIsStarted;
|
||||
LLTimer mSamplingTimer;
|
||||
F64 mElapsedSeconds;
|
||||
};
|
||||
|
||||
class LL_COMMON_API PeriodicRecording
|
||||
: public LLVCRControlsMixin<PeriodicRecording>
|
||||
{
|
||||
public:
|
||||
PeriodicRecording(S32 num_periods)
|
||||
: mNumPeriods(num_periods),
|
||||
mCurPeriod(0),
|
||||
mTotalValid(false),
|
||||
mRecordingPeriods(new Recording[num_periods])
|
||||
{
|
||||
llassert(mNumPeriods > 0);
|
||||
}
|
||||
|
||||
~PeriodicRecording()
|
||||
{
|
||||
delete[] mRecordingPeriods;
|
||||
}
|
||||
|
||||
void nextPeriod()
|
||||
{
|
||||
EPlayState play_state = getPlayState();
|
||||
getCurRecordingPeriod().stop();
|
||||
mCurPeriod = (mCurPeriod + 1) % mNumPeriods;
|
||||
switch(play_state)
|
||||
{
|
||||
case STOPPED:
|
||||
break;
|
||||
case PAUSED:
|
||||
getCurRecordingPeriod().pause();
|
||||
break;
|
||||
case STARTED:
|
||||
getCurRecordingPeriod().start();
|
||||
break;
|
||||
}
|
||||
// new period, need to recalculate total
|
||||
mTotalValid = false;
|
||||
}
|
||||
|
||||
Recording& getCurRecordingPeriod()
|
||||
{
|
||||
return mRecordingPeriods[mCurPeriod];
|
||||
}
|
||||
|
||||
const Recording& getCurRecordingPeriod() const
|
||||
{
|
||||
return mRecordingPeriods[mCurPeriod];
|
||||
}
|
||||
|
||||
Recording& getTotalRecording()
|
||||
{
|
||||
if (!mTotalValid)
|
||||
{
|
||||
mTotalRecording.reset();
|
||||
for (S32 i = (mCurPeriod + 1) % mNumPeriods; i < mCurPeriod; i++)
|
||||
{
|
||||
mTotalRecording.mergeSamples(mRecordingPeriods[i]);
|
||||
}
|
||||
}
|
||||
mTotalValid = true;
|
||||
return mTotalRecording;
|
||||
}
|
||||
|
||||
private:
|
||||
// implementation for LLVCRControlsMixin
|
||||
/*virtual*/ void handleStart()
|
||||
{
|
||||
getCurRecordingPeriod().handleStart();
|
||||
}
|
||||
|
||||
/*virtual*/ void handleStop()
|
||||
{
|
||||
getCurRecordingPeriod().handleStop();
|
||||
}
|
||||
|
||||
/*virtual*/ void handleReset()
|
||||
{
|
||||
getCurRecordingPeriod().handleReset();
|
||||
}
|
||||
|
||||
/*virtual*/ void handleSplitTo(PeriodicRecording& other)
|
||||
{
|
||||
getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod());
|
||||
}
|
||||
|
||||
Recording* mRecordingPeriods;
|
||||
Recording mTotalRecording;
|
||||
bool mTotalValid;
|
||||
S32 mNumPeriods,
|
||||
mCurPeriod;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,13 +44,19 @@ struct LLUnit : public BASE_UNIT
|
|||
: BASE_UNIT(convertToBase(value))
|
||||
{}
|
||||
|
||||
operator value_t() { return get(); }
|
||||
operator value_t() { return value(); }
|
||||
|
||||
value_t get() const
|
||||
value_t value() const
|
||||
{
|
||||
return convertToDerived(mValue);
|
||||
}
|
||||
|
||||
template<typename CONVERTED_TYPE>
|
||||
value_t value() const
|
||||
{
|
||||
return CONVERTED_TYPE(*this).value();
|
||||
}
|
||||
|
||||
static value_t convertToBase(value_t derived_value)
|
||||
{
|
||||
return (value_t)((F32)derived_value * DERIVED_UNIT::conversionToBaseFactor());
|
||||
|
|
@ -84,7 +90,7 @@ struct LLUnit<T, T>
|
|||
return *this;
|
||||
}
|
||||
|
||||
value_t get() { return mValue; }
|
||||
value_t value() { return mValue; }
|
||||
|
||||
static value_t convertToBase(value_t derived_value)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue