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/llthreadlocalstorage.h | 8 ++------ indra/llcommon/lltrace.h | 21 ++++++++++++--------- indra/llcommon/lltracerecording.cpp | 5 +++-- indra/llcommon/lltracerecording.h | 6 +++--- indra/llcommon/lltracethreadrecorder.cpp | 25 ++++++++++++++++++------- indra/llcommon/lltracethreadrecorder.h | 14 +++++++++----- 6 files changed, 47 insertions(+), 32 deletions(-) diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h index 471784749b..cc67248124 100644 --- a/indra/llcommon/llthreadlocalstorage.h +++ b/indra/llcommon/llthreadlocalstorage.h @@ -313,11 +313,6 @@ template class LLThreadLocalSingletonPointer { public: - void operator =(DERIVED_TYPE* value) - { - setInstance(value); - } - LL_FORCE_INLINE static DERIVED_TYPE* getInstance() { #if LL_DARWIN @@ -328,7 +323,7 @@ public: #endif } - LL_FORCE_INLINE static void setInstance(DERIVED_TYPE* instance) + static void setInstance(DERIVED_TYPE* instance) { #if LL_DARWIN createTLSKey(); @@ -339,6 +334,7 @@ public: } private: + #if LL_WINDOWS static __declspec(thread) DERIVED_TYPE* sInstance; #elif LL_LINUX diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index e950a119d3..00bab536ff 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -35,6 +35,7 @@ #include "llunit.h" #include "llapr.h" #include "llthreadlocalstorage.h" +#include "lltimer.h" #include @@ -75,7 +76,6 @@ void set_thread_recorder(class ThreadRecorder*); class MasterThreadRecorder& getUIThreadRecorder(); -// one per thread per type template class AccumulatorBuffer : public LLRefCount { @@ -104,9 +104,9 @@ public: ~AccumulatorBuffer() { - if (LLThreadLocalSingletonPointer::getInstance() == mStorage) + if (isPrimary()) { - LLThreadLocalSingletonPointer::setInstance(getDefaultBuffer()->mStorage); + LLThreadLocalSingletonPointer::setInstance(NULL); } delete[] mStorage; } @@ -169,7 +169,8 @@ public: LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() { - return LLThreadLocalSingletonPointer::getInstance(); + ACCUMULATOR* accumulator = LLThreadLocalSingletonPointer::getInstance(); + return accumulator ? accumulator : sDefaultBuffer->mStorage; } // NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned @@ -222,25 +223,27 @@ public: static self_t* getDefaultBuffer() { - // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data - // so as not to trigger an access violation - static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker()); static bool sInitialized = false; if (!sInitialized) { - sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); + // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data + // so as not to trigger an access violation + sDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker()); sInitialized = true; + sDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); } - return sBuffer; + return sDefaultBuffer; } private: ACCUMULATOR* mStorage; size_t mStorageSize; static size_t sNextStorageSlot; + static self_t* sDefaultBuffer; }; template size_t AccumulatorBuffer::sNextStorageSlot = 0; +template AccumulatorBuffer* AccumulatorBuffer::sDefaultBuffer = NULL; template class TraceType diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 5b0b74524f..86cdca3e10 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -490,8 +490,9 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) { if (mAutoResize) { - for (S32 other_index = (other.mCurPeriod + 2) % other_recording_count; - other_index != other.mCurPeriod; + for (S32 other_index = (other.mCurPeriod + 2) % other_recording_count, + end_index = (other.mCurPeriod + 1) % other_recording_count; + other_index != end_index; other_index = (other_index + 1) % other_recording_count) { llassert(other.mRecordingPeriods[other_index].getDuration() != 0.f diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 19a4fae737..aaeb32e891 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -336,12 +336,12 @@ namespace LLTrace } template - typename T getPeriodMin(const TraceType >& stat, size_t num_periods = U32_MAX) const + T getPeriodMin(const TraceType >& stat, size_t num_periods = U32_MAX) const { size_t total_periods = mRecordingPeriods.size(); num_periods = llmin(num_periods, total_periods); - typename T min_val = std::numeric_limits::max(); + T min_val = std::numeric_limits::max(); for (S32 i = 1; i <= num_periods; i++) { S32 index = (mCurPeriod + total_periods - i) % total_periods; @@ -351,7 +351,7 @@ namespace LLTrace } template - typename T getPeriodMin(const TraceType >& stat, size_t num_periods = U32_MAX) const + T getPeriodMin(const TraceType >& stat, size_t num_periods = U32_MAX) const { size_t total_periods = mRecordingPeriods.size(); num_periods = llmin(num_periods, total_periods); diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 75c7cb2ff1..89b5df1f94 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -202,14 +202,21 @@ SlaveThreadRecorder::~SlaveThreadRecorder() mMasterRecorder.removeSlaveThread(this); } -void SlaveThreadRecorder::pushToMaster() +bool SlaveThreadRecorder::pushToMaster() { - mThreadRecording.stop(); + if (mPushCount != mMasterRecorder.getPullCount()) { - LLMutexLock(mMasterRecorder.getSlaveListMutex()); - mSharedData.appendFrom(mThreadRecording); + mThreadRecording.stop(); + { + LLMutexLock(mMasterRecorder.getSlaveListMutex()); + mSharedData.appendFrom(mThreadRecording); + } + mThreadRecording.start(); + + mPushCount = mMasterRecorder.getPullCount(); + return true; } - mThreadRecording.start(); + return false; } void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source ) @@ -264,6 +271,8 @@ void MasterThreadRecorder::pullFromSlaveThreads() (*it)->mSharedData.mergeTo(target_recording_buffers); (*it)->mSharedData.reset(); } + + mPullCount++; } void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child ) @@ -289,8 +298,10 @@ void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child ) } } -void MasterThreadRecorder::pushToMaster() -{} +bool MasterThreadRecorder::pushToMaster() +{ + return false; +} MasterThreadRecorder::MasterThreadRecorder() {} diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h index 17a2d4a9a9..a044757e62 100644 --- a/indra/llcommon/lltracethreadrecorder.h +++ b/indra/llcommon/lltracethreadrecorder.h @@ -49,7 +49,7 @@ namespace LLTrace void deactivate(Recording* recording); active_recording_list_t::reverse_iterator bringUpToDate(Recording* recording); - virtual void pushToMaster() = 0; + virtual bool pushToMaster() = 0; TimeBlockTreeNode* getTimeBlockTreeNode(S32 index); @@ -80,19 +80,22 @@ namespace LLTrace void addSlaveThread(class SlaveThreadRecorder* child); void removeSlaveThread(class SlaveThreadRecorder* child); - /*virtual */ void pushToMaster(); + /*virtual */ bool pushToMaster(); // call this periodically to gather stats data from slave threads void pullFromSlaveThreads(); LLMutex* getSlaveListMutex() { return &mSlaveListMutex; } + U32 getPullCount() { return mPullCount; } + private: typedef std::list slave_thread_recorder_list_t; - slave_thread_recorder_list_t mSlaveThreadRecorders; - LLMutex mSlaveListMutex; + slave_thread_recorder_list_t mSlaveThreadRecorders; // list of slave thread recorders associated with this master + LLMutex mSlaveListMutex; // protects access to slave list + LLAtomicU32 mPullCount; // number of times data has been pulled from slaves }; class LL_COMMON_API SlaveThreadRecorder : public ThreadRecorder @@ -102,7 +105,7 @@ namespace LLTrace ~SlaveThreadRecorder(); // call this periodically to gather stats data for master thread to consume - /*virtual*/ void pushToMaster(); + /*virtual*/ bool pushToMaster(); MasterThreadRecorder* mMaster; @@ -119,6 +122,7 @@ namespace LLTrace }; SharedData mSharedData; MasterThreadRecorder& mMasterRecorder; + U32 mPushCount; }; } -- cgit v1.2.3