From 3960fdf9e01619ddfd7903bcdd8d894f432752d0 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 4 Oct 2012 23:11:57 -0700 Subject: SH-3275 WIP Update viewer metrics system to be more flexible moved threadrecorder classes into separate file added Count trace type, which tracks value increases and decreases and can report churn as well as overall growth rate --- indra/llcommon/lltracethreadrecorder.cpp | 219 +++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 indra/llcommon/lltracethreadrecorder.cpp (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp new file mode 100644 index 0000000000..9115a52fd1 --- /dev/null +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -0,0 +1,219 @@ +/** + * @file lltracethreadrecorder.cpp + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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 "lltrace.h" + +namespace LLTrace +{ + + +/////////////////////////////////////////////////////////////////////// +// ThreadRecorder +/////////////////////////////////////////////////////////////////////// + +ThreadRecorder::ThreadRecorder() +: mPrimaryRecording(NULL) +{ + get_thread_recorder() = this; + mFullRecording.start(); +} + +ThreadRecorder::ThreadRecorder( const ThreadRecorder& other ) +: mFullRecording(other.mFullRecording), + mPrimaryRecording(NULL) +{ + get_thread_recorder() = this; + mFullRecording.start(); +} + +ThreadRecorder::~ThreadRecorder() +{ + get_thread_recorder() = NULL; +} + +//TODO: remove this and use llviewerstats recording +Recording* ThreadRecorder::getPrimaryRecording() +{ + return mPrimaryRecording; +} + +void ThreadRecorder::activate( Recording* recording ) +{ + mActiveRecordings.push_front(ActiveRecording(mPrimaryRecording, recording)); + mActiveRecordings.front().mBaseline.makePrimary(); + mPrimaryRecording = &mActiveRecordings.front().mBaseline; +} + +//TODO: consider merging results down the list to one past the buffered item. +// this would require 2 buffers per sampler, to separate current total from running total + +void ThreadRecorder::deactivate( Recording* recording ) +{ + for (std::list::iterator it = mActiveRecordings.begin(), end_it = mActiveRecordings.end(); + it != end_it; + ++it) + { + std::list::iterator next_it = it; + if (++next_it != mActiveRecordings.end()) + { + next_it->mergeMeasurements((*it)); + } + + it->flushAccumulators(mPrimaryRecording); + + if (it->mTargetRecording == recording) + { + if (next_it != mActiveRecordings.end()) + { + next_it->mBaseline.makePrimary(); + mPrimaryRecording = &next_it->mBaseline; + } + mActiveRecordings.erase(it); + break; + } + } +} + +ThreadRecorder::ActiveRecording::ActiveRecording( Recording* source, Recording* target ) +: mTargetRecording(target) +{ + // take snapshots of current values rates and timers + if (source) + { + mBaseline.mRates.write()->copyFrom(*source->mRates); + mBaseline.mStackTimers.write()->copyFrom(*source->mStackTimers); + } +} + +void ThreadRecorder::ActiveRecording::mergeMeasurements(ThreadRecorder::ActiveRecording& other) +{ + mBaseline.mMeasurements.write()->mergeSamples(*other.mBaseline.mMeasurements); +} + +void ThreadRecorder::ActiveRecording::flushAccumulators(Recording* current) +{ + // accumulate statistics-like measurements + mTargetRecording->mMeasurements.write()->mergeSamples(*mBaseline.mMeasurements); + // for rate-like measurements, merge total change since baseline + mTargetRecording->mRates.write()->mergeDeltas(*mBaseline.mRates, *current->mRates); + mTargetRecording->mStackTimers.write()->mergeDeltas(*mBaseline.mStackTimers, *current->mStackTimers); + // reset baselines + mBaseline.mRates.write()->copyFrom(*current->mRates); + mBaseline.mStackTimers.write()->copyFrom(*current->mStackTimers); +} + +/////////////////////////////////////////////////////////////////////// +// SlaveThreadRecorder +/////////////////////////////////////////////////////////////////////// + +SlaveThreadRecorder::SlaveThreadRecorder() +: ThreadRecorder(getMasterThreadRecorder()) +{ + getMasterThreadRecorder().addSlaveThread(this); +} + +SlaveThreadRecorder::~SlaveThreadRecorder() +{ + getMasterThreadRecorder().removeSlaveThread(this); +} + +void SlaveThreadRecorder::pushToMaster() +{ + mFullRecording.stop(); + { + LLMutexLock(getMasterThreadRecorder().getSlaveListMutex()); + mSharedData.copyFrom(mFullRecording); + } + mFullRecording.start(); +} + +void SlaveThreadRecorder::SharedData::copyFrom( const Recording& source ) +{ + LLMutexLock lock(&mRecorderMutex); + mRecorder.mergeSamples(source); +} + +void SlaveThreadRecorder::SharedData::copyTo( Recording& sink ) +{ + LLMutexLock lock(&mRecorderMutex); + sink.mergeSamples(mRecorder); +} + +/////////////////////////////////////////////////////////////////////// +// MasterThreadRecorder +/////////////////////////////////////////////////////////////////////// + +void MasterThreadRecorder::pullFromSlaveThreads() +{ + LLMutexLock lock(&mSlaveListMutex); + + for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); + it != end_it; + ++it) + { + (*it)->mRecorder->mSharedData.copyTo((*it)->mSlaveRecording); + } +} + +void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child ) +{ + LLMutexLock lock(&mSlaveListMutex); + + mSlaveThreadRecorders.push_back(new SlaveThreadRecorderProxy(child)); +} + +void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child ) +{ + LLMutexLock lock(&mSlaveListMutex); + + for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); + it != end_it; + ++it) + { + if ((*it)->mRecorder == child) + { + mSlaveThreadRecorders.erase(it); + break; + } + } +} + +void MasterThreadRecorder::pushToMaster() +{} + +MasterThreadRecorder::MasterThreadRecorder() +{} + +/////////////////////////////////////////////////////////////////////// +// MasterThreadRecorder::SlaveThreadTraceProxy +/////////////////////////////////////////////////////////////////////// + +MasterThreadRecorder::SlaveThreadRecorderProxy::SlaveThreadRecorderProxy( class SlaveThreadRecorder* recorder) +: mRecorder(recorder) +{} + +} -- cgit v1.2.3 From 4dce574a8d604a501ec3c12eef3f5d03ee188473 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 5 Oct 2012 10:51:38 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system added update() method to trace recorders to allow mid-collection snapshots --- indra/llcommon/lltracethreadrecorder.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 9115a52fd1..b2c6fe3b80 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -68,10 +68,7 @@ void ThreadRecorder::activate( Recording* recording ) mPrimaryRecording = &mActiveRecordings.front().mBaseline; } -//TODO: consider merging results down the list to one past the buffered item. -// this would require 2 buffers per sampler, to separate current total from running total - -void ThreadRecorder::deactivate( Recording* recording ) +std::list::iterator ThreadRecorder::update( Recording* recording ) { for (std::list::iterator it = mActiveRecordings.begin(), end_it = mActiveRecordings.end(); it != end_it; @@ -92,10 +89,20 @@ void ThreadRecorder::deactivate( Recording* recording ) next_it->mBaseline.makePrimary(); mPrimaryRecording = &next_it->mBaseline; } - mActiveRecordings.erase(it); - break; + return it; } } + + return mActiveRecordings.end(); +} + +void ThreadRecorder::deactivate( Recording* recording ) +{ + std::list::iterator it = update(recording); + if (it != mActiveRecordings.end()) + { + mActiveRecordings.erase(it); + } } ThreadRecorder::ActiveRecording::ActiveRecording( Recording* source, Recording* target ) -- cgit v1.2.3 From 05510799e5a69eafcc919e72d25cf5b89c9274cf Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 9 Oct 2012 22:18:07 -0700 Subject: SH-3275 WIP Update viewer metrics system to be more flexible renamed mergeSamples to mergeRecording --- indra/llcommon/lltracethreadrecorder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index b2c6fe3b80..4d020f5650 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -161,13 +161,13 @@ void SlaveThreadRecorder::pushToMaster() void SlaveThreadRecorder::SharedData::copyFrom( const Recording& source ) { LLMutexLock lock(&mRecorderMutex); - mRecorder.mergeSamples(source); + mRecorder.mergeRecording(source); } void SlaveThreadRecorder::SharedData::copyTo( Recording& sink ) { LLMutexLock lock(&mRecorderMutex); - sink.mergeSamples(mRecorder); + sink.mergeRecording(mRecorder); } /////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 74ac0182ec8f7a0f6d0ea89f5814f0998ab90b62 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 10 Oct 2012 19:25:56 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system fixed units conversion so that trace getters return convertable units removed circular dependencies from lltrace* converted more stats to lltrace --- indra/llcommon/lltracethreadrecorder.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index b2c6fe3b80..78833835c2 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -25,7 +25,7 @@ #include "linden_common.h" -#include "lltrace.h" +#include "lltracethreadrecorder.h" namespace LLTrace { @@ -118,16 +118,16 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* source, Recording* void ThreadRecorder::ActiveRecording::mergeMeasurements(ThreadRecorder::ActiveRecording& other) { - mBaseline.mMeasurements.write()->mergeSamples(*other.mBaseline.mMeasurements); + mBaseline.mMeasurements.write()->addSamples(*other.mBaseline.mMeasurements); } void ThreadRecorder::ActiveRecording::flushAccumulators(Recording* current) { // accumulate statistics-like measurements - mTargetRecording->mMeasurements.write()->mergeSamples(*mBaseline.mMeasurements); + mTargetRecording->mMeasurements.write()->addSamples(*mBaseline.mMeasurements); // for rate-like measurements, merge total change since baseline - mTargetRecording->mRates.write()->mergeDeltas(*mBaseline.mRates, *current->mRates); - mTargetRecording->mStackTimers.write()->mergeDeltas(*mBaseline.mStackTimers, *current->mStackTimers); + mTargetRecording->mRates.write()->addDeltas(*mBaseline.mRates, *current->mRates); + mTargetRecording->mStackTimers.write()->addDeltas(*mBaseline.mStackTimers, *current->mStackTimers); // reset baselines mBaseline.mRates.write()->copyFrom(*current->mRates); mBaseline.mStackTimers.write()->copyFrom(*current->mStackTimers); @@ -161,13 +161,13 @@ void SlaveThreadRecorder::pushToMaster() void SlaveThreadRecorder::SharedData::copyFrom( const Recording& source ) { LLMutexLock lock(&mRecorderMutex); - mRecorder.mergeSamples(source); + mRecorder.addSamples(source); } void SlaveThreadRecorder::SharedData::copyTo( Recording& sink ) { LLMutexLock lock(&mRecorderMutex); - sink.mergeSamples(mRecorder); + sink.addSamples(mRecorder); } /////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 0f58ca02cdec62711eadb82ba28fcff08faef2ee Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 12 Oct 2012 00:20:19 -0700 Subject: SH-3275 WIP Update viewer metrics system to be more flexible cleaned up accumulator merging logic introduced frame recording to LLTrace directly instead of going through LLViewerStats moved consumer code over to frame recording instead of whatever the current active recording was --- indra/llcommon/lltracethreadrecorder.cpp | 73 ++++++++++++++------------------ 1 file changed, 31 insertions(+), 42 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 3acd06d553..48aa1a42f2 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -36,15 +36,13 @@ namespace LLTrace /////////////////////////////////////////////////////////////////////// ThreadRecorder::ThreadRecorder() -: mPrimaryRecording(NULL) { get_thread_recorder() = this; mFullRecording.start(); } ThreadRecorder::ThreadRecorder( const ThreadRecorder& other ) -: mFullRecording(other.mFullRecording), - mPrimaryRecording(NULL) +: mFullRecording(other.mFullRecording) { get_thread_recorder() = this; mFullRecording.start(); @@ -55,45 +53,40 @@ ThreadRecorder::~ThreadRecorder() get_thread_recorder() = NULL; } -//TODO: remove this and use llviewerstats recording -Recording* ThreadRecorder::getPrimaryRecording() -{ - return mPrimaryRecording; -} - void ThreadRecorder::activate( Recording* recording ) { - mActiveRecordings.push_front(ActiveRecording(mPrimaryRecording, recording)); + mActiveRecordings.push_front(ActiveRecording(recording)); mActiveRecordings.front().mBaseline.makePrimary(); - mPrimaryRecording = &mActiveRecordings.front().mBaseline; } std::list::iterator ThreadRecorder::update( Recording* recording ) { - for (std::list::iterator it = mActiveRecordings.begin(), end_it = mActiveRecordings.end(); + std::list::iterator it, end_it; + for (it = mActiveRecordings.begin(), end_it = mActiveRecordings.end(); it != end_it; ++it) { std::list::iterator next_it = it; - if (++next_it != mActiveRecordings.end()) + ++next_it; + + // if we have another recording further down in the stack... + if (next_it != mActiveRecordings.end()) { - next_it->mergeMeasurements((*it)); + // ...push our gathered data down to it + next_it->mBaseline.mergeRecording(it->mBaseline); } - it->flushAccumulators(mPrimaryRecording); + // copy accumulated measurements into result buffer and clear accumulator (mBaseline) + it->moveBaselineToTarget(); if (it->mTargetRecording == recording) { - if (next_it != mActiveRecordings.end()) - { - next_it->mBaseline.makePrimary(); - mPrimaryRecording = &next_it->mBaseline; - } - return it; + // found the recording, so return it + break; } } - return mActiveRecordings.end(); + return it; } void ThreadRecorder::deactivate( Recording* recording ) @@ -101,38 +94,34 @@ void ThreadRecorder::deactivate( Recording* recording ) std::list::iterator it = update(recording); if (it != mActiveRecordings.end()) { + // and if we've found the recording we wanted to update + std::list::iterator next_it = it; + ++next_it; + if (next_it != mActiveRecordings.end()) + { + next_it->mTargetRecording->makePrimary(); + } + mActiveRecordings.erase(it); } } -ThreadRecorder::ActiveRecording::ActiveRecording( Recording* source, Recording* target ) +ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target ) : mTargetRecording(target) { - // take snapshots of current values rates and timers - if (source) - { - mBaseline.mRates.write()->copyFrom(*source->mRates); - mBaseline.mStackTimers.write()->copyFrom(*source->mStackTimers); - } } -void ThreadRecorder::ActiveRecording::mergeMeasurements(ThreadRecorder::ActiveRecording& other) +void ThreadRecorder::ActiveRecording::moveBaselineToTarget() { - mBaseline.mMeasurements.write()->addSamples(*other.mBaseline.mMeasurements); -} - -void ThreadRecorder::ActiveRecording::flushAccumulators(Recording* current) -{ - // accumulate statistics-like measurements mTargetRecording->mMeasurements.write()->addSamples(*mBaseline.mMeasurements); - // for rate-like measurements, merge total change since baseline - mTargetRecording->mRates.write()->addDeltas(*mBaseline.mRates, *current->mRates); - mTargetRecording->mStackTimers.write()->addDeltas(*mBaseline.mStackTimers, *current->mStackTimers); - // reset baselines - mBaseline.mRates.write()->copyFrom(*current->mRates); - mBaseline.mStackTimers.write()->copyFrom(*current->mStackTimers); + mTargetRecording->mRates.write()->addSamples(*mBaseline.mRates); + mTargetRecording->mStackTimers.write()->addSamples(*mBaseline.mStackTimers); + mBaseline.mMeasurements.write()->reset(); + mBaseline.mRates.write()->reset(); + mBaseline.mStackTimers.write()->reset(); } + /////////////////////////////////////////////////////////////////////// // SlaveThreadRecorder /////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 041dfccd1ea5b59c1b3c4e37e9a5495cad342c8f Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 12 Oct 2012 20:17:52 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system default to double precision now fixed unit conversion logic for LLUnit renamed LLTrace::Rate to LLTrace::Count and got rid of the old count as it was confusing some const correctness changes --- indra/llcommon/lltracethreadrecorder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 48aa1a42f2..02dc55771b 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -114,10 +114,10 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target ) void ThreadRecorder::ActiveRecording::moveBaselineToTarget() { mTargetRecording->mMeasurements.write()->addSamples(*mBaseline.mMeasurements); - mTargetRecording->mRates.write()->addSamples(*mBaseline.mRates); + mTargetRecording->mCounts.write()->addSamples(*mBaseline.mCounts); mTargetRecording->mStackTimers.write()->addSamples(*mBaseline.mStackTimers); mBaseline.mMeasurements.write()->reset(); - mBaseline.mRates.write()->reset(); + mBaseline.mCounts.write()->reset(); mBaseline.mStackTimers.write()->reset(); } -- cgit v1.2.3 From 1fadd6138eebf980776f80b9642f4c19279fcadd Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 18 Oct 2012 17:32:44 -0700 Subject: SH-3405 WIP convert existing stats to lltrace system fixed trace recording on background threads hitting null pointer --- indra/llcommon/lltracethreadrecorder.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 02dc55771b..e81333f7f2 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -127,7 +127,6 @@ void ThreadRecorder::ActiveRecording::moveBaselineToTarget() /////////////////////////////////////////////////////////////////////// SlaveThreadRecorder::SlaveThreadRecorder() -: ThreadRecorder(getMasterThreadRecorder()) { getMasterThreadRecorder().addSlaveThread(this); } @@ -149,14 +148,14 @@ void SlaveThreadRecorder::pushToMaster() void SlaveThreadRecorder::SharedData::copyFrom( const Recording& source ) { - LLMutexLock lock(&mRecorderMutex); - mRecorder.mergeRecording(source); + LLMutexLock lock(&mRecordingMutex); + mRecording.mergeRecording(source); } void SlaveThreadRecorder::SharedData::copyTo( Recording& sink ) { - LLMutexLock lock(&mRecorderMutex); - sink.mergeRecording(mRecorder); + LLMutexLock lock(&mRecordingMutex); + sink.mergeRecording(mRecording); } /////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 819adb5eb4d7f982121f3dbd82750e05d26864d9 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 1 Nov 2012 00:26:44 -0700 Subject: SH-3405 FIX convert existing stats to lltrace system final removal of remaining LLStat code --- indra/llcommon/lltracethreadrecorder.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') 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(); -- cgit v1.2.3 From 74fe126590fba03752d1d8d88dd3bb59c6900026 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 1 Nov 2012 17:52:11 -0700 Subject: SH-3405 FIX convert existing stats to lltrace system output of floater_stats is now identical to pre-lltrace system (with some tweaks) --- indra/llcommon/lltracethreadrecorder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 15056b80e4..0feb3ab7af 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -73,7 +73,7 @@ std::list::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) @@ -153,13 +153,13 @@ void SlaveThreadRecorder::pushToMaster() void SlaveThreadRecorder::SharedData::copyFrom( const Recording& source ) { LLMutexLock lock(&mRecordingMutex); - mRecording.mergeRecording(source); + mRecording.appendRecording(source); } void SlaveThreadRecorder::SharedData::copyTo( Recording& sink ) { LLMutexLock lock(&mRecordingMutex); - sink.mergeRecording(mRecording); + sink.appendRecording(mRecording); } /////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 0007114cf5a60779319ab8cbd0a23a0d462b8010 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 5 Nov 2012 16:10:57 -0800 Subject: SH-3499 WIP Ensure asset stats output is correct fixed copy behavior of recordings and accumulator buffers --- indra/llcommon/lltracethreadrecorder.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 0feb3ab7af..af66a69492 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -86,6 +86,11 @@ std::list::iterator ThreadRecorder::update( Rec } } + if (it == end_it) + { + llerrs << "Recording not active on this thread" << llendl; + } + return it; } -- cgit v1.2.3 From 860ff2f7e2a7fe932dfb7c148f0dbc0067018038 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 7 Nov 2012 00:38:21 -0800 Subject: SH-3499 WIP Ensure asset stats output is correct fixed trace data gathering and routing from background thread simplified slave->master thread communication (eliminated redundant recording and proxy object) improved performance of fast timer data gathering (slow iterators) --- indra/llcommon/lltracethreadrecorder.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index af66a69492..5a6ff14f97 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -171,15 +171,20 @@ void SlaveThreadRecorder::SharedData::copyTo( Recording& sink ) // 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); + (*it)->mSharedData.copyTo(target_recording); } } @@ -187,7 +192,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 ) @@ -198,7 +203,7 @@ void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child ) it != end_it; ++it) { - if ((*it)->mRecorder == child) + if ((*it) == child) { mSlaveThreadRecorders.erase(it); break; @@ -212,12 +217,4 @@ void MasterThreadRecorder::pushToMaster() MasterThreadRecorder::MasterThreadRecorder() {} -/////////////////////////////////////////////////////////////////////// -// MasterThreadRecorder::SlaveThreadTraceProxy -/////////////////////////////////////////////////////////////////////// - -MasterThreadRecorder::SlaveThreadRecorderProxy::SlaveThreadRecorderProxy( class SlaveThreadRecorder* recorder) -: mRecorder(recorder) -{} - } -- cgit v1.2.3 From 9d77e030d9a0d23cebce616631677459eec1612c Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 14 Nov 2012 23:52:27 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system cleaning up build moved most includes of windows.h to llwin32headers.h to disable min/max macros, etc streamlined Time class and consolidated functionality in BlockTimer class llfasttimer is no longer included via llstring.h, so had to add it manually in several places --- indra/llcommon/lltracethreadrecorder.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 5a6ff14f97..0f111aab59 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 { -- cgit v1.2.3 From 6db6cb39f41e921e75970d1570a74cf35d353a35 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 16 Nov 2012 23:02:53 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system got new fast timer code to compile and run --- indra/llcommon/lltracethreadrecorder.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 0f111aab59..c2fefe2957 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -40,6 +40,8 @@ ThreadRecorder::ThreadRecorder() { get_thread_recorder() = this; mFullRecording.start(); + + BlockTimer::sCurTimerData = new CurTimerData(); } ThreadRecorder::ThreadRecorder( const ThreadRecorder& other ) @@ -52,6 +54,8 @@ ThreadRecorder::ThreadRecorder( const ThreadRecorder& other ) ThreadRecorder::~ThreadRecorder() { get_thread_recorder() = NULL; + delete BlockTimer::sCurTimerData.get(); + BlockTimer::sCurTimerData = NULL; } void ThreadRecorder::activate( Recording* recording ) -- cgit v1.2.3 From 1c894c05c10ef37be6507ee4bc4e9173506adfb6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 27 Nov 2012 17:26:12 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system hunting down bad values and crashes --- indra/llcommon/lltracethreadrecorder.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index c2fefe2957..faaab4c8e7 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -53,6 +53,10 @@ ThreadRecorder::ThreadRecorder( const ThreadRecorder& other ) ThreadRecorder::~ThreadRecorder() { + while(mActiveRecordings.size()) + { + mActiveRecordings.front().mTargetRecording->stop(); + } get_thread_recorder() = NULL; delete BlockTimer::sCurTimerData.get(); BlockTimer::sCurTimerData = NULL; -- cgit v1.2.3 From 02d503bf8f8890c6d4b57dd09a1fde2973715b75 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 29 Nov 2012 00:43:25 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system moved runtime timer tree topology information to separate array instead of recording stack --- indra/llcommon/lltracethreadrecorder.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index faaab4c8e7..0a2d79cf3a 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -41,25 +41,29 @@ ThreadRecorder::ThreadRecorder() get_thread_recorder() = this; mFullRecording.start(); - BlockTimer::sCurTimerData = new CurTimerData(); -} + mRootTimerData = new CurTimerData(); + mRootTimerData->mTimerData = &BlockTimer::getRootTimer(); + mRootTimerData->mTimerTreeData = new TimerTreeNode[AccumulatorBuffer::getDefaultBuffer().size()]; + BlockTimer::sCurTimerData = mRootTimerData; -ThreadRecorder::ThreadRecorder( const ThreadRecorder& other ) -: mFullRecording(other.mFullRecording) -{ - get_thread_recorder() = this; - mFullRecording.start(); + mRootTimer = new Time(BlockTimer::getRootTimer()); + mRootTimerData->mCurTimer = mRootTimer; + + mRootTimerData->mTimerTreeData[BlockTimer::getRootTimer().getIndex()].mActiveCount = 1; } ThreadRecorder::~ThreadRecorder() { + delete mRootTimer; + while(mActiveRecordings.size()) { mActiveRecordings.front().mTargetRecording->stop(); } get_thread_recorder() = NULL; - delete BlockTimer::sCurTimerData.get(); BlockTimer::sCurTimerData = NULL; + delete [] mRootTimerData->mTimerTreeData; + delete mRootTimerData; } void ThreadRecorder::activate( Recording* recording ) -- cgit v1.2.3 From 407e5013f3845208e0a60e26e8f0a7fad997df5d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 3 Dec 2012 19:54:53 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system converted fast timer view over to new lltrace mechanisms --- indra/llcommon/lltracethreadrecorder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 0a2d79cf3a..16235473ee 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -42,14 +42,14 @@ ThreadRecorder::ThreadRecorder() mFullRecording.start(); mRootTimerData = new CurTimerData(); - mRootTimerData->mTimerData = &BlockTimer::getRootTimer(); - mRootTimerData->mTimerTreeData = new TimerTreeNode[AccumulatorBuffer::getDefaultBuffer().size()]; - BlockTimer::sCurTimerData = mRootTimerData; + mRootTimerData->mTimerData = &TimeBlock::getRootTimer(); + mRootTimerData->mTimerTreeData = new TimeBlockTreeNode[AccumulatorBuffer::getDefaultBuffer().size()]; + TimeBlock::sCurTimerData = mRootTimerData; - mRootTimer = new Time(BlockTimer::getRootTimer()); + mRootTimer = new BlockTimer(TimeBlock::getRootTimer()); mRootTimerData->mCurTimer = mRootTimer; - mRootTimerData->mTimerTreeData[BlockTimer::getRootTimer().getIndex()].mActiveCount = 1; + mRootTimerData->mTimerTreeData[TimeBlock::getRootTimer().getIndex()].mActiveCount = 1; } ThreadRecorder::~ThreadRecorder() @@ -61,7 +61,7 @@ ThreadRecorder::~ThreadRecorder() mActiveRecordings.front().mTargetRecording->stop(); } get_thread_recorder() = NULL; - BlockTimer::sCurTimerData = NULL; + TimeBlock::sCurTimerData = NULL; delete [] mRootTimerData->mTimerTreeData; delete mRootTimerData; } -- cgit v1.2.3 From c219282f5de753a044cecb53bd806145f68add9a Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 18 Dec 2012 20:07:25 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system removed some potential data races got memory stats recording in trace system --- indra/llcommon/lltracethreadrecorder.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 16235473ee..c4144b4999 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -43,13 +43,20 @@ ThreadRecorder::ThreadRecorder() mRootTimerData = new CurTimerData(); mRootTimerData->mTimerData = &TimeBlock::getRootTimer(); - mRootTimerData->mTimerTreeData = new TimeBlockTreeNode[AccumulatorBuffer::getDefaultBuffer().size()]; + TimeBlock::sCurTimerData = mRootTimerData; + TimeBlock::getRootTimer().getPrimaryAccumulator().mActiveCount = 1; + + // initialize parent pointers in time blocks + for (LLInstanceTracker::instance_iter it = LLInstanceTracker::beginInstances(), end_it = LLInstanceTracker::endInstances(); + it != end_it; + ++it) + { + it->getPrimaryAccumulator().mParent = it->mParent; + } mRootTimer = new BlockTimer(TimeBlock::getRootTimer()); mRootTimerData->mCurTimer = mRootTimer; - - mRootTimerData->mTimerTreeData[TimeBlock::getRootTimer().getIndex()].mActiveCount = 1; } ThreadRecorder::~ThreadRecorder() @@ -62,7 +69,6 @@ ThreadRecorder::~ThreadRecorder() } get_thread_recorder() = NULL; TimeBlock::sCurTimerData = NULL; - delete [] mRootTimerData->mTimerTreeData; delete mRootTimerData; } -- cgit v1.2.3 From 013f04cabec8e110ee659d9b3f75a4d25f114b7b Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 21 Dec 2012 00:13:21 -0800 Subject: SH-3468 WIP add memory tracking base class improvements on lifetime of lltrace core data structures tweaks to thread local pointer handling so that static constructors/destructors can safely call functions that use lltrace --- indra/llcommon/lltracethreadrecorder.cpp | 71 +++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 10 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index c4144b4999..156b0ef26b 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -38,25 +38,37 @@ namespace LLTrace ThreadRecorder::ThreadRecorder() { + //NB: the ordering of initialization in this function is very fragile due to a large number of implicit dependencies get_thread_recorder() = this; - mFullRecording.start(); mRootTimerData = new CurTimerData(); mRootTimerData->mTimerData = &TimeBlock::getRootTimer(); - TimeBlock::sCurTimerData = mRootTimerData; - TimeBlock::getRootTimer().getPrimaryAccumulator().mActiveCount = 1; - // initialize parent pointers in time blocks + mNumTimeBlockTreeNodes = AccumulatorBuffer::getDefaultBuffer()->size(); + mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes]; + + mFullRecording.start(); + + TimeBlock& root_timer = TimeBlock::getRootTimer(); + + // initialize time block parent pointers for (LLInstanceTracker::instance_iter it = LLInstanceTracker::beginInstances(), end_it = LLInstanceTracker::endInstances(); it != end_it; ++it) { - it->getPrimaryAccumulator().mParent = it->mParent; + TimeBlock& time_block = *it; + TimeBlockTreeNode& tree_node = mTimeBlockTreeNodes[it->getIndex()]; + tree_node.mBlock = &time_block; + tree_node.mParent = &root_timer; + + it->getPrimaryAccumulator()->mParent = &root_timer; } - mRootTimer = new BlockTimer(TimeBlock::getRootTimer()); + mRootTimer = new BlockTimer(root_timer); mRootTimerData->mCurTimer = mRootTimer; + + TimeBlock::getRootTimer().getPrimaryAccumulator()->mActiveCount = 1; } ThreadRecorder::~ThreadRecorder() @@ -70,8 +82,19 @@ ThreadRecorder::~ThreadRecorder() get_thread_recorder() = NULL; TimeBlock::sCurTimerData = NULL; delete mRootTimerData; + delete[] mTimeBlockTreeNodes; } +TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index) +{ + if (0 <= index && index < mNumTimeBlockTreeNodes) + { + return &mTimeBlockTreeNodes[index]; + } + return NULL; +} + + void ThreadRecorder::activate( Recording* recording ) { mActiveRecordings.push_front(ActiveRecording(recording)); @@ -113,6 +136,13 @@ std::list::iterator ThreadRecorder::update( Rec return it; } +AccumulatorBuffer > gCountsFloat; +AccumulatorBuffer > gMeasurementsFloat; +AccumulatorBuffer > gCounts; +AccumulatorBuffer > gMeasurements; +AccumulatorBuffer gStackTimers; +AccumulatorBuffer gMemStats; + void ThreadRecorder::deactivate( Recording* recording ) { std::list::iterator it = update(recording); @@ -169,23 +199,42 @@ void SlaveThreadRecorder::pushToMaster() mFullRecording.stop(); { LLMutexLock(getMasterThreadRecorder().getSlaveListMutex()); - mSharedData.copyFrom(mFullRecording); + mSharedData.appendFrom(mFullRecording); } mFullRecording.start(); } -void SlaveThreadRecorder::SharedData::copyFrom( const Recording& source ) +void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source ) { LLMutexLock lock(&mRecordingMutex); mRecording.appendRecording(source); } -void SlaveThreadRecorder::SharedData::copyTo( Recording& sink ) +void SlaveThreadRecorder::SharedData::appendTo( Recording& sink ) { LLMutexLock lock(&mRecordingMutex); sink.appendRecording(mRecording); } +void SlaveThreadRecorder::SharedData::mergeFrom( const Recording& source ) +{ + 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 /////////////////////////////////////////////////////////////////////// @@ -203,7 +252,9 @@ void MasterThreadRecorder::pullFromSlaveThreads() it != end_it; ++it) { - (*it)->mSharedData.copyTo(target_recording); + // ignore block timing info for now + (*it)->mSharedData.mergeTo(target_recording); + (*it)->mSharedData.reset(); } } -- cgit v1.2.3 From cda2cdda511eb2f7a58e284db2c852fd4a3808ae Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 3 Jan 2013 00:30:54 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system made fast timer stack thread local added LLThreadLocalSingleton made LLThreadLocalPointer obey pointer rules for const added LLThreadLocalSingletonPointer for fast thread local pointers --- indra/llcommon/lltracethreadrecorder.cpp | 33 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 18 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 156b0ef26b..9fb789c62d 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -39,18 +39,17 @@ namespace LLTrace ThreadRecorder::ThreadRecorder() { //NB: the ordering of initialization in this function is very fragile due to a large number of implicit dependencies - get_thread_recorder() = this; + set_thread_recorder(this); + TimeBlock& root_time_block = TimeBlock::getRootTimeBlock(); - mRootTimerData = new CurTimerData(); - mRootTimerData->mTimerData = &TimeBlock::getRootTimer(); - TimeBlock::sCurTimerData = mRootTimerData; + ThreadTimerStack* timer_stack = ThreadTimerStack::getInstance(); + timer_stack->mTimeBlock = &root_time_block; + timer_stack->mActiveTimer = NULL; mNumTimeBlockTreeNodes = AccumulatorBuffer::getDefaultBuffer()->size(); mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes]; - mFullRecording.start(); - - TimeBlock& root_timer = TimeBlock::getRootTimer(); + mThreadRecording.start(); // initialize time block parent pointers for (LLInstanceTracker::instance_iter it = LLInstanceTracker::beginInstances(), end_it = LLInstanceTracker::endInstances(); @@ -60,15 +59,15 @@ ThreadRecorder::ThreadRecorder() TimeBlock& time_block = *it; TimeBlockTreeNode& tree_node = mTimeBlockTreeNodes[it->getIndex()]; tree_node.mBlock = &time_block; - tree_node.mParent = &root_timer; + tree_node.mParent = &root_time_block; - it->getPrimaryAccumulator()->mParent = &root_timer; + it->getPrimaryAccumulator()->mParent = &root_time_block; } - mRootTimer = new BlockTimer(root_timer); - mRootTimerData->mCurTimer = mRootTimer; + mRootTimer = new BlockTimer(root_time_block); + timer_stack->mActiveTimer = mRootTimer; - TimeBlock::getRootTimer().getPrimaryAccumulator()->mActiveCount = 1; + TimeBlock::getRootTimeBlock().getPrimaryAccumulator()->mActiveCount = 1; } ThreadRecorder::~ThreadRecorder() @@ -79,9 +78,7 @@ ThreadRecorder::~ThreadRecorder() { mActiveRecordings.front().mTargetRecording->stop(); } - get_thread_recorder() = NULL; - TimeBlock::sCurTimerData = NULL; - delete mRootTimerData; + set_thread_recorder(NULL); delete[] mTimeBlockTreeNodes; } @@ -196,12 +193,12 @@ SlaveThreadRecorder::~SlaveThreadRecorder() void SlaveThreadRecorder::pushToMaster() { - mFullRecording.stop(); + mThreadRecording.stop(); { LLMutexLock(getMasterThreadRecorder().getSlaveListMutex()); - mSharedData.appendFrom(mFullRecording); + mSharedData.appendFrom(mThreadRecording); } - mFullRecording.start(); + mThreadRecording.start(); } void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source ) -- cgit v1.2.3 From 68413515029f50713c70e4adec3ce6fd1022d59f Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 6 Jan 2013 21:37:31 -0800 Subject: SH-3468 WIP add memory tracking base class fix for unit test failures...cleanup apr without destroying pools, allowing LLProxy to clean itself up as a singleton (and avoiding spurious dependencies associated with manually destorying singletons that rely on apr pools) --- indra/llcommon/lltracethreadrecorder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 9fb789c62d..7b493a651e 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -127,7 +127,7 @@ std::list::iterator ThreadRecorder::update( Rec if (it == end_it) { - llerrs << "Recording not active on this thread" << llendl; + llwarns << "Recording not active on this thread" << llendl; } return it; -- cgit v1.2.3 From 20b2fa4052ae6789ec8894f33f4764a1f7233b24 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 14 Jan 2013 23:08:01 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system improved performance of fast timer stat gathering --- indra/llcommon/lltracethreadrecorder.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 7b493a651e..9375c7bea3 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -43,7 +43,7 @@ ThreadRecorder::ThreadRecorder() TimeBlock& root_time_block = TimeBlock::getRootTimeBlock(); ThreadTimerStack* timer_stack = ThreadTimerStack::getInstance(); - timer_stack->mTimeBlock = &root_time_block; + timer_stack->mAccumulator = root_time_block.getPrimaryAccumulator(); timer_stack->mActiveTimer = NULL; mNumTimeBlockTreeNodes = AccumulatorBuffer::getDefaultBuffer()->size(); @@ -61,7 +61,9 @@ ThreadRecorder::ThreadRecorder() tree_node.mBlock = &time_block; tree_node.mParent = &root_time_block; - it->getPrimaryAccumulator()->mParent = &root_time_block; + TimeBlockAccumulator* accumulator = it->getPrimaryAccumulator(); + accumulator->mParent = &root_time_block; + accumulator->mBlock = time_block; } mRootTimer = new BlockTimer(root_time_block); -- cgit v1.2.3 From 486743e77efaa3926ddc2c0d666a0a7192700475 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 14 Jan 2013 23:10:02 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system improved performance of fast timer stat gathering (fixed typo) --- indra/llcommon/lltracethreadrecorder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 9375c7bea3..bc1d19e72c 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -63,7 +63,7 @@ ThreadRecorder::ThreadRecorder() TimeBlockAccumulator* accumulator = it->getPrimaryAccumulator(); accumulator->mParent = &root_time_block; - accumulator->mBlock = time_block; + accumulator->mBlock = &time_block; } mRootTimer = new BlockTimer(root_time_block); -- cgit v1.2.3 From 43a92d01afdb4f1dd4003059b79f87e9687527a1 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 17 Jan 2013 20:11:43 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system fixed some uninitialized variables root timer accumulator was being initialized to NULL --- indra/llcommon/lltracethreadrecorder.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index bc1d19e72c..7c5995a104 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -43,14 +43,16 @@ ThreadRecorder::ThreadRecorder() TimeBlock& root_time_block = TimeBlock::getRootTimeBlock(); ThreadTimerStack* timer_stack = ThreadTimerStack::getInstance(); - timer_stack->mAccumulator = root_time_block.getPrimaryAccumulator(); - timer_stack->mActiveTimer = NULL; mNumTimeBlockTreeNodes = AccumulatorBuffer::getDefaultBuffer()->size(); mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes]; mThreadRecording.start(); + timer_stack->mAccumulator = root_time_block.getPrimaryAccumulator(); + timer_stack->mActiveTimer = NULL; + + // initialize time block parent pointers for (LLInstanceTracker::instance_iter it = LLInstanceTracker::beginInstances(), end_it = LLInstanceTracker::endInstances(); it != end_it; -- cgit v1.2.3 From e975ae35ab57f56adfaed64bc108240a5013f040 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 18 Jan 2013 15:59:16 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system fixed crash on startup --- indra/llcommon/lltracethreadrecorder.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 7c5995a104..7b493a651e 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -43,16 +43,14 @@ ThreadRecorder::ThreadRecorder() TimeBlock& root_time_block = TimeBlock::getRootTimeBlock(); ThreadTimerStack* timer_stack = ThreadTimerStack::getInstance(); + timer_stack->mTimeBlock = &root_time_block; + timer_stack->mActiveTimer = NULL; mNumTimeBlockTreeNodes = AccumulatorBuffer::getDefaultBuffer()->size(); mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes]; mThreadRecording.start(); - timer_stack->mAccumulator = root_time_block.getPrimaryAccumulator(); - timer_stack->mActiveTimer = NULL; - - // initialize time block parent pointers for (LLInstanceTracker::instance_iter it = LLInstanceTracker::beginInstances(), end_it = LLInstanceTracker::endInstances(); it != end_it; @@ -63,9 +61,7 @@ ThreadRecorder::ThreadRecorder() tree_node.mBlock = &time_block; tree_node.mParent = &root_time_block; - TimeBlockAccumulator* accumulator = it->getPrimaryAccumulator(); - accumulator->mParent = &root_time_block; - accumulator->mBlock = &time_block; + it->getPrimaryAccumulator()->mParent = &root_time_block; } mRootTimer = new BlockTimer(root_time_block); -- cgit v1.2.3 From 2c68d5367c5c44aceb4ff23d9672c35642e030f7 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 27 Jan 2013 21:35:20 -0800 Subject: SH-3275 WIP interesting Update viewer metrics system to be more flexible fixed memory leak fixed glitching of fast timer display --- indra/llcommon/lltracethreadrecorder.cpp | 33 +++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') 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::iterator ThreadRecorder::update( Recording* recording ) +ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Recording* recording ) { - std::list::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::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 gMemStats; void ThreadRecorder::deactivate( Recording* recording ) { - std::list::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::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) -- cgit v1.2.3 From 1a256eca280e41a672fc87e083db851ab180612c Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 11 Mar 2013 00:37:50 -0700 Subject: renamed some variables/methods in LLTrace to make things clearer --- indra/llcommon/lltracethreadrecorder.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 113febcca8..d540a60308 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -97,11 +97,11 @@ void ThreadRecorder::activate( Recording* recording ) ActiveRecording* active_recording = new ActiveRecording(recording); if (!mActiveRecordings.empty()) { - mActiveRecordings.front()->mBaseline.syncTo(active_recording->mBaseline); + mActiveRecordings.front()->mPartialRecording.handOffTo(active_recording->mPartialRecording); } mActiveRecordings.push_front(active_recording); - mActiveRecordings.front()->mBaseline.makePrimary(); + mActiveRecordings.front()->mPartialRecording.makePrimary(); } ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Recording* recording ) @@ -118,10 +118,10 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Record if (next_it != mActiveRecordings.end()) { // ...push our gathered data down to it - (*next_it)->mBaseline.appendRecording((*it)->mBaseline); + (*next_it)->mPartialRecording.appendRecording((*it)->mPartialRecording); } - // copy accumulated measurements into result buffer and clear accumulator (mBaseline) + // copy accumulated measurements into result buffer and clear accumulator (mPartialRecording) (*it)->moveBaselineToTarget(); if ((*it)->mTargetRecording == recording) @@ -171,16 +171,16 @@ 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(); + mTargetRecording->mMeasurementsFloat.write()->addSamples(*mPartialRecording.mMeasurementsFloat); + mTargetRecording->mCountsFloat.write()->addSamples(*mPartialRecording.mCountsFloat); + mTargetRecording->mMeasurements.write()->addSamples(*mPartialRecording.mMeasurements); + mTargetRecording->mCounts.write()->addSamples(*mPartialRecording.mCounts); + mTargetRecording->mStackTimers.write()->addSamples(*mPartialRecording.mStackTimers); + mPartialRecording.mMeasurementsFloat.write()->reset(); + mPartialRecording.mCountsFloat.write()->reset(); + mPartialRecording.mMeasurements.write()->reset(); + mPartialRecording.mCounts.write()->reset(); + mPartialRecording.mStackTimers.write()->reset(); } @@ -251,7 +251,7 @@ void MasterThreadRecorder::pullFromSlaveThreads() LLMutexLock lock(&mSlaveListMutex); - Recording& target_recording = mActiveRecordings.front()->mBaseline; + Recording& target_recording = mActiveRecordings.front()->mPartialRecording; for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); it != end_it; ++it) -- cgit v1.2.3 From b9c78533ae701fe6af5263e902f8df93c558e493 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 11 Mar 2013 01:09:48 -0700 Subject: separated RecordingBuffers from Recording to make active recording stack more safe (part 2) --- indra/llcommon/lltracethreadrecorder.cpp | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index d540a60308..9bef040cf7 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -118,7 +118,7 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Record if (next_it != mActiveRecordings.end()) { // ...push our gathered data down to it - (*next_it)->mPartialRecording.appendRecording((*it)->mPartialRecording); + (*next_it)->mPartialRecording.appendBuffers((*it)->mPartialRecording); } // copy accumulated measurements into result buffer and clear accumulator (mPartialRecording) @@ -171,16 +171,8 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target ) void ThreadRecorder::ActiveRecording::moveBaselineToTarget() { - mTargetRecording->mMeasurementsFloat.write()->addSamples(*mPartialRecording.mMeasurementsFloat); - mTargetRecording->mCountsFloat.write()->addSamples(*mPartialRecording.mCountsFloat); - mTargetRecording->mMeasurements.write()->addSamples(*mPartialRecording.mMeasurements); - mTargetRecording->mCounts.write()->addSamples(*mPartialRecording.mCounts); - mTargetRecording->mStackTimers.write()->addSamples(*mPartialRecording.mStackTimers); - mPartialRecording.mMeasurementsFloat.write()->reset(); - mPartialRecording.mCountsFloat.write()->reset(); - mPartialRecording.mMeasurements.write()->reset(); - mPartialRecording.mCounts.write()->reset(); - mPartialRecording.mStackTimers.write()->reset(); + mTargetRecording->appendBuffers(mPartialRecording); + mPartialRecording.resetBuffers(); } @@ -220,16 +212,16 @@ void SlaveThreadRecorder::SharedData::appendTo( Recording& sink ) sink.appendRecording(mRecording); } -void SlaveThreadRecorder::SharedData::mergeFrom( const Recording& source ) +void SlaveThreadRecorder::SharedData::mergeFrom( const RecordingBuffers& source ) { LLMutexLock lock(&mRecordingMutex); - mRecording.mergeRecording(source); + mRecording.mergeBuffers(source); } -void SlaveThreadRecorder::SharedData::mergeTo( Recording& sink ) +void SlaveThreadRecorder::SharedData::mergeTo( RecordingBuffers& sink ) { LLMutexLock lock(&mRecordingMutex); - sink.mergeRecording(mRecording); + sink.mergeBuffers(mRecording); } void SlaveThreadRecorder::SharedData::reset() @@ -251,13 +243,13 @@ void MasterThreadRecorder::pullFromSlaveThreads() LLMutexLock lock(&mSlaveListMutex); - Recording& target_recording = mActiveRecordings.front()->mPartialRecording; + RecordingBuffers& target_recording_buffers = mActiveRecordings.front()->mPartialRecording; for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); it != end_it; ++it) { // ignore block timing info for now - (*it)->mSharedData.mergeTo(target_recording); + (*it)->mSharedData.mergeTo(target_recording_buffers); (*it)->mSharedData.reset(); } } -- cgit v1.2.3 From ab5106535758393e02b075d1e404e4e1fcf81abf Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 20 May 2013 19:27:50 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics removed extra dereference for copy on write pointer moved copyonwrite mechanism to RecordingBuffers from individual buffer fixed logic that was leaving scene unfrozen when camera moved during metrics gathering --- indra/llcommon/lltracethreadrecorder.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 9bef040cf7..2001b9cd7f 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -118,7 +118,7 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Record if (next_it != mActiveRecordings.end()) { // ...push our gathered data down to it - (*next_it)->mPartialRecording.appendBuffers((*it)->mPartialRecording); + (*next_it)->mPartialRecording.append((*it)->mPartialRecording); } // copy accumulated measurements into result buffer and clear accumulator (mPartialRecording) @@ -156,7 +156,7 @@ void ThreadRecorder::deactivate( Recording* recording ) ++next_it; if (next_it != mActiveRecordings.end()) { - (*next_it)->mTargetRecording->makePrimary(); + (*next_it)->mTargetRecording->mBuffers.write()->makePrimary(); } delete *it; @@ -171,8 +171,8 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target ) void ThreadRecorder::ActiveRecording::moveBaselineToTarget() { - mTargetRecording->appendBuffers(mPartialRecording); - mPartialRecording.resetBuffers(); + mTargetRecording->mBuffers.write()->append(mPartialRecording); + mPartialRecording.reset(); } @@ -203,31 +203,31 @@ void SlaveThreadRecorder::pushToMaster() void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source ) { LLMutexLock lock(&mRecordingMutex); - mRecording.appendRecording(source); + appendRecording(source); } void SlaveThreadRecorder::SharedData::appendTo( Recording& sink ) { LLMutexLock lock(&mRecordingMutex); - sink.appendRecording(mRecording); + sink.appendRecording(*this); } void SlaveThreadRecorder::SharedData::mergeFrom( const RecordingBuffers& source ) { LLMutexLock lock(&mRecordingMutex); - mRecording.mergeBuffers(source); + mBuffers.write()->merge(source); } void SlaveThreadRecorder::SharedData::mergeTo( RecordingBuffers& sink ) { LLMutexLock lock(&mRecordingMutex); - sink.mergeBuffers(mRecording); + sink.merge(*mBuffers); } void SlaveThreadRecorder::SharedData::reset() { LLMutexLock lock(&mRecordingMutex); - mRecording.reset(); + Recording::reset(); } -- cgit v1.2.3 From 9ae76d12157641033431381959ef4f798a119b8d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 29 May 2013 17:00:50 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics fixed copy construction behavior of Recordings to not zero out data split measurement into event and sample, with sample representing a continuous function --- indra/llcommon/lltracethreadrecorder.cpp | 78 ++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 33 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 2001b9cd7f..75c7cb2ff1 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -74,10 +74,12 @@ ThreadRecorder::~ThreadRecorder() { delete mRootTimer; - while(mActiveRecordings.size()) + if (!mActiveRecordings.empty()) { - mActiveRecordings.front()->mTargetRecording->stop(); + std::for_each(mActiveRecordings.begin(), mActiveRecordings.end(), DeletePointer()); + mActiveRecordings.clear(); } + set_thread_recorder(NULL); delete[] mTimeBlockTreeNodes; } @@ -97,34 +99,40 @@ void ThreadRecorder::activate( Recording* recording ) ActiveRecording* active_recording = new ActiveRecording(recording); if (!mActiveRecordings.empty()) { - mActiveRecordings.front()->mPartialRecording.handOffTo(active_recording->mPartialRecording); + mActiveRecordings.back()->mPartialRecording.handOffTo(active_recording->mPartialRecording); } - mActiveRecordings.push_front(active_recording); + mActiveRecordings.push_back(active_recording); - mActiveRecordings.front()->mPartialRecording.makePrimary(); + mActiveRecordings.back()->mPartialRecording.makePrimary(); } -ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Recording* recording ) +ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( Recording* recording ) { - active_recording_list_t::iterator it, end_it; - for (it = mActiveRecordings.begin(), end_it = mActiveRecordings.end(); + if (mActiveRecordings.empty()) return mActiveRecordings.rend(); + + mActiveRecordings.back()->mPartialRecording.flush(); + + active_recording_list_t::reverse_iterator it, end_it; + for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend(); it != end_it; ++it) { - active_recording_list_t::iterator next_it = it; + ActiveRecording* cur_recording = *it; + + active_recording_list_t::reverse_iterator next_it = it; ++next_it; // if we have another recording further down in the stack... - if (next_it != mActiveRecordings.end()) + if (next_it != mActiveRecordings.rend()) { // ...push our gathered data down to it - (*next_it)->mPartialRecording.append((*it)->mPartialRecording); + (*next_it)->mPartialRecording.append(cur_recording->mPartialRecording); } // copy accumulated measurements into result buffer and clear accumulator (mPartialRecording) - (*it)->moveBaselineToTarget(); + cur_recording->movePartialToTarget(); - if ((*it)->mTargetRecording == recording) + if (cur_recording->mTargetRecording == recording) { // found the recording, so return it break; @@ -139,28 +147,30 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::update( Record return it; } -AccumulatorBuffer > gCountsFloat; -AccumulatorBuffer > gMeasurementsFloat; -AccumulatorBuffer > gCounts; -AccumulatorBuffer > gMeasurements; -AccumulatorBuffer gStackTimers; -AccumulatorBuffer gMemStats; +AccumulatorBuffer > gCountsFloat; +AccumulatorBuffer > gMeasurementsFloat; +AccumulatorBuffer > gCounts; +AccumulatorBuffer > gMeasurements; +AccumulatorBuffer gStackTimers; +AccumulatorBuffer gMemStats; void ThreadRecorder::deactivate( Recording* recording ) { - active_recording_list_t::iterator it = update(recording); - if (it != mActiveRecordings.end()) + active_recording_list_t::reverse_iterator it = bringUpToDate(recording); + if (it != mActiveRecordings.rend()) { // and if we've found the recording we wanted to update - active_recording_list_t::iterator next_it = it; + active_recording_list_t::reverse_iterator next_it = it; ++next_it; - if (next_it != mActiveRecordings.end()) + if (next_it != mActiveRecordings.rend()) { - (*next_it)->mTargetRecording->mBuffers.write()->makePrimary(); + (*next_it)->mPartialRecording.makePrimary(); } - delete *it; - mActiveRecordings.erase(it); + active_recording_list_t::iterator recording_to_remove = (++it).base(); + llassert((*recording_to_remove)->mTargetRecording == recording); + delete *recording_to_remove; + mActiveRecordings.erase(recording_to_remove); } } @@ -169,10 +179,11 @@ ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target ) { } -void ThreadRecorder::ActiveRecording::moveBaselineToTarget() +void ThreadRecorder::ActiveRecording::movePartialToTarget() { mTargetRecording->mBuffers.write()->append(mPartialRecording); - mPartialRecording.reset(); + // reset based on self to keep history + mPartialRecording.reset(&mPartialRecording); } @@ -180,21 +191,22 @@ void ThreadRecorder::ActiveRecording::moveBaselineToTarget() // SlaveThreadRecorder /////////////////////////////////////////////////////////////////////// -SlaveThreadRecorder::SlaveThreadRecorder() +SlaveThreadRecorder::SlaveThreadRecorder(MasterThreadRecorder& master) +: mMasterRecorder(master) { - getMasterThreadRecorder().addSlaveThread(this); + mMasterRecorder.addSlaveThread(this); } SlaveThreadRecorder::~SlaveThreadRecorder() { - getMasterThreadRecorder().removeSlaveThread(this); + mMasterRecorder.removeSlaveThread(this); } void SlaveThreadRecorder::pushToMaster() { mThreadRecording.stop(); { - LLMutexLock(getMasterThreadRecorder().getSlaveListMutex()); + LLMutexLock(mMasterRecorder.getSlaveListMutex()); mSharedData.appendFrom(mThreadRecording); } mThreadRecording.start(); @@ -243,7 +255,7 @@ void MasterThreadRecorder::pullFromSlaveThreads() LLMutexLock lock(&mSlaveListMutex); - RecordingBuffers& target_recording_buffers = mActiveRecordings.front()->mPartialRecording; + RecordingBuffers& target_recording_buffers = mActiveRecordings.back()->mPartialRecording; for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); it != end_it; ++it) -- cgit v1.2.3 From ae355188327515d53b9c15c27ed576829fce3668 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 30 May 2013 18:30:11 -0700 Subject: 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 --- indra/llcommon/lltracethreadrecorder.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') 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() {} -- cgit v1.2.3 From e50e6004082223fdc0bfd78bc697d48a7f45b379 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 30 May 2013 20:15:48 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics reverted SlaveThreadRecorder update gating moved processTimes() outside of Recording, so it is called only once per frame refined sample merge logic so that multi-threaded samples do not stomp on linear history of a stat --- indra/llcommon/lltracethreadrecorder.cpp | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 89b5df1f94..75c7cb2ff1 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -202,21 +202,14 @@ SlaveThreadRecorder::~SlaveThreadRecorder() mMasterRecorder.removeSlaveThread(this); } -bool SlaveThreadRecorder::pushToMaster() +void SlaveThreadRecorder::pushToMaster() { - if (mPushCount != mMasterRecorder.getPullCount()) + mThreadRecording.stop(); { - mThreadRecording.stop(); - { - LLMutexLock(mMasterRecorder.getSlaveListMutex()); - mSharedData.appendFrom(mThreadRecording); - } - mThreadRecording.start(); - - mPushCount = mMasterRecorder.getPullCount(); - return true; + LLMutexLock(mMasterRecorder.getSlaveListMutex()); + mSharedData.appendFrom(mThreadRecording); } - return false; + mThreadRecording.start(); } void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source ) @@ -271,8 +264,6 @@ void MasterThreadRecorder::pullFromSlaveThreads() (*it)->mSharedData.mergeTo(target_recording_buffers); (*it)->mSharedData.reset(); } - - mPullCount++; } void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child ) @@ -298,10 +289,8 @@ void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child ) } } -bool MasterThreadRecorder::pushToMaster() -{ - return false; -} +void MasterThreadRecorder::pushToMaster() +{} MasterThreadRecorder::MasterThreadRecorder() {} -- cgit v1.2.3 From 9def3590f41dee3cba7760e4443fdc71f5fb2db6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 31 May 2013 16:01:46 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics fixed multithreading lltrace causing values to be interpolated towards 0 added Radians unit improved sceneloadmonitor restart heuristic to use accumulated camera motion --- indra/llcommon/lltracethreadrecorder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 75c7cb2ff1..c281b768ce 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -247,7 +247,7 @@ void SlaveThreadRecorder::SharedData::reset() // MasterThreadRecorder /////////////////////////////////////////////////////////////////////// -LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_SLAVES("Pull slave trace data"); +static LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_SLAVES("Pull slave trace data"); void MasterThreadRecorder::pullFromSlaveThreads() { LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_SLAVES); -- cgit v1.2.3 From 233201f8227f92e93061d3e2393a17b42dfa3dd1 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 2 Jun 2013 22:49:17 -0700 Subject: SH-3931 WIP Interesting: Add graphs to visualize scene load metrics removed unnecessary templates from accumulator types...now always track data in double precision floating point, using templated accessors to convert to and from arbitrary types --- indra/llcommon/lltracethreadrecorder.cpp | 7 ------- 1 file changed, 7 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index c281b768ce..c1a0700eff 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -147,13 +147,6 @@ ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringU return it; } -AccumulatorBuffer > gCountsFloat; -AccumulatorBuffer > gMeasurementsFloat; -AccumulatorBuffer > gCounts; -AccumulatorBuffer > gMeasurements; -AccumulatorBuffer gStackTimers; -AccumulatorBuffer gMemStats; - void ThreadRecorder::deactivate( Recording* recording ) { active_recording_list_t::reverse_iterator it = bringUpToDate(recording); -- cgit v1.2.3 From d136c4c29686c565b5a46503aa67a9c958b4145d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 18 Jun 2013 23:41:53 -0700 Subject: SH-4246 FIX interesting: fast timers significantly decreases framerate removed implicit flushes on reads from recorders for better performance made sure stack timers were updated on recorder deactivate faster rendering and better ui for fast timer view --- indra/llcommon/lltracethreadrecorder.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index c1a0700eff..54006f4e5b 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -111,6 +111,7 @@ ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringU if (mActiveRecordings.empty()) return mActiveRecordings.rend(); mActiveRecordings.back()->mPartialRecording.flush(); + TimeBlock::updateTimes(); active_recording_list_t::reverse_iterator it, end_it; for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend(); -- cgit v1.2.3 From 8bddaeec6647e735415f9bd72a4e1313e11fe720 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sat, 22 Jun 2013 12:00:18 -0700 Subject: fixed scene load monitor resetting to eagerly due to spurious camer amotion pulled swap() out of ui time block cleaned up internal lltrace dependencies, factored out common accumulator definitions --- indra/llcommon/lltracethreadrecorder.cpp | 108 +++++++++++++++---------------- 1 file changed, 52 insertions(+), 56 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 54006f4e5b..c571e013e1 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -31,6 +31,7 @@ namespace LLTrace { +MasterThreadRecorder* gUIThreadRecorder = NULL; /////////////////////////////////////////////////////////////////////// // ThreadRecorder @@ -49,7 +50,7 @@ ThreadRecorder::ThreadRecorder() mNumTimeBlockTreeNodes = AccumulatorBuffer::getDefaultBuffer()->size(); mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes]; - mThreadRecording.start(); + activate(&mThreadRecordingBuffers); // initialize time block parent pointers for (LLInstanceTracker::instance_iter it = LLInstanceTracker::beginInstances(), end_it = LLInstanceTracker::endInstances(); @@ -72,6 +73,8 @@ ThreadRecorder::ThreadRecorder() ThreadRecorder::~ThreadRecorder() { + deactivate(&mThreadRecordingBuffers); + delete mRootTimer; if (!mActiveRecordings.empty()) @@ -94,7 +97,7 @@ TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index) } -void ThreadRecorder::activate( Recording* recording ) +void ThreadRecorder::activate( AccumulatorBufferGroup* recording ) { ActiveRecording* active_recording = new ActiveRecording(recording); if (!mActiveRecordings.empty()) @@ -106,7 +109,7 @@ void ThreadRecorder::activate( Recording* recording ) mActiveRecordings.back()->mPartialRecording.makePrimary(); } -ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( Recording* recording ) +ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording ) { if (mActiveRecordings.empty()) return mActiveRecordings.rend(); @@ -148,7 +151,7 @@ ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringU return it; } -void ThreadRecorder::deactivate( Recording* recording ) +void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) { active_recording_list_t::reverse_iterator it = bringUpToDate(recording); if (it != mActiveRecordings.rend()) @@ -168,14 +171,14 @@ void ThreadRecorder::deactivate( Recording* recording ) } } -ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target ) +ThreadRecorder::ActiveRecording::ActiveRecording( AccumulatorBufferGroup* target ) : mTargetRecording(target) { } void ThreadRecorder::ActiveRecording::movePartialToTarget() { - mTargetRecording->mBuffers.write()->append(mPartialRecording); + mTargetRecording->append(mPartialRecording); // reset based on self to keep history mPartialRecording.reset(&mPartialRecording); } @@ -197,46 +200,14 @@ SlaveThreadRecorder::~SlaveThreadRecorder() } void SlaveThreadRecorder::pushToMaster() -{ - mThreadRecording.stop(); - { - LLMutexLock(mMasterRecorder.getSlaveListMutex()); - mSharedData.appendFrom(mThreadRecording); +{ + { LLMutexLock lock(&mSharedRecordingMutex); + mThreadRecordingBuffers.flush(); + LLTrace::get_thread_recorder()->bringUpToDate(&mThreadRecordingBuffers); + mSharedRecordingBuffers.append(mThreadRecordingBuffers); } - mThreadRecording.start(); -} - -void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source ) -{ - LLMutexLock lock(&mRecordingMutex); - appendRecording(source); } -void SlaveThreadRecorder::SharedData::appendTo( Recording& sink ) -{ - LLMutexLock lock(&mRecordingMutex); - sink.appendRecording(*this); -} - -void SlaveThreadRecorder::SharedData::mergeFrom( const RecordingBuffers& source ) -{ - LLMutexLock lock(&mRecordingMutex); - mBuffers.write()->merge(source); -} - -void SlaveThreadRecorder::SharedData::mergeTo( RecordingBuffers& sink ) -{ - LLMutexLock lock(&mRecordingMutex); - sink.merge(*mBuffers); -} - -void SlaveThreadRecorder::SharedData::reset() -{ - LLMutexLock lock(&mRecordingMutex); - Recording::reset(); -} - - /////////////////////////////////////////////////////////////////////// // MasterThreadRecorder /////////////////////////////////////////////////////////////////////// @@ -247,29 +218,30 @@ void MasterThreadRecorder::pullFromSlaveThreads() LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_SLAVES); if (mActiveRecordings.empty()) return; - LLMutexLock lock(&mSlaveListMutex); + { LLMutexLock lock(&mSlaveListMutex); - RecordingBuffers& target_recording_buffers = mActiveRecordings.back()->mPartialRecording; - for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); - it != end_it; - ++it) - { - // ignore block timing info for now - (*it)->mSharedData.mergeTo(target_recording_buffers); - (*it)->mSharedData.reset(); + AccumulatorBufferGroup& target_recording_buffers = mActiveRecordings.back()->mPartialRecording; + for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); + it != end_it; + ++it) + { LLMutexLock lock(&(*it)->mSharedRecordingMutex); + + target_recording_buffers.merge((*it)->mSharedRecordingBuffers); + (*it)->mSharedRecordingBuffers.reset(); + } } } +// called by slave thread void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child ) -{ - LLMutexLock lock(&mSlaveListMutex); +{ LLMutexLock lock(&mSlaveListMutex); mSlaveThreadRecorders.push_back(child); } +// called by slave thread void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child ) -{ - LLMutexLock lock(&mSlaveListMutex); +{ LLMutexLock lock(&mSlaveListMutex); for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); it != end_it; @@ -289,4 +261,28 @@ void MasterThreadRecorder::pushToMaster() MasterThreadRecorder::MasterThreadRecorder() {} + +MasterThreadRecorder& getUIThreadRecorder() +{ + llassert(gUIThreadRecorder != NULL); + return *gUIThreadRecorder; +} + +LLThreadLocalPointer& get_thread_recorder_ptr() +{ + static LLThreadLocalPointer s_thread_recorder; + return s_thread_recorder; +} + +const LLThreadLocalPointer& get_thread_recorder() +{ + return get_thread_recorder_ptr(); +} + +void set_thread_recorder(ThreadRecorder* recorder) +{ + get_thread_recorder_ptr() = recorder; +} + + } -- cgit v1.2.3 From 808d3eff198d65e5a870abb670786935fc8356bd Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 27 Jun 2013 00:07:21 -0700 Subject: SH-4299 WIP: Interesting: High fps shown temporarily off scale in statistics console fixed some lltrace logic errors more consistent syncing of timestamps of sample values in recording stack selection of primary buffers was completely incorrect assignment of recordings got wrong play state due to implicit operator = defined in base class fixed asset stats only working up to the first send --- indra/llcommon/lltracethreadrecorder.cpp | 57 ++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 21 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index c571e013e1..7192564c94 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -87,7 +87,7 @@ ThreadRecorder::~ThreadRecorder() delete[] mTimeBlockTreeNodes; } -TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index) +TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode( S32 index ) { if (0 <= index && index < mNumTimeBlockTreeNodes) { @@ -99,10 +99,20 @@ TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode(S32 index) void ThreadRecorder::activate( AccumulatorBufferGroup* recording ) { + active_recording_list_t::reverse_iterator it, end_it; + for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend(); + it != end_it; + ++it) + { + llassert((*it)->mTargetRecording != recording); + } + ActiveRecording* active_recording = new ActiveRecording(recording); if (!mActiveRecordings.empty()) { - mActiveRecordings.back()->mPartialRecording.handOffTo(active_recording->mPartialRecording); + AccumulatorBufferGroup& prev_active_recording = mActiveRecordings.back()->mPartialRecording; + prev_active_recording.sync(); + prev_active_recording.handOffTo(active_recording->mPartialRecording); } mActiveRecordings.push_back(active_recording); @@ -113,7 +123,7 @@ ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringU { if (mActiveRecordings.empty()) return mActiveRecordings.rend(); - mActiveRecordings.back()->mPartialRecording.flush(); + mActiveRecordings.back()->mPartialRecording.sync(); TimeBlock::updateTimes(); active_recording_list_t::reverse_iterator it, end_it; @@ -156,18 +166,22 @@ void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) active_recording_list_t::reverse_iterator it = bringUpToDate(recording); if (it != mActiveRecordings.rend()) { - // and if we've found the recording we wanted to update - active_recording_list_t::reverse_iterator next_it = it; - ++next_it; - if (next_it != mActiveRecordings.rend()) - { - (*next_it)->mPartialRecording.makePrimary(); - } - active_recording_list_t::iterator recording_to_remove = (++it).base(); + bool was_primary = (*recording_to_remove)->mPartialRecording.isPrimary(); llassert((*recording_to_remove)->mTargetRecording == recording); delete *recording_to_remove; mActiveRecordings.erase(recording_to_remove); + if (was_primary) + { + if (mActiveRecordings.empty()) + { + AccumulatorBufferGroup::clearPrimary(); + } + else + { + mActiveRecordings.back()->mPartialRecording.makePrimary(); + } + } } } @@ -202,7 +216,6 @@ SlaveThreadRecorder::~SlaveThreadRecorder() void SlaveThreadRecorder::pushToMaster() { { LLMutexLock lock(&mSharedRecordingMutex); - mThreadRecordingBuffers.flush(); LLTrace::get_thread_recorder()->bringUpToDate(&mThreadRecordingBuffers); mSharedRecordingBuffers.append(mThreadRecordingBuffers); } @@ -213,23 +226,25 @@ void SlaveThreadRecorder::pushToMaster() /////////////////////////////////////////////////////////////////////// static LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_SLAVES("Pull slave trace data"); + void MasterThreadRecorder::pullFromSlaveThreads() { - LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_SLAVES); + /*LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_SLAVES); if (mActiveRecordings.empty()) return; { LLMutexLock lock(&mSlaveListMutex); - AccumulatorBufferGroup& target_recording_buffers = mActiveRecordings.back()->mPartialRecording; - for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); - it != end_it; - ++it) - { LLMutexLock lock(&(*it)->mSharedRecordingMutex); + AccumulatorBufferGroup& target_recording_buffers = mActiveRecordings.back()->mPartialRecording; + target_recording_buffers.sync(); + for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); + it != end_it; + ++it) + { LLMutexLock lock(&(*it)->mSharedRecordingMutex); - target_recording_buffers.merge((*it)->mSharedRecordingBuffers); - (*it)->mSharedRecordingBuffers.reset(); - } + target_recording_buffers.merge((*it)->mSharedRecordingBuffers); + (*it)->mSharedRecordingBuffers.reset(); } + }*/ } // called by slave thread -- cgit v1.2.3 From ffa7123bb5187e1da491a8f475d696053d9c9ee4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 28 Jun 2013 20:45:20 -0700 Subject: SH-4299 FIX Interesting: High fps shown temporarily off scale in statistics console added ability to force uniqueness of LLCopyOnWritePointer converted more variables to units added convenience function for unit constants --- indra/llcommon/lltracethreadrecorder.cpp | 8 -------- 1 file changed, 8 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 7192564c94..d0f0328d1c 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -99,14 +99,6 @@ TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode( S32 index ) void ThreadRecorder::activate( AccumulatorBufferGroup* recording ) { - active_recording_list_t::reverse_iterator it, end_it; - for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend(); - it != end_it; - ++it) - { - llassert((*it)->mTargetRecording != recording); - } - ActiveRecording* active_recording = new ActiveRecording(recording); if (!mActiveRecordings.empty()) { -- cgit v1.2.3 From 2fc422f39ddaca25c69e8cf2092a9d66840379f3 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 30 Jun 2013 13:32:34 -0700 Subject: fixed memory leak due to implementation of LLThreadLocalSingleton removed LLThreadLocalSingleton collapsed all thread recorder classes to single type, LLTrace::ThreadRecorder moved fasttimer stack head to llthreadlocalsingletonpointer via ThreadRecorder --- indra/llcommon/lltracethreadrecorder.cpp | 117 +++++++++++++++---------------- 1 file changed, 58 insertions(+), 59 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index d0f0328d1c..e88c5bf177 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -31,7 +31,7 @@ namespace LLTrace { -MasterThreadRecorder* gUIThreadRecorder = NULL; +ThreadRecorder* gUIThreadRecorder = NULL; /////////////////////////////////////////////////////////////////////// // ThreadRecorder @@ -39,11 +39,17 @@ MasterThreadRecorder* gUIThreadRecorder = NULL; ThreadRecorder::ThreadRecorder() { + init(); +} + +void ThreadRecorder::init() +{ + LLThreadLocalSingletonPointer::setInstance(&mBlockTimerStackRecord); //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(); + BlockTimerStackRecord* timer_stack = LLThreadLocalSingletonPointer::getInstance(); timer_stack->mTimeBlock = &root_time_block; timer_stack->mActiveTimer = NULL; @@ -71,8 +77,19 @@ ThreadRecorder::ThreadRecorder() TimeBlock::getRootTimeBlock().getPrimaryAccumulator()->mActiveCount = 1; } + +ThreadRecorder::ThreadRecorder(ThreadRecorder& master) +: mMasterRecorder(&master) +{ + init(); + mMasterRecorder->addChildRecorder(this); +} + + ThreadRecorder::~ThreadRecorder() { + LLThreadLocalSingletonPointer::setInstance(NULL); + deactivate(&mThreadRecordingBuffers); delete mRootTimer; @@ -85,6 +102,11 @@ ThreadRecorder::~ThreadRecorder() set_thread_recorder(NULL); delete[] mTimeBlockTreeNodes; + + if (mMasterRecorder) + { + mMasterRecorder->removeChildRecorder(this); + } } TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode( S32 index ) @@ -190,86 +212,63 @@ void ThreadRecorder::ActiveRecording::movePartialToTarget() } -/////////////////////////////////////////////////////////////////////// -// SlaveThreadRecorder -/////////////////////////////////////////////////////////////////////// - -SlaveThreadRecorder::SlaveThreadRecorder(MasterThreadRecorder& master) -: mMasterRecorder(master) -{ - mMasterRecorder.addSlaveThread(this); +// called by child thread +void ThreadRecorder::addChildRecorder( class ThreadRecorder* child ) +{ LLMutexLock lock(&mChildListMutex); + mChildThreadRecorders.push_back(child); } -SlaveThreadRecorder::~SlaveThreadRecorder() +// called by child thread +void ThreadRecorder::removeChildRecorder( class ThreadRecorder* child ) +{ LLMutexLock lock(&mChildListMutex); + +for (child_thread_recorder_list_t::iterator it = mChildThreadRecorders.begin(), end_it = mChildThreadRecorders.end(); + it != end_it; + ++it) { - mMasterRecorder.removeSlaveThread(this); + if ((*it) == child) + { + mChildThreadRecorders.erase(it); + break; + } +} } -void SlaveThreadRecorder::pushToMaster() -{ +void ThreadRecorder::pushToParent() +{ { LLMutexLock lock(&mSharedRecordingMutex); LLTrace::get_thread_recorder()->bringUpToDate(&mThreadRecordingBuffers); mSharedRecordingBuffers.append(mThreadRecordingBuffers); } } + + -/////////////////////////////////////////////////////////////////////// -// MasterThreadRecorder -/////////////////////////////////////////////////////////////////////// -static LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_SLAVES("Pull slave trace data"); +static LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_CHILDREN("Pull child thread trace data"); -void MasterThreadRecorder::pullFromSlaveThreads() +void ThreadRecorder::pullFromChildren() { - /*LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_SLAVES); + LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_CHILDREN); if (mActiveRecordings.empty()) return; - { LLMutexLock lock(&mSlaveListMutex); - - AccumulatorBufferGroup& target_recording_buffers = mActiveRecordings.back()->mPartialRecording; - target_recording_buffers.sync(); - for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); - it != end_it; - ++it) - { LLMutexLock lock(&(*it)->mSharedRecordingMutex); - - target_recording_buffers.merge((*it)->mSharedRecordingBuffers); - (*it)->mSharedRecordingBuffers.reset(); - } - }*/ -} + { LLMutexLock lock(&mChildListMutex); -// called by slave thread -void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child ) -{ LLMutexLock lock(&mSlaveListMutex); + AccumulatorBufferGroup& target_recording_buffers = mActiveRecordings.back()->mPartialRecording; + target_recording_buffers.sync(); + for (child_thread_recorder_list_t::iterator it = mChildThreadRecorders.begin(), end_it = mChildThreadRecorders.end(); + it != end_it; + ++it) + { LLMutexLock lock(&(*it)->mSharedRecordingMutex); - mSlaveThreadRecorders.push_back(child); -} - -// called by slave thread -void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child ) -{ LLMutexLock lock(&mSlaveListMutex); - - for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); - it != end_it; - ++it) - { - if ((*it) == child) - { - mSlaveThreadRecorders.erase(it); - break; + target_recording_buffers.merge((*it)->mSharedRecordingBuffers); + (*it)->mSharedRecordingBuffers.reset(); } } } -void MasterThreadRecorder::pushToMaster() -{} - -MasterThreadRecorder::MasterThreadRecorder() -{} - -MasterThreadRecorder& getUIThreadRecorder() +ThreadRecorder& getUIThreadRecorder() { llassert(gUIThreadRecorder != NULL); return *gUIThreadRecorder; -- cgit v1.2.3 From 04bdc8ba83c297945dd60489c241b88adf892ff4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 1 Jul 2013 17:04:01 -0700 Subject: SH-4294 FIX Interesting: Statistics Texture cache hit rate is always 0% also, removed LLTrace::init and cleanup removed derived class implementation of memory stat for LLMemTrackable is automatic now --- indra/llcommon/lltracethreadrecorder.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index e88c5bf177..7ac0e75154 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -31,13 +31,14 @@ namespace LLTrace { -ThreadRecorder* gUIThreadRecorder = NULL; +static ThreadRecorder* sMasterThreadRecorder = NULL; /////////////////////////////////////////////////////////////////////// // ThreadRecorder /////////////////////////////////////////////////////////////////////// ThreadRecorder::ThreadRecorder() +: mMasterRecorder(NULL) { init(); } @@ -268,10 +269,15 @@ void ThreadRecorder::pullFromChildren() } -ThreadRecorder& getUIThreadRecorder() +void set_master_thread_recorder(ThreadRecorder* recorder) { - llassert(gUIThreadRecorder != NULL); - return *gUIThreadRecorder; + sMasterThreadRecorder = recorder; +} + + +ThreadRecorder* get_master_thread_recorder() +{ + return sMasterThreadRecorder; } LLThreadLocalPointer& get_thread_recorder_ptr() -- cgit v1.2.3 From 11e14cd3b0f58225a96b9b7a9839a7f030fe4045 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 15 Jul 2013 11:05:57 -0700 Subject: SH-4299Interesting: High fps shown temporarily off scale in statistics console various fixes to lltrace start() on started recording no longer resets fixed various instances of unit forgetfullness in lltrace recording split now has gapless timing scene monitor now guarantees min sample time renamed a bunch of stats added names to debug thread view on windows --- indra/llcommon/lltracethreadrecorder.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 7ac0e75154..e20d8b63de 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -120,13 +120,17 @@ TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode( S32 index ) } -void ThreadRecorder::activate( AccumulatorBufferGroup* recording ) +void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_handoff ) { ActiveRecording* active_recording = new ActiveRecording(recording); if (!mActiveRecordings.empty()) { AccumulatorBufferGroup& prev_active_recording = mActiveRecordings.back()->mPartialRecording; prev_active_recording.sync(); + if (!from_handoff) + { + TimeBlock::updateTimes(); + } prev_active_recording.handOffTo(active_recording->mPartialRecording); } mActiveRecordings.push_back(active_recording); @@ -240,6 +244,7 @@ void ThreadRecorder::pushToParent() { LLMutexLock lock(&mSharedRecordingMutex); LLTrace::get_thread_recorder()->bringUpToDate(&mThreadRecordingBuffers); mSharedRecordingBuffers.append(mThreadRecordingBuffers); + mThreadRecordingBuffers.reset(); } } -- cgit v1.2.3 From e340009fc59d59e59b2e8d903a884acb76b178eb Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 9 Aug 2013 17:11:19 -0700 Subject: second phase summer cleaning replace llinfos, lldebugs, etc with new LL_INFOS(), LL_DEBUGS(), etc. --- indra/llcommon/lltracethreadrecorder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index e20d8b63de..8c32e1568b 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -174,7 +174,7 @@ ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringU if (it == end_it) { - llwarns << "Recording not active on this thread" << llendl; + LL_WARNS() << "Recording not active on this thread" << LL_ENDL; } return it; -- cgit v1.2.3 From 2c6bc5afa59a88136fd6de4ebf0cb99ea7cdef3f Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 21 Aug 2013 14:06:57 -0700 Subject: SH-4433 WIP Interesting: Statistics > Ping Sim is always 0 ms made getPrimaryAccumulator return a reference since it was an always non-null pointer changed unit conversion to perform lazy division in order to avoid truncation of timer values --- indra/llcommon/lltracethreadrecorder.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 8c32e1568b..28470fb4c4 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -69,13 +69,13 @@ void ThreadRecorder::init() tree_node.mBlock = &time_block; tree_node.mParent = &root_time_block; - it->getPrimaryAccumulator()->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; + TimeBlock::getRootTimeBlock().getPrimaryAccumulator().mActiveCount = 1; } @@ -247,8 +247,6 @@ void ThreadRecorder::pushToParent() mThreadRecordingBuffers.reset(); } } - - static LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_CHILDREN("Pull child thread trace data"); -- cgit v1.2.3 From cbe397ad13665c7bc993e10d8fe1e4a876253378 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 5 Sep 2013 14:04:13 -0700 Subject: changed fast timer over to using macro another attempt to move mem stat into base class --- indra/llcommon/lltracethreadrecorder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 28470fb4c4..4129f1f889 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -249,11 +249,11 @@ void ThreadRecorder::pushToParent() } -static LLFastTimer::DeclareTimer FTM_PULL_TRACE_DATA_FROM_CHILDREN("Pull child thread trace data"); +static LLTrace::TimeBlock FTM_PULL_TRACE_DATA_FROM_CHILDREN("Pull child thread trace data"); void ThreadRecorder::pullFromChildren() { - LLFastTimer _(FTM_PULL_TRACE_DATA_FROM_CHILDREN); + LL_RECORD_BLOCK_TIME(FTM_PULL_TRACE_DATA_FROM_CHILDREN); if (mActiveRecordings.empty()) return; { LLMutexLock lock(&mChildListMutex); -- cgit v1.2.3 From 3fd68662f267a3fd96d101834b3a9563bde3f61e Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sat, 7 Sep 2013 21:16:39 -0700 Subject: added memory usage and occlusion events to traces renamed "current" to "primary" when referring to accumulators --- indra/llcommon/lltracethreadrecorder.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 28470fb4c4..df4af89184 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -69,13 +69,13 @@ void ThreadRecorder::init() tree_node.mBlock = &time_block; tree_node.mParent = &root_time_block; - it->getPrimaryAccumulator().mParent = &root_time_block; + it->getCurrentAccumulator().mParent = &root_time_block; } mRootTimer = new BlockTimer(root_time_block); timer_stack->mActiveTimer = mRootTimer; - TimeBlock::getRootTimeBlock().getPrimaryAccumulator().mActiveCount = 1; + TimeBlock::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; } @@ -135,7 +135,7 @@ void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_hand } mActiveRecordings.push_back(active_recording); - mActiveRecordings.back()->mPartialRecording.makePrimary(); + mActiveRecordings.back()->mPartialRecording.makeCurrent(); } ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording ) @@ -186,19 +186,19 @@ void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) if (it != mActiveRecordings.rend()) { active_recording_list_t::iterator recording_to_remove = (++it).base(); - bool was_primary = (*recording_to_remove)->mPartialRecording.isPrimary(); + bool was_current = (*recording_to_remove)->mPartialRecording.isCurrent(); llassert((*recording_to_remove)->mTargetRecording == recording); delete *recording_to_remove; mActiveRecordings.erase(recording_to_remove); - if (was_primary) + if (was_current) { if (mActiveRecordings.empty()) { - AccumulatorBufferGroup::clearPrimary(); + AccumulatorBufferGroup::resetCurrent(); } else { - mActiveRecordings.back()->mPartialRecording.makePrimary(); + mActiveRecordings.back()->mPartialRecording.makeCurrent(); } } } -- cgit v1.2.3 From 72f979135b3497d16c2635babf057900ddbc42fe Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 18 Sep 2013 14:20:30 -0700 Subject: merge --- indra/llcommon/lltracethreadrecorder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 8cddc49e71..d3d9eb5ca7 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -194,7 +194,7 @@ void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) { if (mActiveRecordings.empty()) { - AccumulatorBufferGroup::resetCurrent(); + AccumulatorBufferGroup::clearCurrent(); } else { -- cgit v1.2.3 From 053d97db1b283ca2548dc1f64756ddfc5166158f Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 25 Sep 2013 19:12:35 -0700 Subject: better memory usage for LLTrace (tighter packing of recording arrays) removed complicated and unnecessary fast timer gapless handoff logic (it should be gapless anyway) improved MemTrackable API, better separation of shadow and footprint added memory usage stats to floater_stats.xml --- indra/llcommon/lltracethreadrecorder.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index d3d9eb5ca7..e131af5f16 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -127,10 +127,7 @@ void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_hand { AccumulatorBufferGroup& prev_active_recording = mActiveRecordings.back()->mPartialRecording; prev_active_recording.sync(); - if (!from_handoff) - { - TimeBlock::updateTimes(); - } + TimeBlock::updateTimes(); prev_active_recording.handOffTo(active_recording->mPartialRecording); } mActiveRecordings.push_back(active_recording); -- cgit v1.2.3 From 754e8752a9b9a2e75d425a10cb8a0a6f85ad4bf5 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 3 Oct 2013 14:30:34 -0700 Subject: added initial memory usage tracking for lltrace --- indra/llcommon/lltracethreadrecorder.cpp | 62 ++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 22 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index e131af5f16..bf6189dd25 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -27,9 +27,11 @@ #include "lltracethreadrecorder.h" #include "llfasttimer.h" +#include "lltrace.h" namespace LLTrace { +extern MemStatHandle gTraceMemStat; static ThreadRecorder* sMasterThreadRecorder = NULL; @@ -55,6 +57,7 @@ void ThreadRecorder::init() timer_stack->mActiveTimer = NULL; mNumTimeBlockTreeNodes = AccumulatorBuffer::getDefaultBuffer()->size(); + mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes]; activate(&mThreadRecordingBuffers); @@ -76,10 +79,14 @@ void ThreadRecorder::init() timer_stack->mActiveTimer = mRootTimer; TimeBlock::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; + + claim_alloc(gTraceMemStat, sizeof(*this)); + claim_alloc(gTraceMemStat, sizeof(BlockTimer)); + claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes); } -ThreadRecorder::ThreadRecorder(ThreadRecorder& master) +ThreadRecorder::ThreadRecorder( ThreadRecorder& master ) : mMasterRecorder(&master) { init(); @@ -91,6 +98,10 @@ ThreadRecorder::~ThreadRecorder() { LLThreadLocalSingletonPointer::setInstance(NULL); + disclaim_alloc(gTraceMemStat, sizeof(*this)); + disclaim_alloc(gTraceMemStat, sizeof(BlockTimer)); + disclaim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes); + deactivate(&mThreadRecordingBuffers); delete mRootTimer; @@ -135,9 +146,9 @@ void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_hand mActiveRecordings.back()->mPartialRecording.makeCurrent(); } -ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording ) +ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording ) { - if (mActiveRecordings.empty()) return mActiveRecordings.rend(); + if (mActiveRecordings.empty()) return mActiveRecordings.end(); mActiveRecordings.back()->mPartialRecording.sync(); TimeBlock::updateTimes(); @@ -174,15 +185,14 @@ ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringU LL_WARNS() << "Recording not active on this thread" << LL_ENDL; } - return it; + return (++it).base(); } void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) { - active_recording_list_t::reverse_iterator it = bringUpToDate(recording); - if (it != mActiveRecordings.rend()) + active_recording_list_t::iterator recording_to_remove = bringUpToDate(recording); + if (recording_to_remove != mActiveRecordings.end()) { - active_recording_list_t::iterator recording_to_remove = (++it).base(); bool was_current = (*recording_to_remove)->mPartialRecording.isCurrent(); llassert((*recording_to_remove)->mTargetRecording == recording); delete *recording_to_remove; @@ -216,25 +226,33 @@ void ThreadRecorder::ActiveRecording::movePartialToTarget() // called by child thread void ThreadRecorder::addChildRecorder( class ThreadRecorder* child ) -{ LLMutexLock lock(&mChildListMutex); - mChildThreadRecorders.push_back(child); +{ + { LLMutexLock lock(&mChildListMutex); + mChildThreadRecorders.push_back(child); + } } // called by child thread void ThreadRecorder::removeChildRecorder( class ThreadRecorder* child ) -{ LLMutexLock lock(&mChildListMutex); - -for (child_thread_recorder_list_t::iterator it = mChildThreadRecorders.begin(), end_it = mChildThreadRecorders.end(); - it != end_it; - ++it) -{ - if ((*it) == child) - { - mChildThreadRecorders.erase(it); - break; +{ + { LLMutexLock lock(&mChildListMutex); + for (child_thread_recorder_list_t::iterator it = mChildThreadRecorders.begin(), end_it = mChildThreadRecorders.end(); + it != end_it; + ++it) + { + if ((*it) == child) + { + // FIXME: this won't do any good, as the child stores the "pushed" values internally + // and it is in the process of being deleted. + // We need a way to finalize the stats from the outgoing thread, but the storage + // for those stats needs to be outside the child's thread recorder + //(*it)->pushToParent(); + mChildThreadRecorders.erase(it); + break; + } + } } } -} void ThreadRecorder::pushToParent() { @@ -269,7 +287,7 @@ void ThreadRecorder::pullFromChildren() } -void set_master_thread_recorder(ThreadRecorder* recorder) +void set_master_thread_recorder( ThreadRecorder* recorder ) { sMasterThreadRecorder = recorder; } @@ -291,7 +309,7 @@ const LLThreadLocalPointer& get_thread_recorder() return get_thread_recorder_ptr(); } -void set_thread_recorder(ThreadRecorder* recorder) +void set_thread_recorder( ThreadRecorder* recorder ) { get_thread_recorder_ptr() = recorder; } -- cgit v1.2.3 From 1821fa12838974c4eb7de2b6e9f79bf8a4cf23f1 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 3 Oct 2013 16:57:15 -0700 Subject: fixed memory tracking of lltrace system --- indra/llcommon/lltracethreadrecorder.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index bf6189dd25..9dac4f6771 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -80,7 +80,7 @@ void ThreadRecorder::init() TimeBlock::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; - claim_alloc(gTraceMemStat, sizeof(*this)); + claim_alloc(gTraceMemStat, this); claim_alloc(gTraceMemStat, sizeof(BlockTimer)); claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes); } @@ -98,7 +98,7 @@ ThreadRecorder::~ThreadRecorder() { LLThreadLocalSingletonPointer::setInstance(NULL); - disclaim_alloc(gTraceMemStat, sizeof(*this)); + disclaim_alloc(gTraceMemStat, this); disclaim_alloc(gTraceMemStat, sizeof(BlockTimer)); disclaim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes); @@ -190,13 +190,13 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) { - active_recording_list_t::iterator recording_to_remove = bringUpToDate(recording); - if (recording_to_remove != mActiveRecordings.end()) + active_recording_list_t::iterator recording_it = bringUpToDate(recording); + if (recording_it != mActiveRecordings.end()) { - bool was_current = (*recording_to_remove)->mPartialRecording.isCurrent(); - llassert((*recording_to_remove)->mTargetRecording == recording); - delete *recording_to_remove; - mActiveRecordings.erase(recording_to_remove); + ActiveRecording* recording_to_remove = *recording_it; + bool was_current = recording_to_remove->mPartialRecording.isCurrent(); + llassert(recording_to_remove->mTargetRecording == recording); + mActiveRecordings.erase(recording_it); if (was_current) { if (mActiveRecordings.empty()) @@ -208,6 +208,7 @@ void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) mActiveRecordings.back()->mPartialRecording.makeCurrent(); } } + delete recording_to_remove; } } -- cgit v1.2.3 From 697d2e720ba75e142a4d56ae8794bab8d7698dad Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 15 Oct 2013 20:24:42 -0700 Subject: renamed TimeBlock to BlockTimerStatHandle --- indra/llcommon/lltracethreadrecorder.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 9dac4f6771..20e8a0bbaa 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -50,7 +50,7 @@ void ThreadRecorder::init() LLThreadLocalSingletonPointer::setInstance(&mBlockTimerStackRecord); //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(); + BlockTimerStatHandle& root_time_block = BlockTimerStatHandle::getRootTimeBlock(); BlockTimerStackRecord* timer_stack = LLThreadLocalSingletonPointer::getInstance(); timer_stack->mTimeBlock = &root_time_block; @@ -63,11 +63,11 @@ void ThreadRecorder::init() activate(&mThreadRecordingBuffers); // initialize time block parent pointers - for (LLInstanceTracker::instance_iter it = LLInstanceTracker::beginInstances(), end_it = LLInstanceTracker::endInstances(); + for (BlockTimerStatHandle::instance_tracker_t::instance_iter it = BlockTimerStatHandle::instance_tracker_t::beginInstances(), end_it = BlockTimerStatHandle::instance_tracker_t::endInstances(); it != end_it; ++it) { - TimeBlock& time_block = *it; + BlockTimerStatHandle& time_block = static_cast(*it); TimeBlockTreeNode& tree_node = mTimeBlockTreeNodes[it->getIndex()]; tree_node.mBlock = &time_block; tree_node.mParent = &root_time_block; @@ -78,7 +78,7 @@ void ThreadRecorder::init() mRootTimer = new BlockTimer(root_time_block); timer_stack->mActiveTimer = mRootTimer; - TimeBlock::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; + BlockTimerStatHandle::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; claim_alloc(gTraceMemStat, this); claim_alloc(gTraceMemStat, sizeof(BlockTimer)); @@ -138,7 +138,7 @@ void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_hand { AccumulatorBufferGroup& prev_active_recording = mActiveRecordings.back()->mPartialRecording; prev_active_recording.sync(); - TimeBlock::updateTimes(); + BlockTimerStatHandle::updateTimes(); prev_active_recording.handOffTo(active_recording->mPartialRecording); } mActiveRecordings.push_back(active_recording); @@ -151,7 +151,7 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( if (mActiveRecordings.empty()) return mActiveRecordings.end(); mActiveRecordings.back()->mPartialRecording.sync(); - TimeBlock::updateTimes(); + BlockTimerStatHandle::updateTimes(); active_recording_list_t::reverse_iterator it, end_it; for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend(); @@ -265,7 +265,7 @@ void ThreadRecorder::pushToParent() } -static LLTrace::TimeBlock FTM_PULL_TRACE_DATA_FROM_CHILDREN("Pull child thread trace data"); +static LLTrace::BlockTimerStatHandle FTM_PULL_TRACE_DATA_FROM_CHILDREN("Pull child thread trace data"); void ThreadRecorder::pullFromChildren() { -- cgit v1.2.3 From 1beaedacadc8093c9df612992a873f9c89354bce Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 17 Oct 2013 14:23:56 -0700 Subject: moved root timer to global variable added flag to LLInstanceTracker to allow multiple values per key made StatType allow multiple values per key to eliminate block timer related crash --- indra/llcommon/lltracethreadrecorder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 20e8a0bbaa..7b7da5343d 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -81,7 +81,7 @@ void ThreadRecorder::init() BlockTimerStatHandle::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; claim_alloc(gTraceMemStat, this); - claim_alloc(gTraceMemStat, sizeof(BlockTimer)); + claim_alloc(gTraceMemStat, mRootTimer); claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes); } -- cgit v1.2.3 From 1dfba44b3dc14564c99333dedb7a380a160aee44 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 21 Oct 2013 14:22:21 -0700 Subject: fixed things so that trace recordings can be read from even while active --- indra/llcommon/lltracethreadrecorder.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 7b7da5343d..a70e94e4b1 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -131,7 +131,7 @@ TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode( S32 index ) } -void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_handoff ) +AccumulatorBufferGroup* ThreadRecorder::activate( AccumulatorBufferGroup* recording) { ActiveRecording* active_recording = new ActiveRecording(recording); if (!mActiveRecordings.empty()) @@ -144,6 +144,7 @@ void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_hand mActiveRecordings.push_back(active_recording); mActiveRecordings.back()->mPartialRecording.makeCurrent(); + return &active_recording->mPartialRecording; } ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording ) -- cgit v1.2.3 From ab43be5ddb50198304de1ae0e82b641c7d343449 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 23 Oct 2013 13:24:47 -0700 Subject: moved some common functionality from LLTrace::BlockTimerStatHandle to BlockTimer updates appearance utility dependency --- indra/llcommon/lltracethreadrecorder.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index a70e94e4b1..aec36ef2c4 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -50,7 +50,7 @@ void ThreadRecorder::init() LLThreadLocalSingletonPointer::setInstance(&mBlockTimerStackRecord); //NB: the ordering of initialization in this function is very fragile due to a large number of implicit dependencies set_thread_recorder(this); - BlockTimerStatHandle& root_time_block = BlockTimerStatHandle::getRootTimeBlock(); + BlockTimerStatHandle& root_time_block = BlockTimer::getRootTimeBlock(); BlockTimerStackRecord* timer_stack = LLThreadLocalSingletonPointer::getInstance(); timer_stack->mTimeBlock = &root_time_block; @@ -78,7 +78,7 @@ void ThreadRecorder::init() mRootTimer = new BlockTimer(root_time_block); timer_stack->mActiveTimer = mRootTimer; - BlockTimerStatHandle::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; + BlockTimer::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1; claim_alloc(gTraceMemStat, this); claim_alloc(gTraceMemStat, mRootTimer); @@ -138,7 +138,7 @@ AccumulatorBufferGroup* ThreadRecorder::activate( AccumulatorBufferGroup* record { AccumulatorBufferGroup& prev_active_recording = mActiveRecordings.back()->mPartialRecording; prev_active_recording.sync(); - BlockTimerStatHandle::updateTimes(); + BlockTimer::updateTimes(); prev_active_recording.handOffTo(active_recording->mPartialRecording); } mActiveRecordings.push_back(active_recording); @@ -152,7 +152,7 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( if (mActiveRecordings.empty()) return mActiveRecordings.end(); mActiveRecordings.back()->mPartialRecording.sync(); - BlockTimerStatHandle::updateTimes(); + BlockTimer::updateTimes(); active_recording_list_t::reverse_iterator it, end_it; for (it = mActiveRecordings.rbegin(), end_it = mActiveRecordings.rend(); -- cgit v1.2.3 From 3cb64c5038b7cde8bd44ec3a029d477e415085ee Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 3 Dec 2013 15:52:36 -0800 Subject: SH-4606 FIX Interesting: Small objects do not load until they are very close. changed culling to use inverse distance to calculate solid angle, not distance squared --- indra/llcommon/lltracethreadrecorder.cpp | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index aec36ef2c4..d62fabe3df 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -130,7 +130,6 @@ TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode( S32 index ) return NULL; } - AccumulatorBufferGroup* ThreadRecorder::activate( AccumulatorBufferGroup* recording) { ActiveRecording* active_recording = new ActiveRecording(recording); @@ -215,8 +214,7 @@ void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) ThreadRecorder::ActiveRecording::ActiveRecording( AccumulatorBufferGroup* target ) : mTargetRecording(target) -{ -} +{} void ThreadRecorder::ActiveRecording::movePartialToTarget() { @@ -238,21 +236,7 @@ void ThreadRecorder::addChildRecorder( class ThreadRecorder* child ) void ThreadRecorder::removeChildRecorder( class ThreadRecorder* child ) { { LLMutexLock lock(&mChildListMutex); - for (child_thread_recorder_list_t::iterator it = mChildThreadRecorders.begin(), end_it = mChildThreadRecorders.end(); - it != end_it; - ++it) - { - if ((*it) == child) - { - // FIXME: this won't do any good, as the child stores the "pushed" values internally - // and it is in the process of being deleted. - // We need a way to finalize the stats from the outgoing thread, but the storage - // for those stats needs to be outside the child's thread recorder - //(*it)->pushToParent(); - mChildThreadRecorders.erase(it); - break; - } - } + mChildThreadRecorders.remove(child); } } @@ -316,5 +300,4 @@ void set_thread_recorder( ThreadRecorder* recorder ) get_thread_recorder_ptr() = recorder; } - } -- cgit v1.2.3 From 1522c1b3bdc8eca4acd23f92dfce118121721038 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 10 Dec 2013 15:48:57 -0800 Subject: SH-4653 FIX Interesting: Viewer crashes while reading chat history fix for crash on exit resulting from 8c0e024d0c33 --- indra/llcommon/lltracethreadrecorder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index d62fabe3df..a14a8ff035 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -40,7 +40,7 @@ static ThreadRecorder* sMasterThreadRecorder = NULL; /////////////////////////////////////////////////////////////////////// ThreadRecorder::ThreadRecorder() -: mMasterRecorder(NULL) +: mParentRecorder(NULL) { init(); } @@ -86,11 +86,11 @@ void ThreadRecorder::init() } -ThreadRecorder::ThreadRecorder( ThreadRecorder& master ) -: mMasterRecorder(&master) +ThreadRecorder::ThreadRecorder( ThreadRecorder& parent ) +: mParentRecorder(&parent) { init(); - mMasterRecorder->addChildRecorder(this); + mParentRecorder->addChildRecorder(this); } @@ -115,9 +115,9 @@ ThreadRecorder::~ThreadRecorder() set_thread_recorder(NULL); delete[] mTimeBlockTreeNodes; - if (mMasterRecorder) + if (mParentRecorder) { - mMasterRecorder->removeChildRecorder(this); + mParentRecorder->removeChildRecorder(this); } } -- cgit v1.2.3 From a712aab616b13a9887e00b5d37714f02d7fde6a0 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 10 Jan 2014 13:56:35 -0800 Subject: added some defensive asserts in lltrace to make cases of misuse more obvious when it crashes --- indra/llcommon/lltracethreadrecorder.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index a14a8ff035..187d8546d3 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -191,25 +191,25 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) { active_recording_list_t::iterator recording_it = bringUpToDate(recording); - if (recording_it != mActiveRecordings.end()) + // this method should only be called on a thread where the recorder is active + llassert_always(recording_it != mActiveRecordings.end()); + + ActiveRecording* recording_to_remove = *recording_it; + bool was_current = recording_to_remove->mPartialRecording.isCurrent(); + llassert(recording_to_remove->mTargetRecording == recording); + mActiveRecordings.erase(recording_it); + if (was_current) { - ActiveRecording* recording_to_remove = *recording_it; - bool was_current = recording_to_remove->mPartialRecording.isCurrent(); - llassert(recording_to_remove->mTargetRecording == recording); - mActiveRecordings.erase(recording_it); - if (was_current) + if (mActiveRecordings.empty()) { - if (mActiveRecordings.empty()) - { - AccumulatorBufferGroup::clearCurrent(); - } - else - { - mActiveRecordings.back()->mPartialRecording.makeCurrent(); - } + AccumulatorBufferGroup::clearCurrent(); + } + else + { + mActiveRecordings.back()->mPartialRecording.makeCurrent(); } - delete recording_to_remove; } + delete recording_to_remove; } ThreadRecorder::ActiveRecording::ActiveRecording( AccumulatorBufferGroup* target ) -- cgit v1.2.3 From 3040b429a3b136b87ddb0ae88ccfa3a7aa71e232 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 6 Feb 2014 11:27:16 -0800 Subject: added LL_TRACE_ENABLED to allow disabling of lltrace --- indra/llcommon/lltracethreadrecorder.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'indra/llcommon/lltracethreadrecorder.cpp') diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 187d8546d3..181fc2f058 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -47,6 +47,7 @@ ThreadRecorder::ThreadRecorder() void ThreadRecorder::init() { +#if LL_TRACE_ENABLED LLThreadLocalSingletonPointer::setInstance(&mBlockTimerStackRecord); //NB: the ordering of initialization in this function is very fragile due to a large number of implicit dependencies set_thread_recorder(this); @@ -83,6 +84,7 @@ void ThreadRecorder::init() claim_alloc(gTraceMemStat, this); claim_alloc(gTraceMemStat, mRootTimer); claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes); +#endif } @@ -96,6 +98,7 @@ ThreadRecorder::ThreadRecorder( ThreadRecorder& parent ) ThreadRecorder::~ThreadRecorder() { +#if LL_TRACE_ENABLED LLThreadLocalSingletonPointer::setInstance(NULL); disclaim_alloc(gTraceMemStat, this); @@ -119,19 +122,23 @@ ThreadRecorder::~ThreadRecorder() { mParentRecorder->removeChildRecorder(this); } +#endif } TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode( S32 index ) { +#if LL_TRACE_ENABLED if (0 <= index && index < mNumTimeBlockTreeNodes) { return &mTimeBlockTreeNodes[index]; } +#endif return NULL; } AccumulatorBufferGroup* ThreadRecorder::activate( AccumulatorBufferGroup* recording) { +#if LL_TRACE_ENABLED ActiveRecording* active_recording = new ActiveRecording(recording); if (!mActiveRecordings.empty()) { @@ -144,10 +151,14 @@ AccumulatorBufferGroup* ThreadRecorder::activate( AccumulatorBufferGroup* record mActiveRecordings.back()->mPartialRecording.makeCurrent(); return &active_recording->mPartialRecording; +#else + return NULL; +#endif } ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording ) { +#if LL_TRACE_ENABLED if (mActiveRecordings.empty()) return mActiveRecordings.end(); mActiveRecordings.back()->mPartialRecording.sync(); @@ -186,10 +197,14 @@ ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( } return (++it).base(); +#else + return ThreadRecorder::active_recording_list_t::iterator(); +#endif } void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) { +#if LL_TRACE_ENABLED active_recording_list_t::iterator recording_it = bringUpToDate(recording); // this method should only be called on a thread where the recorder is active llassert_always(recording_it != mActiveRecordings.end()); @@ -210,6 +225,7 @@ void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording ) } } delete recording_to_remove; +#endif } ThreadRecorder::ActiveRecording::ActiveRecording( AccumulatorBufferGroup* target ) @@ -218,35 +234,43 @@ ThreadRecorder::ActiveRecording::ActiveRecording( AccumulatorBufferGroup* target void ThreadRecorder::ActiveRecording::movePartialToTarget() { +#if LL_TRACE_ENABLED mTargetRecording->append(mPartialRecording); // reset based on self to keep history mPartialRecording.reset(&mPartialRecording); +#endif } // called by child thread void ThreadRecorder::addChildRecorder( class ThreadRecorder* child ) { +#if LL_TRACE_ENABLED { LLMutexLock lock(&mChildListMutex); mChildThreadRecorders.push_back(child); } +#endif } // called by child thread void ThreadRecorder::removeChildRecorder( class ThreadRecorder* child ) { +#if LL_TRACE_ENABLED { LLMutexLock lock(&mChildListMutex); mChildThreadRecorders.remove(child); } +#endif } void ThreadRecorder::pushToParent() { +#if LL_TRACE_ENABLED { LLMutexLock lock(&mSharedRecordingMutex); LLTrace::get_thread_recorder()->bringUpToDate(&mThreadRecordingBuffers); mSharedRecordingBuffers.append(mThreadRecordingBuffers); mThreadRecordingBuffers.reset(); } +#endif } @@ -254,6 +278,7 @@ static LLTrace::BlockTimerStatHandle FTM_PULL_TRACE_DATA_FROM_CHILDREN("Pull chi void ThreadRecorder::pullFromChildren() { +#if LL_TRACE_ENABLED LL_RECORD_BLOCK_TIME(FTM_PULL_TRACE_DATA_FROM_CHILDREN); if (mActiveRecordings.empty()) return; @@ -270,6 +295,7 @@ void ThreadRecorder::pullFromChildren() (*it)->mSharedRecordingBuffers.reset(); } } +#endif } -- cgit v1.2.3