summaryrefslogtreecommitdiff
path: root/indra/llcommon/lltracethreadrecorder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/lltracethreadrecorder.cpp')
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp132
1 files changed, 102 insertions, 30 deletions
diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp
index 02dc55771b..7b493a651e 100644
--- a/indra/llcommon/lltracethreadrecorder.cpp
+++ b/indra/llcommon/lltracethreadrecorder.cpp
@@ -26,6 +26,7 @@
#include "linden_common.h"
#include "lltracethreadrecorder.h"
+#include "llfasttimer.h"
namespace LLTrace
{
@@ -37,22 +38,60 @@ namespace LLTrace
ThreadRecorder::ThreadRecorder()
{
- get_thread_recorder() = this;
- mFullRecording.start();
+ //NB: the ordering of initialization in this function is very fragile due to a large number of implicit dependencies
+ set_thread_recorder(this);
+ TimeBlock& root_time_block = TimeBlock::getRootTimeBlock();
+
+ ThreadTimerStack* timer_stack = ThreadTimerStack::getInstance();
+ timer_stack->mTimeBlock = &root_time_block;
+ timer_stack->mActiveTimer = NULL;
+
+ mNumTimeBlockTreeNodes = AccumulatorBuffer<TimeBlockAccumulator>::getDefaultBuffer()->size();
+ mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes];
+
+ mThreadRecording.start();
+
+ // initialize time block parent pointers
+ for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(), end_it = LLInstanceTracker<TimeBlock>::endInstances();
+ it != end_it;
+ ++it)
+ {
+ TimeBlock& time_block = *it;
+ TimeBlockTreeNode& tree_node = mTimeBlockTreeNodes[it->getIndex()];
+ tree_node.mBlock = &time_block;
+ tree_node.mParent = &root_time_block;
+
+ it->getPrimaryAccumulator()->mParent = &root_time_block;
+ }
+
+ mRootTimer = new BlockTimer(root_time_block);
+ timer_stack->mActiveTimer = mRootTimer;
+
+ TimeBlock::getRootTimeBlock().getPrimaryAccumulator()->mActiveCount = 1;
}
-ThreadRecorder::ThreadRecorder( const ThreadRecorder& other )
-: mFullRecording(other.mFullRecording)
+ThreadRecorder::~ThreadRecorder()
{
- get_thread_recorder() = this;
- mFullRecording.start();
+ delete mRootTimer;
+
+ while(mActiveRecordings.size())
+ {
+ mActiveRecordings.front().mTargetRecording->stop();
+ }
+ set_thread_recorder(NULL);
+ delete[] mTimeBlockTreeNodes;
}
-ThreadRecorder::~ThreadRecorder()
+TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index)
{
- get_thread_recorder() = NULL;
+ if (0 <= index && index < mNumTimeBlockTreeNodes)
+ {
+ return &mTimeBlockTreeNodes[index];
+ }
+ return NULL;
}
+
void ThreadRecorder::activate( Recording* recording )
{
mActiveRecordings.push_front(ActiveRecording(recording));
@@ -73,7 +112,7 @@ std::list<ThreadRecorder::ActiveRecording>::iterator ThreadRecorder::update( Rec
if (next_it != mActiveRecordings.end())
{
// ...push our gathered data down to it
- next_it->mBaseline.mergeRecording(it->mBaseline);
+ next_it->mBaseline.appendRecording(it->mBaseline);
}
// copy accumulated measurements into result buffer and clear accumulator (mBaseline)
@@ -86,9 +125,21 @@ std::list<ThreadRecorder::ActiveRecording>::iterator ThreadRecorder::update( Rec
}
}
+ if (it == end_it)
+ {
+ llwarns << "Recording not active on this thread" << llendl;
+ }
+
return it;
}
+AccumulatorBuffer<CountAccumulator<F64> > gCountsFloat;
+AccumulatorBuffer<MeasurementAccumulator<F64> > gMeasurementsFloat;
+AccumulatorBuffer<CountAccumulator<S64> > gCounts;
+AccumulatorBuffer<MeasurementAccumulator<S64> > gMeasurements;
+AccumulatorBuffer<TimeBlockAccumulator> gStackTimers;
+AccumulatorBuffer<MemStatAccumulator> gMemStats;
+
void ThreadRecorder::deactivate( Recording* recording )
{
std::list<ActiveRecording>::iterator it = update(recording);
@@ -113,9 +164,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();
@@ -127,7 +182,6 @@ void ThreadRecorder::ActiveRecording::moveBaselineToTarget()
///////////////////////////////////////////////////////////////////////
SlaveThreadRecorder::SlaveThreadRecorder()
-: ThreadRecorder(getMasterThreadRecorder())
{
getMasterThreadRecorder().addSlaveThread(this);
}
@@ -139,39 +193,65 @@ SlaveThreadRecorder::~SlaveThreadRecorder()
void SlaveThreadRecorder::pushToMaster()
{
- mFullRecording.stop();
+ mThreadRecording.stop();
{
LLMutexLock(getMasterThreadRecorder().getSlaveListMutex());
- mSharedData.copyFrom(mFullRecording);
+ mSharedData.appendFrom(mThreadRecording);
}
- mFullRecording.start();
+ mThreadRecording.start();
+}
+
+void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source )
+{
+ LLMutexLock lock(&mRecordingMutex);
+ mRecording.appendRecording(source);
}
-void SlaveThreadRecorder::SharedData::copyFrom( const Recording& source )
+void SlaveThreadRecorder::SharedData::appendTo( Recording& sink )
{
- LLMutexLock lock(&mRecorderMutex);
- mRecorder.mergeRecording(source);
+ LLMutexLock lock(&mRecordingMutex);
+ sink.appendRecording(mRecording);
}
-void SlaveThreadRecorder::SharedData::copyTo( Recording& sink )
+void SlaveThreadRecorder::SharedData::mergeFrom( const Recording& source )
{
- LLMutexLock lock(&mRecorderMutex);
- sink.mergeRecording(mRecorder);
+ LLMutexLock lock(&mRecordingMutex);
+ mRecording.mergeRecording(source);
}
+void SlaveThreadRecorder::SharedData::mergeTo( Recording& sink )
+{
+ LLMutexLock lock(&mRecordingMutex);
+ sink.mergeRecording(mRecording);
+}
+
+void SlaveThreadRecorder::SharedData::reset()
+{
+ LLMutexLock lock(&mRecordingMutex);
+ mRecording.reset();
+}
+
+
///////////////////////////////////////////////////////////////////////
// MasterThreadRecorder
///////////////////////////////////////////////////////////////////////
+LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_SLAVES("Pull slave trace data");
void MasterThreadRecorder::pullFromSlaveThreads()
{
+ LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_SLAVES);
+ if (mActiveRecordings.empty()) return;
+
LLMutexLock lock(&mSlaveListMutex);
+ Recording& target_recording = mActiveRecordings.front().mBaseline;
for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end();
it != end_it;
++it)
{
- (*it)->mRecorder->mSharedData.copyTo((*it)->mSlaveRecording);
+ // ignore block timing info for now
+ (*it)->mSharedData.mergeTo(target_recording);
+ (*it)->mSharedData.reset();
}
}
@@ -179,7 +259,7 @@ void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child )
{
LLMutexLock lock(&mSlaveListMutex);
- mSlaveThreadRecorders.push_back(new SlaveThreadRecorderProxy(child));
+ mSlaveThreadRecorders.push_back(child);
}
void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child )
@@ -190,7 +270,7 @@ void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child )
it != end_it;
++it)
{
- if ((*it)->mRecorder == child)
+ if ((*it) == child)
{
mSlaveThreadRecorders.erase(it);
break;
@@ -204,12 +284,4 @@ void MasterThreadRecorder::pushToMaster()
MasterThreadRecorder::MasterThreadRecorder()
{}
-///////////////////////////////////////////////////////////////////////
-// MasterThreadRecorder::SlaveThreadTraceProxy
-///////////////////////////////////////////////////////////////////////
-
-MasterThreadRecorder::SlaveThreadRecorderProxy::SlaveThreadRecorderProxy( class SlaveThreadRecorder* recorder)
-: mRecorder(recorder)
-{}
-
}