summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/lltrace.h111
1 files changed, 95 insertions, 16 deletions
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 1d2dcff9b7..c6940c12a2 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -27,28 +27,108 @@
#ifndef LL_LLTRACE_H
#define LL_LLTRACE_H
+#include "stdtypes.h"
+#include "llpreprocessor.h"
+
#include <vector>
+#include <boost/type_traits/alignment_of.hpp>
namespace LLTrace
{
- class Stat
+ //TODO figure out best way to do this and proper naming convention
+
+ static
+ void init()
+ {
+
+ }
+
+ template<typename T>
+ class Accumulator
{
public:
- Stat(const char* name)
- : mName(name)
+ Accumulator()
+ : mSum(),
+ mMin(),
+ mMax(),
+ mNumSamples(0)
+ {}
+
+ void sample(T value)
+ {
+ mNumSamples++;
+ mSum += value;
+ if (value < mMin)
+ {
+ mMin = value;
+ }
+ else if (value > mMax)
+ {
+ mMax = value;
+ }
+ }
+
+ private:
+ T mSum,
+ mMin,
+ mMax;
+
+ U32 mNumSamples;
+ };
+
+ class TraceStorage
+ {
+ protected:
+ TraceStorage(const size_t size, const size_t alignment)
+ {
+ mRecordOffset = sNextOffset + (alignment - 1);
+ mRecordOffset -= mRecordOffset % alignment;
+ sNextOffset = mRecordOffset + size;
+ sStorage.reserve((size_t)sNextOffset);
+ }
+
+ // this needs to be thread local
+ static std::vector<U8> sStorage;
+ static ptrdiff_t sNextOffset;
+
+ ptrdiff_t mRecordOffset;
+ };
+
+ std::vector<U8> TraceStorage::sStorage;
+ ptrdiff_t TraceStorage::sNextOffset = 0;
+
+ template<typename T>
+ class Trace : public TraceStorage
+ {
+ public:
+ Trace(const std::string& name)
+ : TraceStorage(sizeof(Accumulator<T>), boost::alignment_of<Accumulator<T> >::value),
+ mName(name)
{}
- void record() {}
- void record(int value) {}
- void record(float value) {}
+
+ void record(T value)
+ {
+ (reinterpret_cast<Accumulator<T>* >(sStorage + mRecordOffset))->sample(value);
+ }
+
private:
- const std::string mName;
+ std::string mName;
+ };
+
+ template<typename T>
+ class Stat : public Trace<T>
+ {
+ public:
+ Stat(const char* name)
+ : Trace(name)
+ {}
};
- class BlockTimer
+ class BlockTimer : public Trace<U32>
{
public:
BlockTimer(const char* name)
- : mName(name)
+ : Trace(name)
{}
struct Accumulator
@@ -56,8 +136,8 @@ namespace LLTrace
U32 mTotalTimeCounter,
mChildTimeCounter,
mCalls;
- Accumulator* mParent, // info for caller timer
- mLastCaller; // used to bootstrap tree construction
+ Accumulator* mParent; // info for caller timer
+ Accumulator* mLastCaller; // used to bootstrap tree construction
const BlockTimer* mTimer; // points to block timer associated with this storage
U8 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
@@ -97,8 +177,8 @@ namespace LLTrace
accumulator->mChildTimeCounter += sCurRecorder.mChildTime;
accumulator->mActiveCount--;
- accumulator->mLastCaller = mLastRecorder->mAccumulator;
- mLastRecorder->mChildTime += total_time;
+ accumulator->mLastCaller = mLastRecorder.mAccumulator;
+ mLastRecorder.mChildTime += total_time;
// pop stack
sCurRecorder = mLastRecorder;
@@ -109,7 +189,7 @@ namespace LLTrace
};
private:
- U32 getCPUClockCount32()
+ static U32 getCPUClockCount32()
{
U32 ret_val;
__asm
@@ -140,8 +220,7 @@ namespace LLTrace
return ret_val;
}
- const std::string mName;
- static RecorderStackEntry* sCurRecorder;
+ static RecorderStackEntry sCurRecorder;
};
BlockTimer::RecorderStackEntry BlockTimer::sCurRecorder;