summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorRichard Linden <none@none>2012-11-01 00:32:45 -0700
committerRichard Linden <none@none>2012-11-01 00:32:45 -0700
commit3ccbce90e37b92d5b32a2507804adc91bc58065d (patch)
tree519ae7f820bc8adde6617736c9d35c82c152705b /indra/llcommon
parentb71e991c1860bbea0387f9434cc2b4b31a26469a (diff)
parent819adb5eb4d7f982121f3dbd82750e05d26864d9 (diff)
Automated merge with ssh://hg.lindenlab.com/richard/viewer-interesting-metrics
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/llinstancetracker.h10
-rw-r--r--indra/llcommon/llmetricperformancetester.cpp1
-rw-r--r--indra/llcommon/llstat.cpp352
-rw-r--r--indra/llcommon/llstat.h103
-rw-r--r--indra/llcommon/lltrace.h90
-rw-r--r--indra/llcommon/lltracerecording.cpp119
-rw-r--r--indra/llcommon/lltracerecording.h216
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp4
9 files changed, 315 insertions, 582 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index d876842cf1..0f5ded86ed 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -91,7 +91,6 @@ set(llcommon_SOURCE_FILES
llsdutil.cpp
llsecondlifeurls.cpp
llsingleton.cpp
- llstat.cpp
llstacktrace.cpp
llstreamqueue.cpp
llstreamtools.cpp
@@ -234,7 +233,6 @@ set(llcommon_HEADER_FILES
llsortedvector.h
llstack.h
llstacktrace.h
- llstat.h
llstatenums.h
llstl.h
llstreamqueue.h
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 403df08990..3a1187a4c1 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -77,8 +77,8 @@ protected:
/// This mix-in class adds support for tracking all instances of the specified class parameter T
/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
/// If KEY is not provided, then instances are stored in a simple set
-/// @NOTE: see explicit specialization below for default KEY==T* case
-template<typename T, typename KEY = T*>
+/// @NOTE: see explicit specialization below for default KEY==void case
+template<typename T, typename KEY = void>
class LLInstanceTracker : public LLInstanceTrackerBase
{
typedef LLInstanceTracker<T, KEY> MyT;
@@ -224,12 +224,12 @@ private:
KEY mInstanceKey;
};
-/// explicit specialization for default case where KEY is T*
+/// explicit specialization for default case where KEY is void
/// use a simple std::set<T*>
template<typename T>
-class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
+class LLInstanceTracker<T, void> : public LLInstanceTrackerBase
{
- typedef LLInstanceTracker<T, T*> MyT;
+ typedef LLInstanceTracker<T, void> MyT;
typedef typename std::set<T*> InstanceSet;
struct StaticData: public StaticBase
{
diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp
index 41d3eb0bf3..a1b0a684c5 100644
--- a/indra/llcommon/llmetricperformancetester.cpp
+++ b/indra/llcommon/llmetricperformancetester.cpp
@@ -29,7 +29,6 @@
#include "indra_constants.h"
#include "llerror.h"
#include "llsdserialize.h"
-#include "llstat.h"
#include "lltreeiterators.h"
#include "llmetricperformancetester.h"
diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp
deleted file mode 100644
index b46d2e58b2..0000000000
--- a/indra/llcommon/llstat.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-/**
- * @file llstat.cpp
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "llstat.h"
-#include "lllivefile.h"
-#include "llerrorcontrol.h"
-#include "llframetimer.h"
-#include "timing.h"
-#include "llsd.h"
-#include "llsdserialize.h"
-#include "llstl.h"
-#include "u64.h"
-
-
-// statics
-//------------------------------------------------------------------------
-LLTimer LLStat::sTimer;
-LLFrameTimer LLStat::sFrameTimer;
-
-void LLStat::reset()
-{
- mNumValues = 0;
- mLastValue = 0.f;
- delete[] mBins;
- mBins = new ValueEntry[mNumBins];
- mCurBin = mNumBins-1;
- mNextBin = 0;
-}
-
-LLStat::LLStat(std::string name, BOOL use_frame_timer)
-: LLInstanceTracker<LLStat, std::string>(name),
- mUseFrameTimer(use_frame_timer),
- mNumBins(50),
- mName(name),
- mBins(NULL)
-{
- llassert(mNumBins > 0);
- mLastTime = 0.f;
-
- reset();
-}
-
-LLStat::~LLStat()
-{
- delete[] mBins;
-}
-//
-//void LLStat::start()
-//{
-// if (mUseFrameTimer)
-// {
-// mBins[mNextBin].mBeginTime = sFrameTimer.getElapsedSeconds();
-// }
-// else
-// {
-// mBins[mNextBin].mBeginTime = sTimer.getElapsedTimeF64();
-// }
-//}
-
-void LLStat::addValue(const F32 value)
-{
- if (mNumValues < mNumBins)
- {
- mNumValues++;
- }
-
- // Increment the bin counters.
- mCurBin++;
- if (mCurBin >= mNumBins)
- {
- mCurBin = 0;
- }
- mNextBin++;
- if (mNextBin >= mNumBins)
- {
- mNextBin = 0;
- }
-
- mBins[mCurBin].mValue = value;
- if (mUseFrameTimer)
- {
- mBins[mCurBin].mTime = sFrameTimer.getElapsedSeconds();
- }
- else
- {
- mBins[mCurBin].mTime = sTimer.getElapsedTimeF64();
- }
- mBins[mCurBin].mDT = (F32)(mBins[mCurBin].mTime - mBins[mCurBin].mBeginTime);
-
- //this value is used to prime the min/max calls
- mLastTime = mBins[mCurBin].mTime;
- mLastValue = value;
-
- // Set the begin time for the next stat segment.
- mBins[mNextBin].mBeginTime = mBins[mCurBin].mTime;
- mBins[mNextBin].mTime = mBins[mCurBin].mTime;
- mBins[mNextBin].mDT = 0.f;
-}
-
-
-F32 LLStat::getMax() const
-{
- S32 i;
- F32 current_max = mLastValue;
- if (mNumBins == 0)
- {
- current_max = 0.f;
- }
- else
- {
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- if (mBins[i].mValue > current_max)
- {
- current_max = mBins[i].mValue;
- }
- }
- }
- return current_max;
-}
-
-F32 LLStat::getMean() const
-{
- S32 i;
- F32 current_mean = 0.f;
- S32 samples = 0;
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- current_mean += mBins[i].mValue;
- samples++;
- }
-
- // There will be a wrap error at 2^32. :)
- if (samples != 0)
- {
- current_mean /= samples;
- }
- else
- {
- current_mean = 0.f;
- }
- return current_mean;
-}
-
-F32 LLStat::getMin() const
-{
- S32 i;
- F32 current_min = mLastValue;
-
- if (mNumBins == 0)
- {
- current_min = 0.f;
- }
- else
- {
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- if (mBins[i].mValue < current_min)
- {
- current_min = mBins[i].mValue;
- }
- }
- }
- return current_min;
-}
-
-F32 LLStat::getPrev(S32 age) const
-{
- S32 bin;
- bin = mCurBin - age;
-
- while (bin < 0)
- {
- bin += mNumBins;
- }
-
- if (bin == mNextBin)
- {
- // Bogus for bin we're currently working on.
- return 0.f;
- }
- return mBins[bin].mValue;
-}
-
-F32 LLStat::getPrevPerSec(S32 age) const
-{
- S32 bin;
- bin = mCurBin - age;
-
- while (bin < 0)
- {
- bin += mNumBins;
- }
-
- if (bin == mNextBin)
- {
- // Bogus for bin we're currently working on.
- return 0.f;
- }
- return mBins[bin].mValue / mBins[bin].mDT;
-}
-
-F32 LLStat::getCurrent() const
-{
- return mBins[mCurBin].mValue;
-}
-
-F32 LLStat::getCurrentPerSec() const
-{
- return mBins[mCurBin].mValue / mBins[mCurBin].mDT;
-}
-
-F32 LLStat::getMeanPerSec() const
-{
- S32 i;
- F32 value = 0.f;
- F32 dt = 0.f;
-
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- value += mBins[i].mValue;
- dt += mBins[i].mDT;
- }
-
- if (dt > 0.f)
- {
- return value/dt;
- }
- else
- {
- return 0.f;
- }
-}
-
-F32 LLStat::getMaxPerSec() const
-{
- F32 value;
-
- if (mNextBin != 0)
- {
- value = mBins[0].mValue/mBins[0].mDT;
- }
- else if (mNumValues > 0)
- {
- value = mBins[1].mValue/mBins[1].mDT;
- }
- else
- {
- value = 0.f;
- }
-
- for (S32 i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- value = llmax(value, mBins[i].mValue/mBins[i].mDT);
- }
- return value;
-}
-
-F32 LLStat::getMinPerSec() const
-{
- S32 i;
- F32 value;
-
- if (mNextBin != 0)
- {
- value = mBins[0].mValue/mBins[0].mDT;
- }
- else if (mNumValues > 0)
- {
- value = mBins[1].mValue/mBins[0].mDT;
- }
- else
- {
- value = 0.f;
- }
-
- for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
- {
- // Skip the bin we're currently filling.
- if (i == mNextBin)
- {
- continue;
- }
- value = llmin(value, mBins[i].mValue/mBins[i].mDT);
- }
- return value;
-}
-
-U32 LLStat::getNumValues() const
-{
- return mNumValues;
-}
-
-S32 LLStat::getNumBins() const
-{
- return mNumBins;
-}
-
-S32 LLStat::getNextBin() const
-{
- return mNextBin;
-}
-
diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h
deleted file mode 100644
index 82a246275d..0000000000
--- a/indra/llcommon/llstat.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/**
- * @file llstat.h
- * @brief Runtime statistics accumulation.
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLSTAT_H
-#define LL_LLSTAT_H
-
-#include <map>
-
-#include "lltimer.h"
-#include "llframetimer.h"
-#include "llinstancetracker.h"
-
-class LLSD;
-
-// ----------------------------------------------------------------------------
-class LL_COMMON_API LLStat : public LLInstanceTracker<LLStat, std::string>
-{
-public:
- LLStat(std::string name = std::string(), BOOL use_frame_timer = FALSE);
- ~LLStat();
-
- //void start(); // Start the timer for the current "frame", otherwise uses the time tracked from
- // the last addValue
- void reset();
- void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT.
- void addValue(const S32 value) { addValue((F32)value); }
- void addValue(const U32 value) { addValue((F32)value); }
-
- S32 getNextBin() const;
-
- F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current
- F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current
-
- F32 getCurrent() const;
- F32 getCurrentPerSec() const;
-
- F32 getMin() const;
- F32 getMinPerSec() const;
-
- F32 getMean() const;
- F32 getMeanPerSec() const;
-
- F32 getMax() const;
- F32 getMaxPerSec() const;
-
- U32 getNumValues() const;
- S32 getNumBins() const;
-
-private:
- bool mUseFrameTimer;
- U32 mNumValues;
- U32 mNumBins;
- F32 mLastValue;
- F64 mLastTime;
-
- struct ValueEntry
- {
- ValueEntry()
- : mValue(0.f),
- mBeginTime(0.0),
- mTime(0.0),
- mDT(0.f)
- {}
- F32 mValue;
- F64 mBeginTime;
- F64 mTime;
- F32 mDT;
- };
- ValueEntry* mBins;
-
- S32 mCurBin;
- S32 mNextBin;
-
- std::string mName;
-
- static LLTimer sTimer;
- static LLFrameTimer sFrameTimer;
-};
-
-#endif // LL_STAT_
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 2cdae4b0d2..2823db5cbb 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -227,10 +227,33 @@ namespace LLTrace
};
+ template<typename T, typename IS_UNIT = void>
+ struct StorageType
+ {
+ typedef T type_t;
+ };
+
+ template<typename T>
+ struct StorageType<T, typename T::is_unit_tag_t>
+ {
+ typedef typename StorageType<typename T::storage_t>::type_t type_t;
+ };
+
+ template<> struct StorageType<F32> { typedef F64 type_t; };
+ template<> struct StorageType<S32> { typedef S64 type_t; };
+ template<> struct StorageType<U32> { typedef S64 type_t; };
+ template<> struct StorageType<S16> { typedef S64 type_t; };
+ template<> struct StorageType<U16> { typedef S64 type_t; };
+ template<> struct StorageType<S8> { typedef S64 type_t; };
+ template<> struct StorageType<U8> { typedef S64 type_t; };
+
template<typename T>
class LL_COMMON_API MeasurementAccumulator
{
public:
+ typedef T value_t;
+ typedef MeasurementAccumulator<T> self_t;
+
MeasurementAccumulator()
: mSum(0),
mMin(std::numeric_limits<T>::max()),
@@ -243,23 +266,24 @@ namespace LLTrace
LL_FORCE_INLINE void sample(T value)
{
+ T storage_value(value);
mNumSamples++;
- mSum += value;
- if (value < mMin)
+ mSum += storage_value;
+ if (storage_value < mMin)
{
- mMin = value;
+ mMin = storage_value;
}
- else if (value > mMax)
+ if (storage_value > mMax)
{
- mMax = value;
+ mMax = storage_value;
}
F64 old_mean = mMean;
- mMean += ((F64)value - old_mean) / (F64)mNumSamples;
- mVarianceSum += ((F64)value - old_mean) * ((F64)value - mMean);
- mLastValue = value;
+ mMean += ((F64)storage_value - old_mean) / (F64)mNumSamples;
+ mVarianceSum += ((F64)storage_value - old_mean) * ((F64)storage_value - mMean);
+ mLastValue = storage_value;
}
- void addSamples(const MeasurementAccumulator<T>& other)
+ void addSamples(const self_t& other)
{
mSum += other.mSum;
if (other.mMin < mMin)
@@ -293,7 +317,7 @@ namespace LLTrace
}
else
{
- mVarianceSum = (F32)mNumSamples
+ 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))
@@ -311,10 +335,10 @@ namespace LLTrace
mMax = 0;
}
- T getSum() const { return mSum; }
- T getMin() const { return mMin; }
- T getMax() const { return mMax; }
- T getLastValue() const { return mLastValue; }
+ 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; }
@@ -325,7 +349,7 @@ namespace LLTrace
mMax,
mLastValue;
- F64 mMean,
+ F64 mMean,
mVarianceSum;
U32 mNumSamples;
@@ -335,6 +359,8 @@ namespace LLTrace
class LL_COMMON_API CountAccumulator
{
public:
+ typedef T value_t;
+
CountAccumulator()
: mSum(0),
mNumSamples(0)
@@ -358,7 +384,7 @@ namespace LLTrace
mSum = 0;
}
- T getSum() const { return mSum; }
+ T getSum() const { return (T)mSum; }
private:
T mSum;
@@ -366,14 +392,15 @@ namespace LLTrace
U32 mNumSamples;
};
- typedef TraceType<MeasurementAccumulator<F64> > measurement_common_t;
+ typedef TraceType<MeasurementAccumulator<F64> > measurement_common_float_t;
+ typedef TraceType<MeasurementAccumulator<S64> > measurement_common_int_t;
template <typename T = F64, typename IS_UNIT = void>
class LL_COMMON_API Measurement
- : public TraceType<MeasurementAccumulator<T> >
+ : public TraceType<MeasurementAccumulator<typename StorageType<T>::type_t> >
{
public:
- typedef T storage_t;
+ typedef typename StorageType<T>::type_t storage_t;
Measurement(const char* name, const char* description = NULL)
: TraceType(name, description)
@@ -381,17 +408,16 @@ namespace LLTrace
void sample(T value)
{
- getPrimaryAccumulator().sample(value);
+ getPrimaryAccumulator().sample((storage_t)value);
}
};
template <typename T>
class LL_COMMON_API Measurement <T, typename T::is_unit_tag_t>
- : public TraceType<MeasurementAccumulator<typename T::storage_t> >
+ : public TraceType<MeasurementAccumulator<typename StorageType<typename T::storage_t>::type_t> >
{
public:
- typedef typename T::storage_t storage_t;
- typedef Measurement<typename T::storage_t> base_measurement_t;
+ typedef typename StorageType<typename T::storage_t>::type_t storage_t;
Measurement(const char* name, const char* description = NULL)
: TraceType(name, description)
@@ -402,18 +428,19 @@ namespace LLTrace
{
T converted_value;
converted_value.assignFrom(value);
- getPrimaryAccumulator().sample(converted_value.value());
+ getPrimaryAccumulator().sample((storage_t)converted_value.value());
}
};
- typedef TraceType<CountAccumulator<F64> > count_common_t;
+ typedef TraceType<CountAccumulator<F64> > count_common_float_t;
+ typedef TraceType<CountAccumulator<S64> > count_common_int_t;
template <typename T = F64, typename IS_UNIT = void>
class LL_COMMON_API Count
- : public TraceType<CountAccumulator<T> >
+ : public TraceType<CountAccumulator<typename StorageType<T>::type_t> >
{
public:
- typedef T storage_t;
+ typedef typename StorageType<T>::type_t storage_t;
Count(const char* name, const char* description = NULL)
: TraceType(name)
@@ -421,17 +448,16 @@ namespace LLTrace
void add(T value)
{
- getPrimaryAccumulator().add(value);
+ getPrimaryAccumulator().add((storage_t)value);
}
};
template <typename T>
class LL_COMMON_API Count <T, typename T::is_unit_tag_t>
- : public TraceType<CountAccumulator<typename T::storage_t> >
+ : public TraceType<CountAccumulator<typename StorageType<typename T::storage_t>::type_t> >
{
public:
- typedef typename T::storage_t storage_t;
- typedef Count<typename T::storage_t> base_count_t;
+ typedef typename StorageType<typename T::storage_t>::type_t storage_t;
Count(const char* name, const char* description = NULL)
: TraceType(name)
@@ -442,7 +468,7 @@ namespace LLTrace
{
T converted_value;
converted_value.assignFrom(value);
- getPrimaryAccumulator().add(converted_value.value());
+ getPrimaryAccumulator().add((storage_t)converted_value.value());
}
};
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 9a769ff344..f44a0a2764 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -39,8 +39,10 @@ namespace LLTrace
Recording::Recording()
: mElapsedSeconds(0),
- mCounts(new AccumulatorBuffer<CountAccumulator<F64> >()),
- mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<F64> >()),
+ mCountsFloat(new AccumulatorBuffer<CountAccumulator<F64> >()),
+ mMeasurementsFloat(new AccumulatorBuffer<MeasurementAccumulator<F64> >()),
+ mCounts(new AccumulatorBuffer<CountAccumulator<S64> >()),
+ mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<S64> >()),
mStackTimers(new AccumulatorBuffer<TimerAccumulator>())
{}
@@ -59,6 +61,8 @@ void Recording::update()
void Recording::handleReset()
{
+ mCountsFloat.write()->reset();
+ mMeasurementsFloat.write()->reset();
mCounts.write()->reset();
mMeasurements.write()->reset();
mStackTimers.write()->reset();
@@ -88,6 +92,8 @@ void Recording::handleSplitTo(Recording& other)
void Recording::makePrimary()
{
+ mCountsFloat.write()->makePrimary();
+ mMeasurementsFloat.write()->makePrimary();
mCounts.write()->makePrimary();
mMeasurements.write()->makePrimary();
mStackTimers.write()->makePrimary();
@@ -100,14 +106,120 @@ bool Recording::isPrimary() const
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);
mStackTimers.write()->addSamples(*other.mStackTimers);
mElapsedSeconds += other.mElapsedSeconds;
}
+F64 Recording::getSum( const TraceType<CountAccumulator<F64> >& stat ) const
+{
+ return stat.getAccumulator(mCountsFloat).getSum();
+}
+
+S64 Recording::getSum( const TraceType<CountAccumulator<S64> >& stat ) const
+{
+ return stat.getAccumulator(mCounts).getSum();
+}
+
+F64 Recording::getSum( const TraceType<MeasurementAccumulator<F64> >& stat ) const
+{
+ return (F64)stat.getAccumulator(mMeasurementsFloat).getSum();
+}
+
+S64 Recording::getSum( const TraceType<MeasurementAccumulator<S64> >& stat ) const
+{
+ return (S64)stat.getAccumulator(mMeasurements).getSum();
+}
+
+
+
+F64 Recording::getPerSec( const TraceType<CountAccumulator<F64> >& stat ) const
+{
+ return stat.getAccumulator(mCountsFloat).getSum() / mElapsedSeconds;
+}
+
+F64 Recording::getPerSec( const TraceType<CountAccumulator<S64> >& stat ) const
+{
+ return (F64)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds;
+}
+
+F64 Recording::getPerSec( const TraceType<MeasurementAccumulator<F64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurementsFloat).getSum() / mElapsedSeconds;
+}
+
+F64 Recording::getPerSec( const TraceType<MeasurementAccumulator<S64> >& stat ) const
+{
+ return (F64)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds;
+}
+
+F64 Recording::getMin( const TraceType<MeasurementAccumulator<F64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurementsFloat).getMin();
+}
+
+S64 Recording::getMin( const TraceType<MeasurementAccumulator<S64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurements).getMin();
+}
+
+F64 Recording::getMax( const TraceType<MeasurementAccumulator<F64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurementsFloat).getMax();
+}
+
+S64 Recording::getMax( const TraceType<MeasurementAccumulator<S64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurements).getMax();
+}
+
+F64 Recording::getMean( const TraceType<MeasurementAccumulator<F64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurementsFloat).getMean();
+}
+
+F64 Recording::getMean( const TraceType<MeasurementAccumulator<S64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurements).getMean();
+}
+
+F64 Recording::getStandardDeviation( const TraceType<MeasurementAccumulator<F64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurementsFloat).getStandardDeviation();
+}
+
+F64 Recording::getStandardDeviation( const TraceType<MeasurementAccumulator<S64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurements).getStandardDeviation();
+}
+
+F64 Recording::getLastValue( const TraceType<MeasurementAccumulator<F64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurementsFloat).getLastValue();
+}
+
+S64 Recording::getLastValue( const TraceType<MeasurementAccumulator<S64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurements).getLastValue();
+}
+
+U32 Recording::getSampleCount( const TraceType<MeasurementAccumulator<F64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurementsFloat).getSampleCount();
+}
+
+U32 Recording::getSampleCount( const TraceType<MeasurementAccumulator<S64> >& stat ) const
+{
+ return stat.getAccumulator(mMeasurements).getSampleCount();
+}
+
+
+
///////////////////////////////////////////////////////////////////////
-// Recording
+// PeriodicRecording
///////////////////////////////////////////////////////////////////////
PeriodicRecording::PeriodicRecording( S32 num_periods )
@@ -179,6 +291,7 @@ void PeriodicRecording::handleSplitTo( PeriodicRecording& other )
getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod());
}
+
///////////////////////////////////////////////////////////////////////
// ExtendableRecording
///////////////////////////////////////////////////////////////////////
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index d3f001ab6a..4af973515d 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -112,124 +112,81 @@ namespace LLTrace
void update();
// Count accessors
+ F64 getSum(const TraceType<CountAccumulator<F64> >& stat) const;
+ S64 getSum(const TraceType<CountAccumulator<S64> >& stat) const;
template <typename T>
- T getSum(const TraceType<CountAccumulator<T> >& stat) const
+ T getSum(const Count<T, typename T::is_unit_tag_t>& stat) const
{
- return (T)stat.getAccumulator(mCounts).getSum();
- }
-
- template <typename T, typename IS_UNIT>
- T getSum(const Count<T, IS_UNIT>& stat) const
- {
- return (T)stat.getAccumulator(mCounts).getSum();
+ return (T)getSum(static_cast<const TraceType<CountAccumulator<StorageType<T>::type_t> >&> (stat));
}
+ F64 getPerSec(const TraceType<CountAccumulator<F64> >& stat) const;
+ F64 getPerSec(const TraceType<CountAccumulator<S64> >& stat) const;
template <typename T>
- T getPerSec(const TraceType<CountAccumulator<T> >& stat) const
+ T getPerSec(const Count<T, typename T::is_unit_tag_t>& stat) const
{
- return (T)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds;
- }
-
- template <typename T, typename IS_UNIT>
- T getPerSec(const Count<T, IS_UNIT>& stat) const
- {
- return (T)stat.getAccumulator(mCounts).getSum() / mElapsedSeconds;
+ return (T)getPerSec(static_cast<const TraceType<CountAccumulator<StorageType<T>::type_t> >&> (stat));
}
// Measurement accessors
+ F64 getSum(const TraceType<MeasurementAccumulator<F64> >& stat) const;
+ S64 getSum(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getSum(const TraceType<MeasurementAccumulator<T> >& stat) const
+ T getSum(const Measurement<T, typename T::is_unit_tag_t>& stat) const
{
- return (T)stat.getAccumulator(mMeasurements).getSum();
-
- }
-
- template <typename T, typename IS_UNIT>
- T getSum(const Measurement<T, IS_UNIT>& stat) const
- {
- return (T)stat.getAccumulator(mMeasurements).getSum();
-
+ return (T)getSum(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
}
+ F64 getPerSec(const TraceType<MeasurementAccumulator<F64> >& stat) const;
+ F64 getPerSec(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getPerSec(const TraceType<MeasurementAccumulator<T> >& stat) const
- {
- return (T)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds;
- }
-
- template <typename T, typename IS_UNIT>
- T getPerSec(const Measurement<T, IS_UNIT>& stat) const
+ T getPerSec(const Measurement<T, typename T::is_unit_tag_t>& stat) const
{
- return (typename Count<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds;
+ return (T)getPerSec(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
}
+ F64 getMin(const TraceType<MeasurementAccumulator<F64> >& stat) const;
+ S64 getMin(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getMin(const TraceType<MeasurementAccumulator<T> >& stat) const
- {
- return (T)stat.getAccumulator(mMeasurements).getMin();
- }
-
- template <typename T, typename IS_UNIT>
- T getMin(const Measurement<T, IS_UNIT>& stat) const
+ T getMin(const Measurement<T, typename T::is_unit_tag_t>& stat) const
{
- return (T)stat.getAccumulator(mMeasurements).getMin();
+ return (T)getMin(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
}
-
+ F64 getMax(const TraceType<MeasurementAccumulator<F64> >& stat) const;
+ S64 getMax(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getMax(const TraceType<MeasurementAccumulator<T> >& stat) const
- {
- return (T)stat.getAccumulator(mMeasurements).getMax();
- }
-
- template <typename T, typename IS_UNIT>
- T getMax(const Measurement<T, IS_UNIT>& stat) const
+ T getMax(const Measurement<T, typename T::is_unit_tag_t>& stat) const
{
- return (T)stat.getAccumulator(mMeasurements).getMax();
+ return (T)getMax(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
}
+ F64 getMean(const TraceType<MeasurementAccumulator<F64> >& stat) const;
+ F64 getMean(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getMean(const TraceType<MeasurementAccumulator<T> >& stat) const
+ T getMean(Measurement<T, typename T::is_unit_tag_t>& stat) const
{
- return (T)stat.getAccumulator(mMeasurements).getMean();
- }
-
- template <typename T, typename IS_UNIT>
- T getMean(Measurement<T, IS_UNIT>& stat) const
- {
- return (T)stat.getAccumulator(mMeasurements).getMean();
+ return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
}
+ F64 getStandardDeviation(const TraceType<MeasurementAccumulator<F64> >& stat) const;
+ F64 getStandardDeviation(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getStandardDeviation(const TraceType<MeasurementAccumulator<T> >& stat) const
- {
- return (T)stat.getAccumulator(mMeasurements).getStandardDeviation();
- }
-
- template <typename T, typename IS_UNIT>
- T getStandardDeviation(const Measurement<T, IS_UNIT>& stat) const
+ T getStandardDeviation(const Measurement<T, typename T::is_unit_tag_t>& stat) const
{
- return (T)stat.getAccumulator(mMeasurements).getStandardDeviation();
+ return (T)getMean(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
}
+ F64 getLastValue(const TraceType<MeasurementAccumulator<F64> >& stat) const;
+ S64 getLastValue(const TraceType<MeasurementAccumulator<S64> >& stat) const;
template <typename T>
- T getLastValue(const TraceType<MeasurementAccumulator<T> >& stat) const
- {
- return (T)stat.getAccumulator(mMeasurements).getLastValue();
- }
-
- template <typename T, typename IS_UNIT>
- T getLastValue(const Measurement<T, IS_UNIT>& stat) const
+ T getLastValue(const Measurement<T, typename T::is_unit_tag_t>& stat) const
{
- return (T)stat.getAccumulator(mMeasurements).getLastValue();
+ return (T)getLastValue(static_cast<const TraceType<MeasurementAccumulator<StorageType<T>::type_t> >&> (stat));
}
-
- template <typename T>
- U32 getSampleCount(const TraceType<MeasurementAccumulator<T> >& stat) const
- {
- return stat.getAccumulator(mMeasurements).getSampleCount();
- }
+ U32 getSampleCount(const TraceType<MeasurementAccumulator<F64> >& stat) const;
+ U32 getSampleCount(const TraceType<MeasurementAccumulator<S64> >& stat) const;
LLUnit::Seconds<F64> getDuration() const { return mElapsedSeconds; }
@@ -244,8 +201,10 @@ namespace LLTrace
// returns data for current thread
class ThreadRecorder* getThreadRecorder();
- LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<F64> > > mCounts;
- LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<F64> > > mMeasurements;
+ LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<F64> > > mCountsFloat;
+ LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<F64> > > mMeasurementsFloat;
+ LLCopyOnWritePointer<AccumulatorBuffer<CountAccumulator<S64> > > mCounts;
+ LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<S64> > > mMeasurements;
LLCopyOnWritePointer<AccumulatorBuffer<TimerAccumulator> > mStackTimers;
LLTimer mSamplingTimer;
@@ -260,6 +219,7 @@ namespace LLTrace
~PeriodicRecording();
void nextPeriod();
+ S32 getNumPeriods() { return mNumPeriods; }
Recording& getLastRecordingPeriod()
{
@@ -268,7 +228,7 @@ namespace LLTrace
const Recording& getLastRecordingPeriod() const
{
- return mRecordingPeriods[(mCurPeriod + mNumPeriods - 1) % mNumPeriods];
+ return getPrevRecordingPeriod(1);
}
Recording& getCurRecordingPeriod()
@@ -281,6 +241,16 @@ namespace LLTrace
return mRecordingPeriods[mCurPeriod];
}
+ Recording& getPrevRecordingPeriod(S32 offset)
+ {
+ return mRecordingPeriods[(mCurPeriod + mNumPeriods - offset) % mNumPeriods];
+ }
+
+ const Recording& getPrevRecordingPeriod(S32 offset) const
+ {
+ return mRecordingPeriods[(mCurPeriod + mNumPeriods - offset) % mNumPeriods];
+ }
+
Recording snapshotCurRecordingPeriod() const
{
Recording recording_copy(getCurRecordingPeriod());
@@ -290,6 +260,84 @@ namespace LLTrace
Recording& getTotalRecording();
+ template <typename T>
+ typename T getPeriodMin(const TraceType<CountAccumulator<T> >& stat) const
+ {
+ T min_val = std::numeric_limits<T>::max();
+ for (S32 i = 0; i < mNumPeriods; i++)
+ {
+ min_val = llmin(min_val, mRecordingPeriods[i].getSum(stat));
+ }
+ return (T)min_val;
+ }
+
+ template <typename T>
+ F64 getPeriodMinPerSec(const TraceType<CountAccumulator<T> >& stat) const
+ {
+ F64 min_val = std::numeric_limits<F64>::max();
+ for (S32 i = 0; i < mNumPeriods; i++)
+ {
+ min_val = llmin(min_val, mRecordingPeriods[i].getPerSec(stat));
+ }
+ return min_val;
+ }
+
+ template <typename T>
+ T getPeriodMax(const TraceType<CountAccumulator<T> >& stat) const
+ {
+ T max_val = std::numeric_limits<T>::min();
+ for (S32 i = 0; i < mNumPeriods; i++)
+ {
+ max_val = llmax(max_val, mRecordingPeriods[i].getSum(stat));
+ }
+ return max_val;
+ }
+
+ template <typename T>
+ F64 getPeriodMaxPerSec(const TraceType<CountAccumulator<T> >& stat) const
+ {
+ F64 max_val = std::numeric_limits<F64>::min();
+ for (S32 i = 0; i < mNumPeriods; i++)
+ {
+ max_val = llmax(max_val, mRecordingPeriods[i].getPerSec(stat));
+ }
+ return max_val;
+ }
+
+ template <typename T>
+ F64 getPeriodMean(const TraceType<CountAccumulator<T> >& stat) const
+ {
+ F64 mean = 0.0;
+ F64 count = 0;
+ for (S32 i = 0; i < mNumPeriods; i++)
+ {
+ if (mRecordingPeriods[i].getDuration() > 0.f)
+ {
+ count++;
+ mean += mRecordingPeriods[i].getSum(stat);
+ }
+ }
+ mean /= (F64)mNumPeriods;
+ return mean;
+ }
+
+ template <typename T>
+ F64 getPeriodMeanPerSec(const TraceType<CountAccumulator<T> >& stat) const
+ {
+ F64 mean = 0.0;
+ F64 count = 0;
+ for (S32 i = 0; i < mNumPeriods; i++)
+ {
+ if (mRecordingPeriods[i].getDuration() > 0.f)
+ {
+ count++;
+ mean += mRecordingPeriods[i].getPerSec(stat);
+ }
+ }
+ mean /= count;
+ return mean;
+ }
+
private:
// implementation for LLVCRControlsMixin
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index e81333f7f2..15056b80e4 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -113,9 +113,13 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target )
void ThreadRecorder::ActiveRecording::moveBaselineToTarget()
{
+ mTargetRecording->mMeasurementsFloat.write()->addSamples(*mBaseline.mMeasurementsFloat);
+ mTargetRecording->mCountsFloat.write()->addSamples(*mBaseline.mCountsFloat);
mTargetRecording->mMeasurements.write()->addSamples(*mBaseline.mMeasurements);
mTargetRecording->mCounts.write()->addSamples(*mBaseline.mCounts);
mTargetRecording->mStackTimers.write()->addSamples(*mBaseline.mStackTimers);
+ mBaseline.mMeasurementsFloat.write()->reset();
+ mBaseline.mCountsFloat.write()->reset();
mBaseline.mMeasurements.write()->reset();
mBaseline.mCounts.write()->reset();
mBaseline.mStackTimers.write()->reset();