summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llfasttimer.cpp43
-rw-r--r--indra/llcommon/llfasttimer.h8
-rw-r--r--indra/llcommon/lltrace.h827
-rw-r--r--indra/llcommon/lltracerecording.cpp29
-rw-r--r--indra/llcommon/lltracerecording.h34
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp33
-rw-r--r--indra/llcommon/lltracethreadrecorder.h12
-rw-r--r--indra/llcommon/llunit.h5
8 files changed, 531 insertions, 460 deletions
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index a144a8c94e..5baf049c03 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -256,12 +256,12 @@ void TimeBlock::processTimes()
while(cur_timer && cur_timer->mParentTimerData.mActiveTimer != cur_timer)
{
U64 cumulative_time_delta = cur_time - cur_timer->mStartTime;
-
- accumulator->mTotalTimeCounter += cumulative_time_delta;
- accumulator->mChildTimeCounter += stack_record->mChildTime;
+ accumulator->mTotalTimeCounter += cumulative_time_delta - (accumulator->mTotalTimeCounter - cur_timer->mBlockStartTotalTimeCounter);
+ accumulator->mSelfTimeCounter += cumulative_time_delta - stack_record->mChildTime;
stack_record->mChildTime = 0;
cur_timer->mStartTime = cur_time;
+ cur_timer->mBlockStartTotalTimeCounter = accumulator->mTotalTimeCounter;
stack_record = &cur_timer->mParentTimerData;
accumulator = stack_record->mTimeBlock->getPrimaryAccumulator();
@@ -376,7 +376,7 @@ void TimeBlock::dumpCurTimes()
}
out_str << timerp->getName() << " "
- << std::setprecision(3) << total_time_ms.as<LLUnits::Milliseconds, F32>().value() << " ms, "
+ << std::setprecision(3) << total_time_ms.as<LLUnits::Milliseconds>().value() << " ms, "
<< num_calls << " calls";
llinfos << out_str.str() << llendl;
@@ -400,8 +400,9 @@ void TimeBlock::writeLog(std::ostream& os)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TimeBlockAccumulator::TimeBlockAccumulator()
-: mChildTimeCounter(0),
- mTotalTimeCounter(0),
+: mTotalTimeCounter(0),
+ mSelfTimeCounter(0),
+ mStartTotalTimeCounter(0),
mCalls(0),
mLastCaller(NULL),
mActiveCount(0),
@@ -411,8 +412,8 @@ TimeBlockAccumulator::TimeBlockAccumulator()
void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other )
{
- mChildTimeCounter += other.mChildTimeCounter;
- mTotalTimeCounter += other.mTotalTimeCounter;
+ mTotalTimeCounter += other.mTotalTimeCounter - other.mStartTotalTimeCounter;
+ mSelfTimeCounter += other.mSelfTimeCounter;
mCalls += other.mCalls;
mLastCaller = other.mLastCaller;
mActiveCount = other.mActiveCount;
@@ -422,9 +423,31 @@ void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other )
void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other )
{
- mTotalTimeCounter = 0;
- mChildTimeCounter = 0;
mCalls = 0;
+ mSelfTimeCounter = 0;
+
+ if (other)
+ {
+ mStartTotalTimeCounter = other->mTotalTimeCounter;
+ mTotalTimeCounter = mStartTotalTimeCounter;
+
+ mLastCaller = other->mLastCaller;
+ mActiveCount = other->mActiveCount;
+ mMoveUpTree = other->mMoveUpTree;
+ mParent = other->mParent;
+ }
+ else
+ {
+ mStartTotalTimeCounter = mTotalTimeCounter;
+ }
+}
+
+LLUnit<LLUnits::Seconds, F64> BlockTimer::getElapsedTime()
+{
+ U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime;
+
+ return (F64)total_time / (F64)TimeBlock::countsPerSecond();
}
+
} // namespace LLTrace
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 726db70fbe..32a0629a87 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -71,9 +71,12 @@ public:
BlockTimer(TimeBlock& timer);
~BlockTimer();
+ LLUnit<LLUnits::Seconds, F64> getElapsedTime();
+
private:
U64 mStartTime;
+ U64 mBlockStartTotalTimeCounter;
BlockTimerStackRecord mParentTimerData;
};
@@ -279,6 +282,7 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer)
BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists();
TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator();
accumulator->mActiveCount++;
+ mBlockStartTotalTimeCounter = accumulator->mTotalTimeCounter;
// keep current parent as long as it is active when we are
accumulator->mMoveUpTree |= (accumulator->mParent->getPrimaryAccumulator()->mActiveCount == 0);
@@ -299,8 +303,8 @@ LL_FORCE_INLINE BlockTimer::~BlockTimer()
TimeBlockAccumulator* accumulator = cur_timer_data->mTimeBlock->getPrimaryAccumulator();
accumulator->mCalls++;
- accumulator->mChildTimeCounter += cur_timer_data->mChildTime;
- accumulator->mTotalTimeCounter += total_time;
+ accumulator->mTotalTimeCounter += total_time - (accumulator->mTotalTimeCounter - mBlockStartTotalTimeCounter);
+ accumulator->mSelfTimeCounter += total_time - cur_timer_data->mChildTime;
accumulator->mActiveCount--;
// store last caller to bootstrap tree creation
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 0f927bad53..44da1939c6 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -42,506 +42,519 @@
namespace LLTrace
{
- class Recording;
-
- typedef LLUnit<LLUnits::Bytes, F64> Bytes;
- typedef LLUnit<LLUnits::Kilobytes, F64> Kilobytes;
- typedef LLUnit<LLUnits::Megabytes, F64> Megabytes;
- typedef LLUnit<LLUnits::Gigabytes, F64> Gigabytes;
- typedef LLUnit<LLUnits::Bits, F64> Bits;
- typedef LLUnit<LLUnits::Kilobits, F64> Kilobits;
- typedef LLUnit<LLUnits::Megabits, F64> Megabits;
- typedef LLUnit<LLUnits::Gigabits, F64> Gigabits;
-
- typedef LLUnit<LLUnits::Seconds, F64> Seconds;
- typedef LLUnit<LLUnits::Milliseconds, F64> Milliseconds;
- typedef LLUnit<LLUnits::Minutes, F64> Minutes;
- typedef LLUnit<LLUnits::Hours, F64> Hours;
- typedef LLUnit<LLUnits::Milliseconds, F64> Milliseconds;
- typedef LLUnit<LLUnits::Microseconds, F64> Microseconds;
- typedef LLUnit<LLUnits::Nanoseconds, F64> Nanoseconds;
-
- typedef LLUnit<LLUnits::Meters, F64> Meters;
- typedef LLUnit<LLUnits::Kilometers, F64> Kilometers;
- typedef LLUnit<LLUnits::Centimeters, F64> Centimeters;
- typedef LLUnit<LLUnits::Millimeters, F64> Millimeters;
-
- void init();
- void cleanup();
- bool isInitialized();
-
- const LLThreadLocalPointer<class ThreadRecorder>& get_thread_recorder();
- void set_thread_recorder(class ThreadRecorder*);
-
- class MasterThreadRecorder& getMasterThreadRecorder();
-
- // one per thread per type
- template<typename ACCUMULATOR>
- class AccumulatorBuffer : public LLRefCount
- {
- typedef AccumulatorBuffer<ACCUMULATOR> self_t;
- static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64;
- private:
- struct StaticAllocationMarker { };
-
- AccumulatorBuffer(StaticAllocationMarker m)
- : mStorageSize(0),
- mStorage(NULL),
- mNextStorageSlot(0)
- {
- }
+class Recording;
+
+typedef LLUnit<LLUnits::Bytes, F64> Bytes;
+typedef LLUnit<LLUnits::Kilobytes, F64> Kilobytes;
+typedef LLUnit<LLUnits::Megabytes, F64> Megabytes;
+typedef LLUnit<LLUnits::Gigabytes, F64> Gigabytes;
+typedef LLUnit<LLUnits::Bits, F64> Bits;
+typedef LLUnit<LLUnits::Kilobits, F64> Kilobits;
+typedef LLUnit<LLUnits::Megabits, F64> Megabits;
+typedef LLUnit<LLUnits::Gigabits, F64> Gigabits;
+
+typedef LLUnit<LLUnits::Seconds, F64> Seconds;
+typedef LLUnit<LLUnits::Milliseconds, F64> Milliseconds;
+typedef LLUnit<LLUnits::Minutes, F64> Minutes;
+typedef LLUnit<LLUnits::Hours, F64> Hours;
+typedef LLUnit<LLUnits::Milliseconds, F64> Milliseconds;
+typedef LLUnit<LLUnits::Microseconds, F64> Microseconds;
+typedef LLUnit<LLUnits::Nanoseconds, F64> Nanoseconds;
+
+typedef LLUnit<LLUnits::Meters, F64> Meters;
+typedef LLUnit<LLUnits::Kilometers, F64> Kilometers;
+typedef LLUnit<LLUnits::Centimeters, F64> Centimeters;
+typedef LLUnit<LLUnits::Millimeters, F64> Millimeters;
+
+void init();
+void cleanup();
+bool isInitialized();
+
+const LLThreadLocalPointer<class ThreadRecorder>& get_thread_recorder();
+void set_thread_recorder(class ThreadRecorder*);
+
+class MasterThreadRecorder& getMasterThreadRecorder();
+
+// one per thread per type
+template<typename ACCUMULATOR>
+class AccumulatorBuffer : public LLRefCount
+{
+ typedef AccumulatorBuffer<ACCUMULATOR> self_t;
+ static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64;
+private:
+ struct StaticAllocationMarker { };
- public:
+ AccumulatorBuffer(StaticAllocationMarker m)
+ : mStorageSize(0),
+ mStorage(NULL),
+ mNextStorageSlot(0)
+ {
+ }
- AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer())
- : mStorageSize(0),
- mStorage(NULL),
- mNextStorageSlot(other.mNextStorageSlot)
- {
- resize(other.mStorageSize);
- for (S32 i = 0; i < mNextStorageSlot; i++)
- {
- mStorage[i] = other.mStorage[i];
- }
- }
+public:
- ~AccumulatorBuffer()
+ AccumulatorBuffer(const AccumulatorBuffer& other = *getDefaultBuffer())
+ : mStorageSize(0),
+ mStorage(NULL),
+ mNextStorageSlot(other.mNextStorageSlot)
+ {
+ resize(other.mStorageSize);
+ for (S32 i = 0; i < mNextStorageSlot; i++)
{
- if (LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance() == mStorage)
- {
- LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(getDefaultBuffer()->mStorage);
- }
- delete[] mStorage;
+ mStorage[i] = other.mStorage[i];
}
+ }
- LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)
- {
- return mStorage[index];
+ ~AccumulatorBuffer()
+ {
+ if (LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance() == mStorage)
+ {
+ LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(getDefaultBuffer()->mStorage);
}
+ delete[] mStorage;
+ }
- LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const
- {
- return mStorage[index];
- }
+ LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index)
+ {
+ return mStorage[index];
+ }
- void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other)
- {
- llassert(mNextStorageSlot == other.mNextStorageSlot);
+ LL_FORCE_INLINE const ACCUMULATOR& operator[](size_t index) const
+ {
+ return mStorage[index];
+ }
- for (size_t i = 0; i < mNextStorageSlot; i++)
- {
- mStorage[i].addSamples(other.mStorage[i]);
- }
- }
+ void addSamples(const AccumulatorBuffer<ACCUMULATOR>& other)
+ {
+ llassert(mNextStorageSlot == other.mNextStorageSlot);
- void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other)
+ for (size_t i = 0; i < mNextStorageSlot; i++)
{
- for (size_t i = 0; i < mNextStorageSlot; i++)
- {
- mStorage[i] = other.mStorage[i];
- }
+ mStorage[i].addSamples(other.mStorage[i]);
}
+ }
- void reset(const AccumulatorBuffer<ACCUMULATOR>* other = NULL)
+ void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other)
+ {
+ for (size_t i = 0; i < mNextStorageSlot; i++)
{
- for (size_t i = 0; i < mNextStorageSlot; i++)
- {
- mStorage[i].reset(other ? &other->mStorage[i] : NULL);
- }
+ mStorage[i] = other.mStorage[i];
}
+ }
- void makePrimary()
+ void reset(const AccumulatorBuffer<ACCUMULATOR>* other = NULL)
+ {
+ for (size_t i = 0; i < mNextStorageSlot; i++)
{
- LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(mStorage);
+ mStorage[i].reset(other ? &other->mStorage[i] : NULL);
}
+ }
- bool isPrimary() const
- {
- return LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance() == mStorage;
- }
+ void makePrimary()
+ {
+ LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(mStorage);
+ }
- LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage()
- {
- return LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance();
- }
+ bool isPrimary() const
+ {
+ return LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance() == mStorage;
+ }
- // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned
- size_t reserveSlot()
+ LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage()
+ {
+ return LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance();
+ }
+
+ // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned
+ size_t reserveSlot()
+ {
+ if (LLTrace::isInitialized())
{
- if (LLTrace::isInitialized())
- {
- llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl;
- }
- size_t next_slot = mNextStorageSlot++;
- if (next_slot >= mStorageSize)
- {
- resize(mStorageSize + (mStorageSize >> 2));
- }
- llassert(mStorage && next_slot < mStorageSize);
- return next_slot;
+ llerrs << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << llendl;
}
-
- void resize(size_t new_size)
+ size_t next_slot = mNextStorageSlot++;
+ if (next_slot >= mStorageSize)
{
- if (new_size <= mStorageSize) return;
+ resize(mStorageSize + (mStorageSize >> 2));
+ }
+ llassert(mStorage && next_slot < mStorageSize);
+ return next_slot;
+ }
- ACCUMULATOR* old_storage = mStorage;
- mStorage = new ACCUMULATOR[new_size];
- if (old_storage)
- {
- for (S32 i = 0; i < mStorageSize; i++)
- {
- mStorage[i] = old_storage[i];
- }
- }
- mStorageSize = new_size;
- delete[] old_storage;
+ void resize(size_t new_size)
+ {
+ if (new_size <= mStorageSize) return;
- self_t* default_buffer = getDefaultBuffer();
- if (this != default_buffer
- && new_size > default_buffer->size())
+ ACCUMULATOR* old_storage = mStorage;
+ mStorage = new ACCUMULATOR[new_size];
+ if (old_storage)
+ {
+ for (S32 i = 0; i < mStorageSize; i++)
{
- //NB: this is not thread safe, but we assume that all resizing occurs during static initialization
- default_buffer->resize(new_size);
+ mStorage[i] = old_storage[i];
}
}
+ mStorageSize = new_size;
+ delete[] old_storage;
- size_t size() const
+ self_t* default_buffer = getDefaultBuffer();
+ if (this != default_buffer
+ && new_size > default_buffer->size())
{
- return mNextStorageSlot;
+ //NB: this is not thread safe, but we assume that all resizing occurs during static initialization
+ default_buffer->resize(new_size);
}
+ }
+
+ size_t size() const
+ {
+ return mNextStorageSlot;
+ }
- static self_t* getDefaultBuffer()
+ static self_t* getDefaultBuffer()
+ {
+ // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data
+ // so as not to trigger an access violation
+ static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker());
+ static bool sInitialized = false;
+ if (!sInitialized)
{
- // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data
- // so as not to trigger an access violation
- static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker());
- static bool sInitialized = false;
- if (!sInitialized)
- {
- sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE);
- sInitialized = true;
- }
- return sBuffer;
+ sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE);
+ sInitialized = true;
}
+ return sBuffer;
+ }
- private:
- ACCUMULATOR* mStorage;
- size_t mStorageSize;
- size_t mNextStorageSlot;
- };
+private:
+ ACCUMULATOR* mStorage;
+ size_t mStorageSize;
+ size_t mNextStorageSlot;
+};
- //TODO: replace with decltype when C++11 is enabled
- template<typename T>
- struct MeanValueType
- {
- typedef F64 type;
- };
+//TODO: replace with decltype when C++11 is enabled
+template<typename T>
+struct MeanValueType
+{
+ typedef F64 type;
+};
- template<typename ACCUMULATOR>
- class TraceType
- : public LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>
- {
- public:
- typedef typename MeanValueType<TraceType<ACCUMULATOR> >::type mean_t;
+template<typename ACCUMULATOR>
+class TraceType
+: public LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>
+{
+public:
+ TraceType(const char* name, const char* description = NULL)
+ : LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>(name),
+ mName(name),
+ mDescription(description ? description : ""),
+ mAccumulatorIndex(AccumulatorBuffer<ACCUMULATOR>::getDefaultBuffer()->reserveSlot())
+ {}
- TraceType(const char* name, const char* description = NULL)
- : LLInstanceTracker<TraceType<ACCUMULATOR>, std::string>(name),
- mName(name),
- mDescription(description ? description : ""),
- mAccumulatorIndex(AccumulatorBuffer<ACCUMULATOR>::getDefaultBuffer()->reserveSlot())
- {}
+ LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const
+ {
+ ACCUMULATOR* accumulator_storage = AccumulatorBuffer<ACCUMULATOR>::getPrimaryStorage();
+ return &accumulator_storage[mAccumulatorIndex];
+ }
- LL_FORCE_INLINE ACCUMULATOR* getPrimaryAccumulator() const
- {
- ACCUMULATOR* accumulator_storage = AccumulatorBuffer<ACCUMULATOR>::getPrimaryStorage();
- return &accumulator_storage[mAccumulatorIndex];
- }
+ size_t getIndex() const { return mAccumulatorIndex; }
- size_t getIndex() const { return mAccumulatorIndex; }
+ const std::string& getName() const { return mName; }
- const std::string& getName() const { return mName; }
+protected:
+ const std::string mName;
+ const std::string mDescription;
+ const size_t mAccumulatorIndex;
+};
- protected:
- const std::string mName;
- const std::string mDescription;
- const size_t mAccumulatorIndex;
- };
+template<typename T>
+class MeasurementAccumulator
+{
+public:
+ typedef T value_t;
+ typedef MeasurementAccumulator<T> self_t;
+
+ MeasurementAccumulator()
+ : mSum(0),
+ mMin((std::numeric_limits<T>::max)()),
+ mMax((std::numeric_limits<T>::min)()),
+ mMean(0),
+ mVarianceSum(0),
+ mNumSamples(0),
+ mLastValue(0)
+ {}
- template<typename T>
- class MeasurementAccumulator
+ void sample(T value)
{
- public:
- typedef T value_t;
- typedef MeasurementAccumulator<T> self_t;
-
- MeasurementAccumulator()
- : mSum(0),
- mMin((std::numeric_limits<T>::max)()),
- mMax((std::numeric_limits<T>::min)()),
- mMean(0),
- mVarianceSum(0),
- mNumSamples(0),
- mLastValue(0)
- {}
+ mNumSamples++;
+ mSum += value;
+ if (value < mMin)
+ {
+ mMin = value;
+ }
+ if (value > mMax)
+ {
+ mMax = value;
+ }
+ F64 old_mean = mMean;
+ mMean += ((F64)value - old_mean) / (F64)mNumSamples;
+ mVarianceSum += ((F64)value - old_mean) * ((F64)value - mMean);
+ mLastValue = value;
+ }
- LL_FORCE_INLINE void sample(T value)
+ void addSamples(const self_t& other)
+ {
+ if (other.mNumSamples)
{
- T storage_value(value);
- mNumSamples++;
- mSum += storage_value;
- if (storage_value < mMin)
+ mSum += other.mSum;
+ if (other.mMin < mMin)
{
- mMin = storage_value;
+ mMin = other.mMin;
}
- if (storage_value > mMax)
+ if (other.mMax > mMax)
{
- mMax = storage_value;
+ mMax = other.mMax;
}
- F64 old_mean = mMean;
- mMean += ((F64)storage_value - old_mean) / (F64)mNumSamples;
- mVarianceSum += ((F64)storage_value - old_mean) * ((F64)storage_value - mMean);
- mLastValue = storage_value;
- }
-
- void addSamples(const self_t& other)
- {
- if (other.mNumSamples)
+ F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples);
+ mNumSamples += other.mNumSamples;
+ mMean = mMean * weight + other.mMean * (1.f - weight);
+
+ // combine variance (and hence standard deviation) of 2 different sized sample groups using
+ // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
+ F64 n_1 = (F64)mNumSamples,
+ n_2 = (F64)other.mNumSamples;
+ F64 m_1 = mMean,
+ m_2 = other.mMean;
+ F64 v_1 = mVarianceSum / mNumSamples,
+ v_2 = other.mVarianceSum / other.mNumSamples;
+ if (n_1 == 0)
+ {
+ mVarianceSum = other.mVarianceSum;
+ }
+ else if (n_2 == 0)
+ {
+ // don't touch variance
+ // mVarianceSum = mVarianceSum;
+ }
+ else
{
- mSum += other.mSum;
- if (other.mMin < mMin)
- {
- mMin = other.mMin;
- }
- if (other.mMax > mMax)
- {
- mMax = other.mMax;
- }
- F64 weight = (F64)mNumSamples / (F64)(mNumSamples + other.mNumSamples);
- mNumSamples += other.mNumSamples;
- mMean = mMean * weight + other.mMean * (1.f - weight);
-
- // combine variance (and hence standard deviation) of 2 different sized sample groups using
- // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
- F64 n_1 = (F64)mNumSamples,
- n_2 = (F64)other.mNumSamples;
- F64 m_1 = mMean,
- m_2 = other.mMean;
- F64 sd_1 = getStandardDeviation(),
- sd_2 = other.getStandardDeviation();
- if (n_1 == 0)
- {
- mVarianceSum = other.mVarianceSum;
- }
- else if (n_2 == 0)
- {
- // don't touch variance
- // mVarianceSum = mVarianceSum;
- }
- else
- {
- mVarianceSum = (F64)mNumSamples
- * ((((n_1 - 1.f) * sd_1 * sd_1)
- + ((n_2 - 1.f) * sd_2 * sd_2)
- + (((n_1 * n_2) / (n_1 + n_2))
- * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2))))
- / (n_1 + n_2 - 1.f));
- }
- mLastValue = other.mLastValue;
+ mVarianceSum = (F64)mNumSamples
+ * ((((n_1 - 1.f) * v_1)
+ + ((n_2 - 1.f) * v_2)
+ + (((n_1 * n_2) / (n_1 + n_2))
+ * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2))))
+ / (n_1 + n_2 - 1.f));
}
+ mLastValue = other.mLastValue;
}
+ }
- void reset(const self_t* other)
- {
- mNumSamples = 0;
- mSum = 0;
- mMin = 0;
- mMax = 0;
- mMean = 0;
- mVarianceSum = 0;
- mLastValue = other ? other->mLastValue : 0;
- }
+ void reset(const self_t* other)
+ {
+ mNumSamples = 0;
+ mSum = 0;
+ mMin = 0;
+ mMax = 0;
+ mMean = 0;
+ mVarianceSum = 0;
+ mLastValue = other ? other->mLastValue : 0;
+ }
+
+ T getSum() const { return (T)mSum; }
+ T getMin() const { return (T)mMin; }
+ T getMax() const { return (T)mMax; }
+ T getLastValue() const { return (T)mLastValue; }
+ F64 getMean() const { return mMean; }
+ F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); }
+ U32 getSampleCount() const { return mNumSamples; }
- T getSum() const { return (T)mSum; }
- T getMin() const { return (T)mMin; }
- T getMax() const { return (T)mMax; }
- T getLastValue() const { return (T)mLastValue; }
- F64 getMean() const { return mMean; }
- F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); }
- U32 getSampleCount() const { return mNumSamples; }
+private:
+ T mSum,
+ mMin,
+ mMax,
+ mLastValue;
- private:
- T mSum,
- mMin,
- mMax,
- mLastValue;
+ F64 mMean,
+ mVarianceSum;
- F64 mMean,
- mVarianceSum;
+ U32 mNumSamples;
+};
- U32 mNumSamples;
- };
+template<typename T>
+class CountAccumulator
+{
+public:
+ typedef CountAccumulator<T> self_t;
+ typedef T value_t;
- template<typename T>
- class CountAccumulator
+ CountAccumulator()
+ : mSum(0),
+ mNumSamples(0)
+ {}
+
+ void add(T value)
{
- public:
- typedef CountAccumulator<T> self_t;
- typedef T value_t;
+ mNumSamples++;
+ mSum += value;
+ }
- CountAccumulator()
- : mSum(0),
- mNumSamples(0)
- {}
+ void addSamples(const CountAccumulator<T>& other)
+ {
+ mSum += other.mSum;
+ mNumSamples += other.mNumSamples;
+ }
- LL_FORCE_INLINE void add(T value)
- {
- mNumSamples++;
- mSum += value;
- }
+ void reset(const self_t* other)
+ {
+ mNumSamples = 0;
+ mSum = 0;
+ }
- void addSamples(const CountAccumulator<T>& other)
- {
- mSum += other.mSum;
- mNumSamples += other.mNumSamples;
- }
+ T getSum() const { return (T)mSum; }
- void reset(const self_t* other)
- {
- mNumSamples = 0;
- mSum = 0;
- }
+ U32 getSampleCount() const { return mNumSamples; }
- T getSum() const { return (T)mSum; }
+private:
+ T mSum;
- U32 getSampleCount() const { return mNumSamples; }
+ U32 mNumSamples;
+};
- private:
- T mSum;
+class TimeBlockAccumulator
+{
+public:
+ typedef LLUnit<LLUnits::Seconds, F64> value_t;
+ typedef TimeBlockAccumulator self_t;
- U32 mNumSamples;
+ // fake class that allows us to view call count aspect of timeblock accumulator
+ struct CallCountAspect
+ {
+ typedef U32 value_t;
};
- class TimeBlockAccumulator
+ struct SelfTimeAspect
{
- public:
typedef LLUnit<LLUnits::Seconds, F64> value_t;
- typedef TimeBlockAccumulator self_t;
+ };
- // fake class that allows us to view call count aspect of timeblock accumulator
- struct CallCountAspect
- {
- typedef U32 value_t;
- };
+ TimeBlockAccumulator();
+ void addSamples(const self_t& other);
+ void reset(const self_t* other);
+
+ //
+ // members
+ //
+ U64 mStartTotalTimeCounter,
+ mTotalTimeCounter,
+ mSelfTimeCounter;
+ U32 mCalls;
+ class TimeBlock* mParent; // last acknowledged parent of this time block
+ class TimeBlock* mLastCaller; // used to bootstrap tree construction
+ U16 mActiveCount; // number of timers with this ID active on stack
+ bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
- struct SelfTimeAspect
- {
- typedef LLUnit<LLUnits::Seconds, F64> value_t;
- };
-
- TimeBlockAccumulator();
- void addSamples(const self_t& other);
- void reset(const self_t* other);
-
- //
- // members
- //
- U64 mChildTimeCounter,
- mTotalTimeCounter;
- U32 mCalls;
- class TimeBlock* mParent; // last acknowledged parent of this time block
- class TimeBlock* mLastCaller; // used to bootstrap tree construction
- U16 mActiveCount; // number of timers with this ID active on stack
- bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
+};
- };
+template<>
+struct MeanValueType<TraceType<TimeBlockAccumulator> >
+{
+ typedef LLUnit<LLUnits::Seconds, F64> type;
+};
+
+template<>
+class TraceType<TimeBlockAccumulator::CallCountAspect>
+: public TraceType<TimeBlockAccumulator>
+{
+public:
+
+ TraceType(const char* name, const char* description = "")
+ : TraceType<TimeBlockAccumulator>(name, description)
+ {}
+};
+
+template<>
+struct MeanValueType<TraceType<TimeBlockAccumulator::CallCountAspect> >
+{
+ typedef F64 type;
+};
- template<>
- struct MeanValueType<TraceType<TimeBlockAccumulator> >
- {
- typedef LLUnit<LLUnits::Seconds, F64> type;
- };
- template<>
- class TraceType<TimeBlockAccumulator::CallCountAspect>
+template<>
+class TraceType<TimeBlockAccumulator::SelfTimeAspect>
: public TraceType<TimeBlockAccumulator>
- {
- public:
- typedef F32 mean_t;
+{
+public:
- TraceType(const char* name, const char* description = "")
+ TraceType(const char* name, const char* description = "")
: TraceType<TimeBlockAccumulator>(name, description)
- {}
- };
+ {}
+};
- template<>
- class TraceType<TimeBlockAccumulator::SelfTimeAspect>
- : public TraceType<TimeBlockAccumulator>
- {
- public:
- typedef F32 mean_t;
+template<>
+struct MeanValueType<TraceType<TimeBlockAccumulator::SelfTimeAspect> >
+{
+ typedef LLUnit<LLUnits::Seconds, F64> type;
+};
- TraceType(const char* name, const char* description = "")
- : TraceType<TimeBlockAccumulator>(name, description)
- {}
- };
- class TimeBlock;
- class TimeBlockTreeNode
- {
- public:
- TimeBlockTreeNode();
+class TimeBlock;
+class TimeBlockTreeNode
+{
+public:
+ TimeBlockTreeNode();
- void setParent(TimeBlock* parent);
- TimeBlock* getParent() { return mParent; }
+ void setParent(TimeBlock* parent);
+ TimeBlock* getParent() { return mParent; }
- TimeBlock* mBlock;
- TimeBlock* mParent;
- std::vector<TimeBlock*> mChildren;
- bool mNeedsSorting;
- };
+ TimeBlock* mBlock;
+ TimeBlock* mParent;
+ std::vector<TimeBlock*> mChildren;
+ bool mNeedsSorting;
+};
- template <typename T = F64>
- class Measurement
- : public TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >
- {
- public:
- typedef typename LLUnits::HighestPrecisionType<T>::type_t storage_t;
- typedef TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> > trace_t;
+template <typename T = F64>
+class MeasurementStatHandle
+: public TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >
+{
+public:
+ typedef typename LLUnits::HighestPrecisionType<T>::type_t storage_t;
+ typedef TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> > trace_t;
- Measurement(const char* name, const char* description = NULL)
- : trace_t(name, description)
- {}
+ MeasurementStatHandle(const char* name, const char* description = NULL)
+ : trace_t(name, description)
+ {}
+};
- template<typename UNIT_T>
- void sample(UNIT_T value)
- {
- T converted_value(value);
- trace_t::getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value));
- }
- };
+template<typename T, typename VALUE_T>
+void sample(MeasurementStatHandle<T>& measurement, VALUE_T value)
+{
+ T converted_value(value);
+ measurement.getPrimaryAccumulator()->sample(LLUnits::rawValue(converted_value));
+}
- template <typename T = F64>
- class Count
- : public TraceType<CountAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >
- {
- public:
- typedef typename LLUnits::HighestPrecisionType<T>::type_t storage_t;
- typedef TraceType<CountAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> > trace_t;
- Count(const char* name, const char* description = NULL)
- : trace_t(name)
- {}
+template <typename T = F64>
+class CountStatHandle
+: public TraceType<CountAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >
+{
+public:
+ typedef typename LLUnits::HighestPrecisionType<T>::type_t storage_t;
+ typedef TraceType<CountAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> > trace_t;
+
+ CountStatHandle(const char* name, const char* description = NULL)
+ : trace_t(name)
+ {}
+
+};
+
+template<typename T, typename VALUE_T>
+void add(CountStatHandle<T>& count, VALUE_T value)
+{
+ T converted_value(value);
+ count.getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value));
+}
- template<typename UNIT_T>
- void add(UNIT_T value)
- {
- T converted_value(value);
- trace_t::getPrimaryAccumulator()->add(LLUnits::rawValue(converted_value));
- }
- };
struct MemStatAccumulator
{
@@ -574,11 +587,11 @@ struct MemStatAccumulator
mDeallocatedCount;
};
-class MemStat : public TraceType<MemStatAccumulator>
+class MemStatHandle : public TraceType<MemStatAccumulator>
{
public:
typedef TraceType<MemStatAccumulator> trace_t;
- MemStat(const char* name)
+ MemStatHandle(const char* name)
: trace_t(name)
{}
};
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 913c4cbdad..ab8dbce2ce 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -109,9 +109,17 @@ void Recording::handleSplitTo(Recording& other)
{
stop();
other.restart();
+ syncTo(other);
+}
+
+void Recording::syncTo(Recording& other)
+{
+ other.mCountsFloat.write()->reset(mCountsFloat);
other.mMeasurementsFloat.write()->reset(mMeasurementsFloat);
+ other.mCounts.write()->reset(mCounts);
other.mMeasurements.write()->reset(mMeasurements);
- //TODO: figure out how to get seamless handoff of timing stats
+ other.mStackTimers.write()->reset(mStackTimers);
+ other.mMemStats.write()->reset(mMemStats);
}
void Recording::makePrimary()
@@ -174,12 +182,15 @@ void Recording::mergeRecording( const Recording& other)
LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator>& stat) const
{
- return (F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter / (F64)LLTrace::TimeBlock::countsPerSecond();
+ const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()];
+ return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter)
+ / (F64)LLTrace::TimeBlock::countsPerSecond();
}
LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const
{
- return ((F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter - (F64)(*mStackTimers)[stat.getIndex()].mChildTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond();
+ const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()];
+ return (F64)(accumulator.mSelfTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond();
}
@@ -190,12 +201,18 @@ U32 Recording::getSum(const TraceType<TimeBlockAccumulator::CallCountAspect>& st
LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator>& stat) const
{
- return (F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);
+ const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()];
+
+ return (F64)(accumulator.mTotalTimeCounter - accumulator.mStartTotalTimeCounter)
+ / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);
}
LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const
{
- return ((F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter - (F64)(*mStackTimers)[stat.getIndex()].mChildTimeCounter) / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);
+ const TimeBlockAccumulator& accumulator = (*mStackTimers)[stat.getIndex()];
+
+ return (F64)(accumulator.mSelfTimeCounter)
+ / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds);
}
F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat) const
@@ -520,7 +537,7 @@ void ExtendableRecording::splitFrom(ExtendableRecording& other)
PeriodicRecording& get_frame_recording()
{
- static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(64, PeriodicRecording::STARTED));
+ static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED));
return *sRecording;
}
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 05e1577a5a..7a0266529b 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -119,6 +119,7 @@ namespace LLTrace
// gather data from recording, ignoring time relationship (for example, pulling data from slave threads)
void mergeRecording(const Recording& other);
+ // grab latest recorded data
void update();
// Timer accessors
@@ -134,11 +135,11 @@ namespace LLTrace
LLUnit<LLUnits::Bytes, U32> getSum(const TraceType<MemStatAccumulator>& stat) const;
LLUnit<LLUnits::Bytes, F32> getPerSec(const TraceType<MemStatAccumulator>& stat) const;
- // Count accessors
+ // CountStatHandle accessors
F64 getSum(const TraceType<CountAccumulator<F64> >& stat) const;
S64 getSum(const TraceType<CountAccumulator<S64> >& stat) const;
template <typename T>
- T getSum(const Count<T>& stat) const
+ T getSum(const CountStatHandle<T>& stat) const
{
return (T)getSum(static_cast<const TraceType<CountAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
}
@@ -146,7 +147,7 @@ namespace LLTrace
F64 getPerSec(const TraceType<CountAccumulator<F64> >& stat) const;
F64 getPerSec(const TraceType<CountAccumulator<S64> >& stat) const;
template <typename T>
- T getPerSec(const Count<T>& stat) const
+ T getPerSec(const CountStatHandle<T>& stat) const
{
return (T)getPerSec(static_cast<const TraceType<CountAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
}
@@ -155,11 +156,11 @@ namespace LLTrace
U32 getSampleCount(const TraceType<CountAccumulator<S64> >& stat) const;
- // Measurement accessors
+ // MeasurementStatHandle accessors
F64 getSum(const TraceType<MeasurementAccumulator<F64> >& stat) const;
S64 getSum(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getSum(const Measurement<T>& stat) const
+ T getSum(const MeasurementStatHandle<T>& stat) const
{
return (T)getSum(static_cast<const TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
}
@@ -167,7 +168,7 @@ namespace LLTrace
F64 getPerSec(const TraceType<MeasurementAccumulator<F64> >& stat) const;
F64 getPerSec(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getPerSec(const Measurement<T>& stat) const
+ T getPerSec(const MeasurementStatHandle<T>& stat) const
{
return (T)getPerSec(static_cast<const TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
}
@@ -175,7 +176,7 @@ namespace LLTrace
F64 getMin(const TraceType<MeasurementAccumulator<F64> >& stat) const;
S64 getMin(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getMin(const Measurement<T>& stat) const
+ T getMin(const MeasurementStatHandle<T>& stat) const
{
return (T)getMin(static_cast<const TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
}
@@ -183,7 +184,7 @@ namespace LLTrace
F64 getMax(const TraceType<MeasurementAccumulator<F64> >& stat) const;
S64 getMax(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getMax(const Measurement<T>& stat) const
+ T getMax(const MeasurementStatHandle<T>& stat) const
{
return (T)getMax(static_cast<const TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
}
@@ -191,7 +192,7 @@ namespace LLTrace
F64 getMean(const TraceType<MeasurementAccumulator<F64> >& stat) const;
F64 getMean(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getMean(Measurement<T>& stat) const
+ T getMean(MeasurementStatHandle<T>& stat) const
{
return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
}
@@ -199,7 +200,7 @@ namespace LLTrace
F64 getStandardDeviation(const TraceType<MeasurementAccumulator<F64> >& stat) const;
F64 getStandardDeviation(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getStandardDeviation(const Measurement<T>& stat) const
+ T getStandardDeviation(const MeasurementStatHandle<T>& stat) const
{
return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
}
@@ -207,7 +208,7 @@ namespace LLTrace
F64 getLastValue(const TraceType<MeasurementAccumulator<F64> >& stat) const;
S64 getLastValue(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getLastValue(const Measurement<T>& stat) const
+ T getLastValue(const MeasurementStatHandle<T>& stat) const
{
return (T)getLastValue(static_cast<const TraceType<MeasurementAccumulator<typename LLUnits::HighestPrecisionType<T>::type_t> >&> (stat));
}
@@ -217,6 +218,8 @@ namespace LLTrace
LLUnit<LLUnits::Seconds, F64> getDuration() const { return LLUnit<LLUnits::Seconds, F64>(mElapsedSeconds); }
+ void syncTo(Recording& other);
+
private:
friend class ThreadRecorder;
@@ -337,9 +340,9 @@ namespace LLTrace
}
template <typename T>
- typename TraceType<T>::mean_t getPeriodMean(const TraceType<T>& stat) const
+ typename MeanValueType<TraceType<T> >::type getPeriodMean(const TraceType<T>& stat) const
{
- typename TraceType<T>::mean_t mean = 0.0;
+ typename MeanValueType<TraceType<T> >::type mean = 0.0;
for (S32 i = 0; i < mNumPeriods; i++)
{
if (mRecordingPeriods[i].getDuration() > 0.f)
@@ -352,9 +355,9 @@ namespace LLTrace
}
template <typename T>
- typename TraceType<T>::mean_t getPeriodMeanPerSec(const TraceType<T>& stat) const
+ typename MeanValueType<TraceType<T> >::type getPeriodMeanPerSec(const TraceType<T>& stat) const
{
- typename TraceType<T>::mean_t mean = 0.0;
+ typename MeanValueType<TraceType<T> >::type mean = 0.0;
for (S32 i = 0; i < mNumPeriods; i++)
{
if (mRecordingPeriods[i].getDuration() > 0.f)
@@ -391,6 +394,7 @@ namespace LLTrace
{
public:
void extend();
+
Recording& getAcceptedRecording() { return mAcceptedRecording; }
// implementation for LLStopWatchControlsMixin
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 7b493a651e..113febcca8 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -76,7 +76,7 @@ ThreadRecorder::~ThreadRecorder()
while(mActiveRecordings.size())
{
- mActiveRecordings.front().mTargetRecording->stop();
+ mActiveRecordings.front()->mTargetRecording->stop();
}
set_thread_recorder(NULL);
delete[] mTimeBlockTreeNodes;
@@ -94,31 +94,37 @@ TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index)
void ThreadRecorder::activate( Recording* recording )
{
- mActiveRecordings.push_front(ActiveRecording(recording));
- mActiveRecordings.front().mBaseline.makePrimary();
+ ActiveRecording* active_recording = new ActiveRecording(recording);
+ if (!mActiveRecordings.empty())
+ {
+ mActiveRecordings.front()->mBaseline.syncTo(active_recording->mBaseline);
+ }
+ mActiveRecordings.push_front(active_recording);
+
+ mActiveRecordings.front()->mBaseline.makePrimary();
}
-std::list<ThreadRecorder::ActiveRecording>::iterator ThreadRecorder::update( Recording* recording )
+ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Recording* recording )
{
- std::list<ActiveRecording>::iterator it, end_it;
+ active_recording_list_t::iterator it, end_it;
for (it = mActiveRecordings.begin(), end_it = mActiveRecordings.end();
it != end_it;
++it)
{
- std::list<ActiveRecording>::iterator next_it = it;
+ active_recording_list_t::iterator next_it = it;
++next_it;
// if we have another recording further down in the stack...
if (next_it != mActiveRecordings.end())
{
// ...push our gathered data down to it
- next_it->mBaseline.appendRecording(it->mBaseline);
+ (*next_it)->mBaseline.appendRecording((*it)->mBaseline);
}
// copy accumulated measurements into result buffer and clear accumulator (mBaseline)
- it->moveBaselineToTarget();
+ (*it)->moveBaselineToTarget();
- if (it->mTargetRecording == recording)
+ if ((*it)->mTargetRecording == recording)
{
// found the recording, so return it
break;
@@ -142,17 +148,18 @@ AccumulatorBuffer<MemStatAccumulator> gMemStats;
void ThreadRecorder::deactivate( Recording* recording )
{
- std::list<ActiveRecording>::iterator it = update(recording);
+ active_recording_list_t::iterator it = update(recording);
if (it != mActiveRecordings.end())
{
// and if we've found the recording we wanted to update
- std::list<ActiveRecording>::iterator next_it = it;
+ active_recording_list_t::iterator next_it = it;
++next_it;
if (next_it != mActiveRecordings.end())
{
- next_it->mTargetRecording->makePrimary();
+ (*next_it)->mTargetRecording->makePrimary();
}
+ delete *it;
mActiveRecordings.erase(it);
}
}
@@ -244,7 +251,7 @@ void MasterThreadRecorder::pullFromSlaveThreads()
LLMutexLock lock(&mSlaveListMutex);
- Recording& target_recording = mActiveRecordings.front().mBaseline;
+ Recording& target_recording = mActiveRecordings.front()->mBaseline;
for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end();
it != end_it;
++it)
diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h
index 337035974c..0e6c091900 100644
--- a/indra/llcommon/lltracethreadrecorder.h
+++ b/indra/llcommon/lltracethreadrecorder.h
@@ -39,13 +39,14 @@ namespace LLTrace
{
protected:
struct ActiveRecording;
+ typedef std::list<ActiveRecording*> active_recording_list_t;
public:
ThreadRecorder();
virtual ~ThreadRecorder();
void activate(Recording* recording);
- std::list<struct ActiveRecording>::iterator update(Recording* recording);
+ active_recording_list_t::iterator update(Recording* recording);
void deactivate(Recording* recording);
virtual void pushToMaster() = 0;
@@ -63,11 +64,12 @@ namespace LLTrace
void moveBaselineToTarget();
};
Recording mThreadRecording;
- std::list<ActiveRecording> mActiveRecordings;
- class BlockTimer* mRootTimer;
- TimeBlockTreeNode* mTimeBlockTreeNodes;
- size_t mNumTimeBlockTreeNodes;
+ active_recording_list_t mActiveRecordings;
+
+ class BlockTimer* mRootTimer;
+ TimeBlockTreeNode* mTimeBlockTreeNodes;
+ size_t mNumTimeBlockTreeNodes;
};
class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index c2a31b7604..823550db5d 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -106,11 +106,12 @@ struct LLUnit
return mValue;
}
- template<typename NEW_UNIT_TYPE, typename NEW_STORAGE_TYPE> LLUnit<NEW_UNIT_TYPE, NEW_STORAGE_TYPE> as()
+ template<typename NEW_UNIT_TYPE> LLUnit<NEW_UNIT_TYPE, STORAGE_TYPE> as()
{
- return LLUnit<NEW_UNIT_TYPE, NEW_STORAGE_TYPE>(*this);
+ return LLUnit<NEW_UNIT_TYPE, STORAGE_TYPE>(*this);
}
+
void operator += (storage_t value)
{
mValue += value;