summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-05-30 18:30:11 -0700
committerRichard Linden <none@none>2013-05-30 18:30:11 -0700
commitae355188327515d53b9c15c27ed576829fce3668 (patch)
tree1fd6d4816df45fde80fe5d862bfcd2cb9adb1c6c
parentfe7959591633e4c6bda570c6fd19d7fdfec15454 (diff)
SH-3931 WIP Interesting: Add graphs to visualize scene load metrics
fixed LLTrace::ExtendablePeriodicRecording::extend() to include *all* frame extensions gated SlaveThreadRecorder pushing to master based on master update rate reverted changes to LLThreadLocalSingletonPointer to not use offset-from-default trick
-rw-r--r--indra/llcommon/llthreadlocalstorage.h8
-rw-r--r--indra/llcommon/lltrace.h21
-rw-r--r--indra/llcommon/lltracerecording.cpp5
-rw-r--r--indra/llcommon/lltracerecording.h6
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp25
-rw-r--r--indra/llcommon/lltracethreadrecorder.h14
6 files changed, 47 insertions, 32 deletions
diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h
index 471784749b..cc67248124 100644
--- a/indra/llcommon/llthreadlocalstorage.h
+++ b/indra/llcommon/llthreadlocalstorage.h
@@ -313,11 +313,6 @@ template<typename DERIVED_TYPE>
class LLThreadLocalSingletonPointer
{
public:
- void operator =(DERIVED_TYPE* value)
- {
- setInstance(value);
- }
-
LL_FORCE_INLINE static DERIVED_TYPE* getInstance()
{
#if LL_DARWIN
@@ -328,7 +323,7 @@ public:
#endif
}
- LL_FORCE_INLINE static void setInstance(DERIVED_TYPE* instance)
+ static void setInstance(DERIVED_TYPE* instance)
{
#if LL_DARWIN
createTLSKey();
@@ -339,6 +334,7 @@ public:
}
private:
+
#if LL_WINDOWS
static __declspec(thread) DERIVED_TYPE* sInstance;
#elif LL_LINUX
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index e950a119d3..00bab536ff 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -35,6 +35,7 @@
#include "llunit.h"
#include "llapr.h"
#include "llthreadlocalstorage.h"
+#include "lltimer.h"
#include <list>
@@ -75,7 +76,6 @@ void set_thread_recorder(class ThreadRecorder*);
class MasterThreadRecorder& getUIThreadRecorder();
-// one per thread per type
template<typename ACCUMULATOR>
class AccumulatorBuffer : public LLRefCount
{
@@ -104,9 +104,9 @@ public:
~AccumulatorBuffer()
{
- if (LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance() == mStorage)
+ if (isPrimary())
{
- LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(getDefaultBuffer()->mStorage);
+ LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
}
delete[] mStorage;
}
@@ -169,7 +169,8 @@ public:
LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage()
{
- return LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance();
+ ACCUMULATOR* accumulator = LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance();
+ return accumulator ? accumulator : sDefaultBuffer->mStorage;
}
// NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned
@@ -222,25 +223,27 @@ public:
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)
{
- sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE);
+ // 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
+ sDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker());
sInitialized = true;
+ sDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE);
}
- return sBuffer;
+ return sDefaultBuffer;
}
private:
ACCUMULATOR* mStorage;
size_t mStorageSize;
static size_t sNextStorageSlot;
+ static self_t* sDefaultBuffer;
};
template<typename ACCUMULATOR> size_t AccumulatorBuffer<ACCUMULATOR>::sNextStorageSlot = 0;
+template<typename ACCUMULATOR> AccumulatorBuffer<ACCUMULATOR>* AccumulatorBuffer<ACCUMULATOR>::sDefaultBuffer = NULL;
template<typename ACCUMULATOR>
class TraceType
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index 5b0b74524f..86cdca3e10 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -490,8 +490,9 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
{
if (mAutoResize)
{
- for (S32 other_index = (other.mCurPeriod + 2) % other_recording_count;
- other_index != other.mCurPeriod;
+ for (S32 other_index = (other.mCurPeriod + 2) % other_recording_count,
+ end_index = (other.mCurPeriod + 1) % other_recording_count;
+ other_index != end_index;
other_index = (other_index + 1) % other_recording_count)
{
llassert(other.mRecordingPeriods[other_index].getDuration() != 0.f
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index 19a4fae737..aaeb32e891 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -336,12 +336,12 @@ namespace LLTrace
}
template <typename T>
- typename T getPeriodMin(const TraceType<SampleAccumulator<T> >& stat, size_t num_periods = U32_MAX) const
+ T getPeriodMin(const TraceType<SampleAccumulator<T> >& stat, size_t num_periods = U32_MAX) const
{
size_t total_periods = mRecordingPeriods.size();
num_periods = llmin(num_periods, total_periods);
- typename T min_val = std::numeric_limits<T>::max();
+ T min_val = std::numeric_limits<T>::max();
for (S32 i = 1; i <= num_periods; i++)
{
S32 index = (mCurPeriod + total_periods - i) % total_periods;
@@ -351,7 +351,7 @@ namespace LLTrace
}
template <typename T>
- typename T getPeriodMin(const TraceType<EventAccumulator<T> >& stat, size_t num_periods = U32_MAX) const
+ T getPeriodMin(const TraceType<EventAccumulator<T> >& stat, size_t num_periods = U32_MAX) const
{
size_t total_periods = mRecordingPeriods.size();
num_periods = llmin(num_periods, total_periods);
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 75c7cb2ff1..89b5df1f94 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -202,14 +202,21 @@ SlaveThreadRecorder::~SlaveThreadRecorder()
mMasterRecorder.removeSlaveThread(this);
}
-void SlaveThreadRecorder::pushToMaster()
+bool SlaveThreadRecorder::pushToMaster()
{
- mThreadRecording.stop();
+ if (mPushCount != mMasterRecorder.getPullCount())
{
- LLMutexLock(mMasterRecorder.getSlaveListMutex());
- mSharedData.appendFrom(mThreadRecording);
+ mThreadRecording.stop();
+ {
+ LLMutexLock(mMasterRecorder.getSlaveListMutex());
+ mSharedData.appendFrom(mThreadRecording);
+ }
+ mThreadRecording.start();
+
+ mPushCount = mMasterRecorder.getPullCount();
+ return true;
}
- mThreadRecording.start();
+ return false;
}
void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source )
@@ -264,6 +271,8 @@ void MasterThreadRecorder::pullFromSlaveThreads()
(*it)->mSharedData.mergeTo(target_recording_buffers);
(*it)->mSharedData.reset();
}
+
+ mPullCount++;
}
void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child )
@@ -289,8 +298,10 @@ void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child )
}
}
-void MasterThreadRecorder::pushToMaster()
-{}
+bool MasterThreadRecorder::pushToMaster()
+{
+ return false;
+}
MasterThreadRecorder::MasterThreadRecorder()
{}
diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h
index 17a2d4a9a9..a044757e62 100644
--- a/indra/llcommon/lltracethreadrecorder.h
+++ b/indra/llcommon/lltracethreadrecorder.h
@@ -49,7 +49,7 @@ namespace LLTrace
void deactivate(Recording* recording);
active_recording_list_t::reverse_iterator bringUpToDate(Recording* recording);
- virtual void pushToMaster() = 0;
+ virtual bool pushToMaster() = 0;
TimeBlockTreeNode* getTimeBlockTreeNode(S32 index);
@@ -80,19 +80,22 @@ namespace LLTrace
void addSlaveThread(class SlaveThreadRecorder* child);
void removeSlaveThread(class SlaveThreadRecorder* child);
- /*virtual */ void pushToMaster();
+ /*virtual */ bool pushToMaster();
// call this periodically to gather stats data from slave threads
void pullFromSlaveThreads();
LLMutex* getSlaveListMutex() { return &mSlaveListMutex; }
+ U32 getPullCount() { return mPullCount; }
+
private:
typedef std::list<class SlaveThreadRecorder*> slave_thread_recorder_list_t;
- slave_thread_recorder_list_t mSlaveThreadRecorders;
- LLMutex mSlaveListMutex;
+ slave_thread_recorder_list_t mSlaveThreadRecorders; // list of slave thread recorders associated with this master
+ LLMutex mSlaveListMutex; // protects access to slave list
+ LLAtomicU32 mPullCount; // number of times data has been pulled from slaves
};
class LL_COMMON_API SlaveThreadRecorder : public ThreadRecorder
@@ -102,7 +105,7 @@ namespace LLTrace
~SlaveThreadRecorder();
// call this periodically to gather stats data for master thread to consume
- /*virtual*/ void pushToMaster();
+ /*virtual*/ bool pushToMaster();
MasterThreadRecorder* mMaster;
@@ -119,6 +122,7 @@ namespace LLTrace
};
SharedData mSharedData;
MasterThreadRecorder& mMasterRecorder;
+ U32 mPushCount;
};
}