From 735fde8c742188d019e41faf26ff67aab6a24d25 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 21 Sep 2012 18:52:08 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages added LLThreadLocalPtr broke llmutex out into llmutex.h got primary sampling buffer under thread local storage --- indra/llcommon/llthread.cpp | 214 ++++---------------------------------------- 1 file changed, 19 insertions(+), 195 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index a6ad6b125c..f3ab8aa40c 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -29,6 +29,7 @@ #include "apr_portable.h" #include "llthread.h" +#include "llmutex.h" #include "lltimer.h" @@ -56,12 +57,20 @@ // //---------------------------------------------------------------------------- -#if !LL_DARWIN -U32 ll_thread_local sThreadID = 0; -#endif +#if LL_DARWIN +// statically allocated thread local storage not supported in Darwin executable formats +#elif LL_WINDOWS +U32 __declspec(thread) LLThread::sThreadIndex = 0; +#elif LL_LINUX +U32 __thread LLThread::sThreadID = 0; +#endif U32 LLThread::sIDIter = 0; +LLTrace::MasterThreadTrace gMasterThreadTrace; +LLThreadLocalPtr LLThread::sTraceData(&gMasterThreadTrace); + + LL_COMMON_API void assert_main_thread() { static U32 s_thread_id = LLThread::currentID(); @@ -78,8 +87,10 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap { LLThread *threadp = (LLThread *)datap; + sTraceData = new LLTrace::SlaveThreadTrace(gMasterThreadTrace); + #if !LL_DARWIN - sThreadID = threadp->mID; + sThreadIndex = threadp->mID; #endif // Run the user supplied function @@ -93,7 +104,6 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap return NULL; } - LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mPaused(FALSE), mName(name), @@ -301,198 +311,12 @@ void LLThread::wakeLocked() } } -//============================================================================ - -LLMutex::LLMutex(apr_pool_t *poolp) : - mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD) -{ - //if (poolp) - //{ - // mIsLocalPool = FALSE; - // mAPRPoolp = poolp; - //} - //else - { - mIsLocalPool = TRUE; - apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread - } - apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); -} - - -LLMutex::~LLMutex() -{ -#if MUTEX_DEBUG - //bad assertion, the subclass LLSignal might be "locked", and that's OK - //llassert_always(!isLocked()); // better not be locked! -#endif - apr_thread_mutex_destroy(mAPRMutexp); - mAPRMutexp = NULL; - if (mIsLocalPool) - { - apr_pool_destroy(mAPRPoolp); - } -} - - -void LLMutex::lock() -{ - if(isSelfLocked()) - { //redundant lock - mCount++; - return; - } - - apr_thread_mutex_lock(mAPRMutexp); - -#if MUTEX_DEBUG - // Have to have the lock before we can access the debug info - U32 id = LLThread::currentID(); - if (mIsLocked[id] != FALSE) - llerrs << "Already locked in Thread: " << id << llendl; - mIsLocked[id] = TRUE; -#endif - -#if LL_DARWIN - mLockingThread = LLThread::currentID(); -#else - mLockingThread = sThreadID; -#endif -} - -void LLMutex::unlock() -{ - if (mCount > 0) - { //not the root unlock - mCount--; - return; - } - -#if MUTEX_DEBUG - // Access the debug info while we have the lock - U32 id = LLThread::currentID(); - if (mIsLocked[id] != TRUE) - llerrs << "Not locked in Thread: " << id << llendl; - mIsLocked[id] = FALSE; -#endif - - mLockingThread = NO_THREAD; - apr_thread_mutex_unlock(mAPRMutexp); -} - -bool LLMutex::isLocked() -{ - apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp); - if (APR_STATUS_IS_EBUSY(status)) - { - return true; - } - else - { - apr_thread_mutex_unlock(mAPRMutexp); - return false; - } -} - -bool LLMutex::isSelfLocked() -{ -#if LL_DARWIN - return mLockingThread == LLThread::currentID(); -#else - return mLockingThread == sThreadID; -#endif -} - -U32 LLMutex::lockingThread() const -{ - return mLockingThread; -} - -//============================================================================ - -LLCondition::LLCondition(apr_pool_t *poolp) : - LLMutex(poolp) -{ - // base class (LLMutex) has already ensured that mAPRPoolp is set up. - - apr_thread_cond_create(&mAPRCondp, mAPRPoolp); -} - - -LLCondition::~LLCondition() -{ - apr_thread_cond_destroy(mAPRCondp); - mAPRCondp = NULL; -} - - -void LLCondition::wait() -{ - if (!isLocked()) - { //mAPRMutexp MUST be locked before calling apr_thread_cond_wait - apr_thread_mutex_lock(mAPRMutexp); -#if MUTEX_DEBUG - // avoid asserts on destruction in non-release builds - U32 id = LLThread::currentID(); - mIsLocked[id] = TRUE; -#endif - } - apr_thread_cond_wait(mAPRCondp, mAPRMutexp); -} - -void LLCondition::signal() -{ - apr_thread_cond_signal(mAPRCondp); -} - -void LLCondition::broadcast() -{ - apr_thread_cond_broadcast(mAPRCondp); -} - -//============================================================================ - -//---------------------------------------------------------------------------- - -//static -LLMutex* LLThreadSafeRefCount::sMutex = 0; - -//static -void LLThreadSafeRefCount::initThreadSafeRefCount() -{ - if (!sMutex) - { - sMutex = new LLMutex(0); - } -} - -//static -void LLThreadSafeRefCount::cleanupThreadSafeRefCount() +void LLThread::lockData() { - delete sMutex; - sMutex = NULL; -} - - -//---------------------------------------------------------------------------- - -LLThreadSafeRefCount::LLThreadSafeRefCount() : - mRef(0) -{ -} - -LLThreadSafeRefCount::~LLThreadSafeRefCount() -{ - if (mRef != 0) - { - llerrs << "deleting non-zero reference" << llendl; - } + mRunCondition->lock(); } -//============================================================================ - -LLResponder::~LLResponder() +void LLThread::unlockData() { + mRunCondition->unlock(); } - -//============================================================================ -- cgit v1.3 From adeeabfc13c91dc99a1ea1949cd2f820c4150995 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 24 Sep 2012 18:56:01 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages moved LLThreadLocalPtr to llapr fixed various startup race conditions for LLThreadLocalPtr --- indra/llcommon/CMakeLists.txt | 1 - indra/llcommon/llapr.cpp | 82 ++++++++++++++++++++++ indra/llcommon/llapr.h | 117 +++++++++++++++++++++++++++++++ indra/llcommon/llcommon.cpp | 2 + indra/llcommon/llthread.cpp | 8 +-- indra/llcommon/llthread.h | 1 - indra/llcommon/llthreadlocalptr.h | 141 -------------------------------------- indra/llcommon/lltrace.cpp | 16 ++++- indra/llcommon/lltrace.h | 57 +++++++-------- 9 files changed, 249 insertions(+), 176 deletions(-) delete mode 100644 indra/llcommon/llthreadlocalptr.h (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index eec2695dde..f78751601c 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -240,7 +240,6 @@ set(llcommon_HEADER_FILES llstringtable.h llsys.h llthread.h - llthreadlocalptr.h llthreadsafequeue.h lltimer.h lltrace.h diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index d1c44c9403..76749f8a91 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -54,6 +54,8 @@ void ll_init_apr() { LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; } + + LLThreadLocalPtrBase::initAllThreadLocalStorage(); } @@ -476,6 +478,86 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset) return LLAPRFile::seek(mFile, where, offset) ; } +// +//LLThreadLocalPtrBase +// +bool LLThreadLocalPtrBase::sInitialized = false; + +LLThreadLocalPtrBase::LLThreadLocalPtrBase(void (*cleanup_func)(void*)) +: mCleanupFunc(cleanup_func), + mThreadKey(NULL) +{ + if (sInitialized) + { + initStorage(); + } +} + +LLThreadLocalPtrBase::LLThreadLocalPtrBase( const LLThreadLocalPtrBase& other) +: mCleanupFunc(other.mCleanupFunc), + mThreadKey(NULL) +{ + if (sInitialized) + { + initStorage(); + } +} + +LLThreadLocalPtrBase::~LLThreadLocalPtrBase() +{ + destroyStorage(); +} + +void LLThreadLocalPtrBase::set( void* value ) +{ + llassert(sInitialized && mThreadKey); + + apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey); + if (result != APR_SUCCESS) + { + ll_apr_warn_status(result); + llerrs << "Failed to set thread local data" << llendl; + } +} + +void LLThreadLocalPtrBase::initStorage( ) +{ + apr_status_t result = apr_threadkey_private_create(&mThreadKey, mCleanupFunc, gAPRPoolp); + if (result != APR_SUCCESS) + { + ll_apr_warn_status(result); + llerrs << "Failed to allocate thread local data" << llendl; + } +} + +void LLThreadLocalPtrBase::destroyStorage() +{ + if (mThreadKey) + { + apr_status_t result = apr_threadkey_private_delete(mThreadKey); + if (result != APR_SUCCESS) + { + ll_apr_warn_status(result); + llerrs << "Failed to delete thread local data" << llendl; + } + } +} + +void LLThreadLocalPtrBase::initAllThreadLocalStorage() +{ + if (!sInitialized) + { + sInitialized = true; + for (LLInstanceTracker::instance_iter it = beginInstances(), end_it = endInstances(); + it != end_it; + ++it) + { + (*it).initStorage(); + } + } +} + + // //******************************************************************************************************************************* //static components of LLAPRFile diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index af33ce666f..eb0bf627a0 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -49,6 +49,7 @@ #include "apr_signal.h" #include "apr_atomic.h" #include "llstring.h" +#include "llinstancetracker.h" extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp; extern apr_thread_mutex_t* gCallStacksLogMutexp; @@ -255,6 +256,122 @@ public: //******************************************************************************************************************************* }; +class LLThreadLocalPtrBase : LLInstanceTracker +{ +public: + LLThreadLocalPtrBase(void (*cleanup_func)(void*) ); + LLThreadLocalPtrBase(const LLThreadLocalPtrBase& other); + ~LLThreadLocalPtrBase(); + +protected: + friend void LL_COMMON_API ll_init_apr(); + void set(void* value); + + LL_FORCE_INLINE void* get() + { + void* ptr; + //apr_status_t result = + apr_threadkey_private_get(&ptr, mThreadKey); + //if (result != APR_SUCCESS) + //{ + // ll_apr_warn_status(s); + // llerrs << "Failed to get thread local data" << llendl; + //} + return ptr; + } + + LL_FORCE_INLINE const void* get() const + { + void* ptr; + //apr_status_t result = + apr_threadkey_private_get(&ptr, mThreadKey); + //if (result != APR_SUCCESS) + //{ + // ll_apr_warn_status(s); + // llerrs << "Failed to get thread local data" << llendl; + //} + return ptr; + } + + void initStorage(); + + void destroyStorage(); + + static void initAllThreadLocalStorage(); + +private: + void (*mCleanupFunc)(void*); + apr_threadkey_t* mThreadKey; + static bool sInitialized; +}; + +template +class LLThreadLocalPtr : public LLThreadLocalPtrBase +{ +public: + + LLThreadLocalPtr() + : LLThreadLocalPtrBase(&cleanup) + {} + + LLThreadLocalPtr(T* value) + : LLThreadLocalPtrBase(&cleanup) + { + set(value); + } + + + LLThreadLocalPtr(const LLThreadLocalPtr& other) + : LLThreadLocalPtrBase(other, &cleanup) + { + set(other.get()); + } + + T* get() + { + return (T*)LLThreadLocalPtrBase::get(); + } + + const T* get() const + { + return (const T*)LLThreadLocalPtrBase::get(); + } + + T* operator -> () + { + return (T*)get(); + } + + const T* operator -> () const + { + return (T*)get(); + } + + T& operator*() + { + return *(T*)get(); + } + + const T& operator*() const + { + return *(T*)get(); + } + + LLThreadLocalPtr& operator = (T* value) + { + set((void*)value); + return *this; + } + +private: + + static void cleanup(void* ptr) + { + delete reinterpret_cast(ptr); + } + +}; + /** * @brief Function which appropriately logs error or remains quiet on * APR_SUCCESS. diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 8be9e4f4de..512e7da840 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -44,6 +44,7 @@ void LLCommon::initClass() } LLTimer::initClass(); LLThreadSafeRefCount::initThreadSafeRefCount(); + LLTrace::init(); // LLWorkerThread::initClass(); // LLFrameCallbackManager::initClass(); } @@ -61,4 +62,5 @@ void LLCommon::cleanupClass() sAprInitialized = FALSE; } LLMemory::cleanupClass(); + LLTrace::cleanup(); } diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index f3ab8aa40c..023004eedd 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -66,9 +66,7 @@ U32 __thread LLThread::sThreadID = 0; #endif U32 LLThread::sIDIter = 0; - -LLTrace::MasterThreadTrace gMasterThreadTrace; -LLThreadLocalPtr LLThread::sTraceData(&gMasterThreadTrace); +LLThreadLocalPtr LLThread::sTraceData; LL_COMMON_API void assert_main_thread() @@ -87,7 +85,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap { LLThread *threadp = (LLThread *)datap; - sTraceData = new LLTrace::SlaveThreadTrace(gMasterThreadTrace); + sTraceData = new LLTrace::SlaveThreadTrace(); #if !LL_DARWIN sThreadIndex = threadp->mID; @@ -155,7 +153,7 @@ void LLThread::shutdown() //llinfos << "LLThread::~LLThread() Killing thread " << mName << " Status: " << mStatus << llendl; // Now wait a bit for the thread to exit // It's unclear whether I should even bother doing this - this destructor - // should netver get called unless we're already stopped, really... + // should never get called unless we're already stopped, really... S32 counter = 0; const S32 MAX_WAIT = 600; while (counter < MAX_WAIT) diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index e2de4c8b85..e50fa7653d 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -31,7 +31,6 @@ #include "llapr.h" #include "apr_thread_cond.h" #include "lltrace.h" -#include "llthreadlocalptr.h" class LL_COMMON_API LLThread { diff --git a/indra/llcommon/llthreadlocalptr.h b/indra/llcommon/llthreadlocalptr.h deleted file mode 100644 index f02f4849ca..0000000000 --- a/indra/llcommon/llthreadlocalptr.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * @file llthreadlocalptr.h - * @brief manage thread local storage through non-copyable pointer - * - * $LicenseInfo:firstyear=2004&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$ - */ - -#ifndef LL_LLTHREAD_LOCAL_PTR_H -#define LL_LLTHREAD_LOCAL_PTR_H - -#include "llapr.h" - -template -class LLThreadLocalPtr -{ -public: - LLThreadLocalPtr(T* value = NULL, apr_pool_t* pool = NULL) - { - apr_status_t result = apr_threadkey_private_create(&mThreadKey, cleanup, pool); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - llerrs << "Failed to allocate thread local data" << llendl; - } - set(value); - } - - - ~LLThreadLocalPtr() - { - apr_status_t result = apr_threadkey_private_delete(mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - llerrs << "Failed to delete thread local data" << llendl; - } - } - - T* operator -> () - { - return get(); - } - - const T* operator -> () const - { - return get(); - } - - T& operator*() - { - return *get(); - } - - const T& operator*() const - { - return *get(); - } - - LLThreadLocalPtr& operator = (T* value) - { - set(value); - return *this; - } - - void copyFrom(const LLThreadLocalPtr& other) - { - set(other.get()); - } - - LL_FORCE_INLINE void set(T* value) - { - apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - llerrs << "Failed to set thread local data" << llendl; - } - } - - LL_FORCE_INLINE T* get() - { - T* ptr; - //apr_status_t result = - apr_threadkey_private_get((void**)&ptr, mThreadKey); - //if (result != APR_SUCCESS) - //{ - // ll_apr_warn_status(s); - // llerrs << "Failed to get thread local data" << llendl; - //} - return ptr; - } - - LL_FORCE_INLINE const T* get() const - { - T* ptr; - //apr_status_t result = - apr_threadkey_private_get((void**)&ptr, mThreadKey); - //if (result != APR_SUCCESS) - //{ - // ll_apr_warn_status(s); - // llerrs << "Failed to get thread local data" << llendl; - //} - return ptr; - } - - -private: - static void cleanup(void* ptr) - { - delete reinterpret_cast(ptr); - } - - LLThreadLocalPtr(const LLThreadLocalPtr& other) - { - // do not copy construct - llassert(false); - } - - apr_threadkey_t* mThreadKey; -}; - -#endif // LL_LLTHREAD_LOCAL_PTR_H diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 037c52f8c1..501414ebf3 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -32,7 +32,21 @@ namespace LLTrace { BlockTimer::Recorder::StackEntry BlockTimer::sCurRecorder; -LLThreadLocalPtr ThreadTraceData::sCurThreadTrace; + +MasterThreadTrace *gMasterThreadTrace = NULL; +LLThreadLocalPtr gCurThreadTrace; + +void init() +{ + gMasterThreadTrace = new MasterThreadTrace(); + gCurThreadTrace = gMasterThreadTrace; +} + +void cleanup() +{ + delete gMasterThreadTrace; +} + /////////////////////////////////////////////////////////////////////// // Sampler diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 401ddfd6f3..3af05d67f9 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -32,7 +32,6 @@ #include "llmutex.h" #include "llmemory.h" -#include "llthreadlocalptr.h" #include @@ -42,19 +41,29 @@ namespace LLTrace { + void init(); + void cleanup(); + + extern class MasterThreadTrace *gMasterThreadTrace; + extern LLThreadLocalPtr gCurThreadTrace; + // one per thread per type template class AccumulatorBuffer { static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; - public: - AccumulatorBuffer() + private: + enum StaticAllocationMarker { STATIC_ALLOC }; + + AccumulatorBuffer(StaticAllocationMarker m) : mStorageSize(64), - mStorage(new ACCUMULATOR[DEFAULT_ACCUMULATOR_BUFFER_SIZE]), - mNextStorageSlot(0) - {} + mNextStorageSlot(0), + mStorage(new ACCUMULATOR[DEFAULT_ACCUMULATOR_BUFFER_SIZE]) + { + } + public: - AccumulatorBuffer(const AccumulatorBuffer& other) + AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer()) : mStorageSize(other.mStorageSize), mStorage(new ACCUMULATOR[other.mStorageSize]), mNextStorageSlot(other.mNextStorageSlot) @@ -116,6 +125,12 @@ namespace LLTrace return next_slot; } + static AccumulatorBuffer& getDefaultBuffer() + { + static AccumulatorBuffer sBuffer; + return sBuffer; + } + private: ACCUMULATOR* mStorage; size_t mStorageSize; @@ -124,15 +139,6 @@ namespace LLTrace }; template LLThreadLocalPtr AccumulatorBuffer::sPrimaryStorage; - template - class PrimaryAccumulatorBuffer : public AccumulatorBuffer class Trace { @@ -140,7 +146,7 @@ namespace LLTrace Trace(const std::string& name) : mName(name) { - mAccumulatorIndex = getPrimaryBuffer().reserveSlot(); + mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); } LL_FORCE_INLINE ACCUMULATOR& getAccumulator() @@ -148,12 +154,6 @@ namespace LLTrace return AccumulatorBuffer::getPrimaryStorage()[mAccumulatorIndex]; } - static PrimaryAccumulatorBuffer& getPrimaryBuffer() - { - static PrimaryAccumulatorBuffer sBuffer; - return sBuffer; - } - private: std::string mName; size_t mAccumulatorIndex; @@ -347,9 +347,13 @@ namespace LLTrace { public: Sampler() {} - Sampler(const Sampler& other); + Sampler(const Sampler& other) + : mF32Stats(other.mF32Stats), + mS32Stats(other.mS32Stats), + mTimers(other.mTimers) + {} - ~Sampler(); + ~Sampler() {} void makePrimary() { @@ -438,7 +442,6 @@ namespace LLTrace protected: Sampler mPrimarySampler; std::list mActiveSamplers; - static LLThreadLocalPtr sCurThreadTrace; }; class MasterThreadTrace : public ThreadTraceData @@ -472,7 +475,7 @@ namespace LLTrace { public: explicit - SlaveThreadTrace(MasterThreadTrace& master_trace) + SlaveThreadTrace(MasterThreadTrace& master_trace = *gMasterThreadTrace) : mMaster(master_trace), ThreadTraceData(master_trace), mSharedData(mPrimarySampler) -- cgit v1.3 From 308ff886c3ab2aa561477921bc0d92e1bd7d399a Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 24 Sep 2012 19:01:48 -0700 Subject: fixed build moved LLThread::lockData and unlockData back to header --- indra/llcommon/llthread.cpp | 10 ---------- indra/llcommon/llthread.h | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 023004eedd..de1f0801a1 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -308,13 +308,3 @@ void LLThread::wakeLocked() mRunCondition->signal(); } } - -void LLThread::lockData() -{ - mRunCondition->lock(); -} - -void LLThread::unlockData() -{ - mRunCondition->unlock(); -} diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index e50fa7653d..fed111b0e4 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -136,6 +136,18 @@ protected: // mRunCondition->unlock(); }; + +void LLThread::lockData() +{ + mRunCondition->lock(); +} + +void LLThread::unlockData() +{ + mRunCondition->unlock(); +} + + //============================================================================ #endif // LL_LLTHREAD_H -- cgit v1.3 From 05a3203d8274a0a0999faad128f629614b8d62c5 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 26 Sep 2012 17:04:57 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages fixed various issues related to unit tests and LLThreadLocalPtr initialization and teardown --- indra/llcommon/llapr.cpp | 45 +++++++++++++++++++--------- indra/llcommon/llapr.h | 27 ++++++++--------- indra/llcommon/llcommon.cpp | 6 +--- indra/llcommon/llthread.cpp | 5 +++- indra/llcommon/llthread.h | 2 +- indra/llcommon/lltrace.cpp | 33 ++++++++++++++------- indra/llcommon/lltrace.h | 47 +++++++++++++++++------------- indra/llimage/tests/llimageworker_test.cpp | 5 ++++ indra/test/test.cpp | 15 ++++------ 9 files changed, 108 insertions(+), 77 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 76749f8a91..e9930c10f7 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -52,7 +52,7 @@ void ll_init_apr() if(!LLAPRFile::sAPRFilePoolp) { - LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; + LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE); } LLThreadLocalPtrBase::initAllThreadLocalStorage(); @@ -79,6 +79,9 @@ void ll_cleanup_apr() apr_thread_mutex_destroy(gCallStacksLogMutexp); gCallStacksLogMutexp = NULL; } + + LLThreadLocalPtrBase::destroyAllThreadLocalStorage(); + if (gAPRPoolp) { apr_pool_destroy(gAPRPoolp); @@ -86,7 +89,7 @@ void ll_cleanup_apr() } if (LLAPRFile::sAPRFilePoolp) { - delete LLAPRFile::sAPRFilePoolp ; + delete LLAPRFile::sAPRFilePoolp ; LLAPRFile::sAPRFilePoolp = NULL ; } apr_terminate(); @@ -483,9 +486,8 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset) // bool LLThreadLocalPtrBase::sInitialized = false; -LLThreadLocalPtrBase::LLThreadLocalPtrBase(void (*cleanup_func)(void*)) -: mCleanupFunc(cleanup_func), - mThreadKey(NULL) +LLThreadLocalPtrBase::LLThreadLocalPtrBase() +: mThreadKey(NULL) { if (sInitialized) { @@ -494,8 +496,7 @@ LLThreadLocalPtrBase::LLThreadLocalPtrBase(void (*cleanup_func)(void*)) } LLThreadLocalPtrBase::LLThreadLocalPtrBase( const LLThreadLocalPtrBase& other) -: mCleanupFunc(other.mCleanupFunc), - mThreadKey(NULL) +: mThreadKey(NULL) { if (sInitialized) { @@ -522,7 +523,7 @@ void LLThreadLocalPtrBase::set( void* value ) void LLThreadLocalPtrBase::initStorage( ) { - apr_status_t result = apr_threadkey_private_create(&mThreadKey, mCleanupFunc, gAPRPoolp); + apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp); if (result != APR_SUCCESS) { ll_apr_warn_status(result); @@ -532,13 +533,16 @@ void LLThreadLocalPtrBase::initStorage( ) void LLThreadLocalPtrBase::destroyStorage() { - if (mThreadKey) + if (sInitialized) { - apr_status_t result = apr_threadkey_private_delete(mThreadKey); - if (result != APR_SUCCESS) + if (mThreadKey) { - ll_apr_warn_status(result); - llerrs << "Failed to delete thread local data" << llendl; + apr_status_t result = apr_threadkey_private_delete(mThreadKey); + if (result != APR_SUCCESS) + { + ll_apr_warn_status(result); + llerrs << "Failed to delete thread local data" << llendl; + } } } } @@ -547,16 +551,29 @@ void LLThreadLocalPtrBase::initAllThreadLocalStorage() { if (!sInitialized) { - sInitialized = true; for (LLInstanceTracker::instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it) { (*it).initStorage(); } + sInitialized = true; } } +void LLThreadLocalPtrBase::destroyAllThreadLocalStorage() +{ + if (sInitialized) + { + for (LLInstanceTracker::instance_iter it = beginInstances(), end_it = endInstances(); + it != end_it; + ++it) + { + (*it).destroyStorage(); + } + sInitialized = false; + } +} // //******************************************************************************************************************************* diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index eb0bf627a0..830e0a33fa 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -259,16 +259,19 @@ public: class LLThreadLocalPtrBase : LLInstanceTracker { public: - LLThreadLocalPtrBase(void (*cleanup_func)(void*) ); + LLThreadLocalPtrBase(); LLThreadLocalPtrBase(const LLThreadLocalPtrBase& other); ~LLThreadLocalPtrBase(); + static void initAllThreadLocalStorage(); + static void destroyAllThreadLocalStorage(); + protected: - friend void LL_COMMON_API ll_init_apr(); void set(void* value); LL_FORCE_INLINE void* get() { + llassert(sInitialized); void* ptr; //apr_status_t result = apr_threadkey_private_get(&ptr, mThreadKey); @@ -294,13 +297,9 @@ protected: } void initStorage(); - void destroyStorage(); - static void initAllThreadLocalStorage(); - -private: - void (*mCleanupFunc)(void*); +protected: apr_threadkey_t* mThreadKey; static bool sInitialized; }; @@ -311,10 +310,10 @@ class LLThreadLocalPtr : public LLThreadLocalPtrBase public: LLThreadLocalPtr() - : LLThreadLocalPtrBase(&cleanup) + : LLThreadLocalPtrBase() {} - LLThreadLocalPtr(T* value) + explicit LLThreadLocalPtr(T* value) : LLThreadLocalPtrBase(&cleanup) { set(value); @@ -327,7 +326,7 @@ public: set(other.get()); } - T* get() + LL_FORCE_INLINE T* get() { return (T*)LLThreadLocalPtrBase::get(); } @@ -363,13 +362,11 @@ public: return *this; } -private: - - static void cleanup(void* ptr) + bool operator ==(T* other) { - delete reinterpret_cast(ptr); + if (!sInitialized) return false; + return get() == other; } - }; /** diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index 512e7da840..c149a1fe5c 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -45,15 +45,12 @@ void LLCommon::initClass() LLTimer::initClass(); LLThreadSafeRefCount::initThreadSafeRefCount(); LLTrace::init(); -// LLWorkerThread::initClass(); -// LLFrameCallbackManager::initClass(); } //static void LLCommon::cleanupClass() { -// LLFrameCallbackManager::cleanupClass(); -// LLWorkerThread::cleanupClass(); + LLTrace::cleanup(); LLThreadSafeRefCount::cleanupThreadSafeRefCount(); LLTimer::cleanupClass(); if (sAprInitialized) @@ -62,5 +59,4 @@ void LLCommon::cleanupClass() sAprInitialized = FALSE; } LLMemory::cleanupClass(); - LLTrace::cleanup(); } diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index de1f0801a1..2e6eb085dc 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -66,7 +66,7 @@ U32 __thread LLThread::sThreadID = 0; #endif U32 LLThread::sIDIter = 0; -LLThreadLocalPtr LLThread::sTraceData; +LLThreadLocalPtr LLThread::sTraceData; LL_COMMON_API void assert_main_thread() @@ -99,6 +99,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap // We're done with the run function, this thread is done executing now. threadp->mStatus = STOPPED; + delete sTraceData.get(); + return NULL; } @@ -108,6 +110,7 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mAPRThreadp(NULL), mStatus(STOPPED) { + mID = ++sIDIter; // Thread creation probably CAN be paranoid about APR being initialized, if necessary diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index fed111b0e4..6889fab2c1 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -105,7 +105,7 @@ protected: EThreadStatus mStatus; U32 mID; - static LLThreadLocalPtr sTraceData; + static LLThreadLocalPtr sTraceData; //a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used. //Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes. diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 501414ebf3..8cedcafd10 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -31,27 +31,37 @@ namespace LLTrace { -BlockTimer::Recorder::StackEntry BlockTimer::sCurRecorder; - -MasterThreadTrace *gMasterThreadTrace = NULL; -LLThreadLocalPtr gCurThreadTrace; +static MasterThreadTrace* gMasterThreadTrace = NULL; void init() { gMasterThreadTrace = new MasterThreadTrace(); - gCurThreadTrace = gMasterThreadTrace; } void cleanup() { delete gMasterThreadTrace; + gMasterThreadTrace = NULL; } +BlockTimer::Recorder::StackEntry BlockTimer::sCurRecorder; + + + +MasterThreadTrace& getMasterThreadTrace() +{ + llassert(gMasterThreadTrace != NULL); + return *gMasterThreadTrace; +} + + + /////////////////////////////////////////////////////////////////////// // Sampler /////////////////////////////////////////////////////////////////////// + void Sampler::stop() { getThreadTrace()->deactivate(this); @@ -71,15 +81,15 @@ class ThreadTraceData* Sampler::getThreadTrace() // MasterThreadTrace /////////////////////////////////////////////////////////////////////// -void MasterThreadTrace::pullFromWorkerThreads() +void MasterThreadTrace::pullFromSlaveThreads() { LLMutexLock lock(&mSlaveListMutex); - for (worker_thread_trace_list_t::iterator it = mSlaveThreadTraces.begin(), end_it = mSlaveThreadTraces.end(); + for (slave_thread_trace_list_t::iterator it = mSlaveThreadTraces.begin(), end_it = mSlaveThreadTraces.end(); it != end_it; ++it) { - it->mWorkerTrace->mSharedData.copyTo(it->mSamplerStorage); + it->mSlaveTrace->mSharedData.copyTo(it->mSamplerStorage); } } @@ -87,18 +97,18 @@ void MasterThreadTrace::addSlaveThread( class SlaveThreadTrace* child ) { LLMutexLock lock(&mSlaveListMutex); - mSlaveThreadTraces.push_back(WorkerThreadTraceProxy(child)); + mSlaveThreadTraces.push_back(SlaveThreadTraceProxy(child)); } void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child ) { LLMutexLock lock(&mSlaveListMutex); - for (worker_thread_trace_list_t::iterator it = mSlaveThreadTraces.begin(), end_it = mSlaveThreadTraces.end(); + for (slave_thread_trace_list_t::iterator it = mSlaveThreadTraces.begin(), end_it = mSlaveThreadTraces.end(); it != end_it; ++it) { - if (it->mWorkerTrace == child) + if (it->mSlaveTrace == child) { mSlaveThreadTraces.erase(it); break; @@ -107,3 +117,4 @@ void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child ) } } + diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 3af05d67f9..e4bec0a644 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -44,8 +44,7 @@ namespace LLTrace void init(); void cleanup(); - extern class MasterThreadTrace *gMasterThreadTrace; - extern LLThreadLocalPtr gCurThreadTrace; + class MasterThreadTrace& getMasterThreadTrace(); // one per thread per type template @@ -59,8 +58,8 @@ namespace LLTrace : mStorageSize(64), mNextStorageSlot(0), mStorage(new ACCUMULATOR[DEFAULT_ACCUMULATOR_BUFFER_SIZE]) - { - } + {} + public: AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer()) @@ -69,6 +68,15 @@ namespace LLTrace mNextStorageSlot(other.mNextStorageSlot) {} + ~AccumulatorBuffer() + { + if (sPrimaryStorage == mStorage) + { + //TODO pick another primary? + sPrimaryStorage = NULL; + } + } + LL_FORCE_INLINE ACCUMULATOR& operator[](size_t index) { return mStorage[index]; @@ -353,7 +361,8 @@ namespace LLTrace mTimers(other.mTimers) {} - ~Sampler() {} + ~Sampler() + {} void makePrimary() { @@ -453,21 +462,21 @@ namespace LLTrace void addSlaveThread(class SlaveThreadTrace* child); void removeSlaveThread(class SlaveThreadTrace* child); - // call this periodically to gather stats data from worker threads - void pullFromWorkerThreads(); + // call this periodically to gather stats data from slave threads + void pullFromSlaveThreads(); private: - struct WorkerThreadTraceProxy + struct SlaveThreadTraceProxy { - WorkerThreadTraceProxy(class SlaveThreadTrace* trace) - : mWorkerTrace(trace) + SlaveThreadTraceProxy(class SlaveThreadTrace* trace) + : mSlaveTrace(trace) {} - class SlaveThreadTrace* mWorkerTrace; + class SlaveThreadTrace* mSlaveTrace; Sampler mSamplerStorage; }; - typedef std::list worker_thread_trace_list_t; + typedef std::list slave_thread_trace_list_t; - worker_thread_trace_list_t mSlaveThreadTraces; + slave_thread_trace_list_t mSlaveThreadTraces; LLMutex mSlaveListMutex; }; @@ -475,17 +484,16 @@ namespace LLTrace { public: explicit - SlaveThreadTrace(MasterThreadTrace& master_trace = *gMasterThreadTrace) - : mMaster(master_trace), - ThreadTraceData(master_trace), + SlaveThreadTrace() + : ThreadTraceData(getMasterThreadTrace()), mSharedData(mPrimarySampler) { - master_trace.addSlaveThread(this); + getMasterThreadTrace().addSlaveThread(this); } ~SlaveThreadTrace() { - mMaster.removeSlaveThread(this); + getMasterThreadTrace().removeSlaveThread(this); } // call this periodically to gather stats data for master thread to consume @@ -494,7 +502,7 @@ namespace LLTrace mSharedData.copyFrom(mPrimarySampler); } - MasterThreadTrace& mMaster; + MasterThreadTrace* mMaster; // this data is accessed by other threads, so give it a 64 byte alignment // to avoid false sharing on most x86 processors @@ -529,7 +537,6 @@ namespace LLTrace SharedData mSharedData; }; - class TimeInterval { public: diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index e255d65b43..be7aae4eb7 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -114,11 +114,13 @@ namespace tut // Constructor and destructor of the test wrapper imagedecodethread_test() { + LLTrace::init(); mThread = NULL; } ~imagedecodethread_test() { delete mThread; + LLTrace::cleanup(); } }; @@ -136,6 +138,8 @@ namespace tut imagerequest_test() { done = false; + LLTrace::init(); + mRequest = new LLImageDecodeThread::ImageRequest(0, 0, LLQueuedThread::PRIORITY_NORMAL, 0, FALSE, new responder_test(&done)); @@ -145,6 +149,7 @@ namespace tut // We should delete the object *but*, because its destructor is protected, that cannot be // done from outside an LLImageDecodeThread instance... So we leak memory here... It's fine... //delete mRequest; + LLTrace::cleanup(); } }; diff --git a/indra/test/test.cpp b/indra/test/test.cpp index dc8580fe69..2b66c6aa26 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -512,15 +512,10 @@ int main(int argc, char **argv) ctype_workaround(); #endif - apr_initialize(); - apr_pool_t* pool = NULL; - if(APR_SUCCESS != apr_pool_create(&pool, NULL)) - { - std::cerr << "Unable to initialize pool" << std::endl; - return 1; - } + ll_init_apr(); + apr_getopt_t* os = NULL; - if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv)) + if(APR_SUCCESS != apr_getopt_init(&os, gAPRPoolp, argc, argv)) { std::cerr << "apr_getopt_init() failed" << std::endl; return 1; @@ -602,7 +597,7 @@ int main(int argc, char **argv) if (LOGFAIL) { LLError::ELevel level = LLError::decodeLevel(LOGFAIL); - replayer.reset(new LLReplayLogReal(level, pool)); + replayer.reset(new LLReplayLogReal(level, gAPRPoolp)); } else { @@ -646,7 +641,7 @@ int main(int argc, char **argv) s.close(); } - apr_terminate(); + ll_cleanup_apr(); int retval = (success ? 0 : 1); return retval; -- cgit v1.3 From 07c4be092b276f0d7c14ba12872efb31c1f16764 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 26 Sep 2012 19:12:40 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages slave threads now pushing data to master thread --- indra/llcommon/llqueuedthread.cpp | 2 ++ indra/llcommon/llthread.cpp | 2 +- indra/llcommon/llthread.h | 5 +-- indra/llcommon/lltrace.cpp | 71 ++++++++++++++++++++++++++++++++++++++- indra/llcommon/lltrace.h | 63 +++++++++------------------------- indra/newview/llappviewer.cpp | 1 + 6 files changed, 93 insertions(+), 51 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 1738c16dea..a741d342d3 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -111,6 +111,8 @@ void LLQueuedThread::shutdown() // virtual S32 LLQueuedThread::update(F32 max_time_ms) { + LLThread::getTraceData()->pushToMaster(); + if (!mStarted) { if (!mThreaded) diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 2e6eb085dc..2ff524d9ba 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -66,7 +66,7 @@ U32 __thread LLThread::sThreadID = 0; #endif U32 LLThread::sIDIter = 0; -LLThreadLocalPtr LLThread::sTraceData; +LLThreadLocalPtr LLThread::sTraceData; LL_COMMON_API void assert_main_thread() diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 6889fab2c1..5cd287ec39 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -87,7 +87,8 @@ public: U32 getID() const { return mID; } - static LLTrace::ThreadTraceData* getTraceData() { return sTraceData.get(); } + static LLTrace::ThreadTrace* getTraceData() { return sTraceData.get(); } + static void setTraceData(LLTrace::ThreadTrace* data) { sTraceData = data;} private: BOOL mPaused; @@ -105,7 +106,7 @@ protected: EThreadStatus mStatus; U32 mID; - static LLThreadLocalPtr sTraceData; + static LLThreadLocalPtr sTraceData; //a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used. //Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes. diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 8cedcafd10..24a2b33a5f 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -72,11 +72,69 @@ void Sampler::resume() getThreadTrace()->activate(this); } -class ThreadTraceData* Sampler::getThreadTrace() +class ThreadTrace* Sampler::getThreadTrace() { return LLThread::getTraceData(); } +/////////////////////////////////////////////////////////////////////// +// MasterThreadTrace +/////////////////////////////////////////////////////////////////////// + +ThreadTrace::ThreadTrace() +{ + mPrimarySampler.makePrimary(); +} + +ThreadTrace::ThreadTrace( const ThreadTrace& other ) : mPrimarySampler(other.mPrimarySampler) +{ + mPrimarySampler.makePrimary(); +} + +void ThreadTrace::activate( Sampler* sampler ) +{ + flushPrimary(); + mActiveSamplers.push_back(sampler); +} + +void ThreadTrace::deactivate( Sampler* sampler ) +{ + sampler->mergeFrom(mPrimarySampler); + + // TODO: replace with intrusive list + std::list::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler); + if (found_it != mActiveSamplers.end()) + { + mActiveSamplers.erase(found_it); + } +} + +void ThreadTrace::flushPrimary() +{ + for (std::list::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end(); + it != end_it; + ++it) + { + (*it)->mergeFrom(mPrimarySampler); + } + mPrimarySampler.reset(); +} + + + + + + +/////////////////////////////////////////////////////////////////////// +// SlaveThreadTrace +/////////////////////////////////////////////////////////////////////// + +void SlaveThreadTrace::pushToMaster() +{ + mSharedData.copyFrom(mPrimarySampler); +} + + /////////////////////////////////////////////////////////////////////// // MasterThreadTrace /////////////////////////////////////////////////////////////////////// @@ -116,5 +174,16 @@ void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child ) } } +void MasterThreadTrace::pushToMaster() +{ + +} + +MasterThreadTrace::MasterThreadTrace() +{ + LLThread::setTraceData(this); +} + + } diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index e4bec0a644..601b5ed182 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -396,7 +396,7 @@ namespace LLTrace private: // returns data for current thread - class ThreadTraceData* getThreadTrace(); + class ThreadTrace* getThreadTrace(); AccumulatorBuffer > mF32Stats; AccumulatorBuffer > mS32Stats; @@ -404,48 +404,19 @@ namespace LLTrace AccumulatorBuffer mTimers; }; - class ThreadTraceData + class ThreadTrace { public: - ThreadTraceData() - { - mPrimarySampler.makePrimary(); - } - - ThreadTraceData(const ThreadTraceData& other) - : mPrimarySampler(other.mPrimarySampler) - { - mPrimarySampler.makePrimary(); - } + ThreadTrace(); + ThreadTrace(const ThreadTrace& other); - void activate(Sampler* sampler) - { - flushPrimary(); - mActiveSamplers.push_back(sampler); - } + virtual ~ThreadTrace() {} - void deactivate(Sampler* sampler) - { - sampler->mergeFrom(mPrimarySampler); - - // TODO: replace with intrusive list - std::list::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler); - if (found_it != mActiveSamplers.end()) - { - mActiveSamplers.erase(found_it); - } - } + void activate(Sampler* sampler); + void deactivate(Sampler* sampler); + void flushPrimary(); - void flushPrimary() - { - for (std::list::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end(); - it != end_it; - ++it) - { - (*it)->mergeFrom(mPrimarySampler); - } - mPrimarySampler.reset(); - } + virtual void pushToMaster() = 0; Sampler* getPrimarySampler() { return &mPrimarySampler; } protected: @@ -453,15 +424,16 @@ namespace LLTrace std::list mActiveSamplers; }; - class MasterThreadTrace : public ThreadTraceData + class MasterThreadTrace : public ThreadTrace { public: - MasterThreadTrace() - {} + MasterThreadTrace(); void addSlaveThread(class SlaveThreadTrace* child); void removeSlaveThread(class SlaveThreadTrace* child); + /*virtual */ void pushToMaster(); + // call this periodically to gather stats data from slave threads void pullFromSlaveThreads(); @@ -480,12 +452,12 @@ namespace LLTrace LLMutex mSlaveListMutex; }; - class SlaveThreadTrace : public ThreadTraceData + class SlaveThreadTrace : public ThreadTrace { public: explicit SlaveThreadTrace() - : ThreadTraceData(getMasterThreadTrace()), + : ThreadTrace(getMasterThreadTrace()), mSharedData(mPrimarySampler) { getMasterThreadTrace().addSlaveThread(this); @@ -497,10 +469,7 @@ namespace LLTrace } // call this periodically to gather stats data for master thread to consume - void pushToParent() - { - mSharedData.copyFrom(mPrimarySampler); - } + /*virtual*/ void pushToMaster(); MasterThreadTrace* mMaster; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index c3ac615169..fcbef491fe 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1222,6 +1222,7 @@ bool LLAppViewer::mainLoop() { LLFastTimer _(FTM_FRAME); LLFastTimer::nextFrame(); + LLTrace::getMasterThreadTrace().pullFromSlaveThreads(); //clear call stack records llclearcallstacks; -- cgit v1.3 From 38354e19063478c8cda0408547ad05023b457041 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 28 Sep 2012 10:45:14 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages created separate constructor for static allocation of sampler buffer fixed start/stop/resume semantics of samplers and added sampler time interval tracking --- indra/llcommon/llcommon.cpp | 1 + indra/llcommon/llqueuedthread.cpp | 1 + indra/llcommon/llthread.cpp | 14 +++- indra/llcommon/llthread.h | 10 ++- indra/llcommon/lltrace.cpp | 117 ++++++++++++++++++++++++----- indra/llcommon/lltrace.h | 108 ++++++++++++-------------- indra/llimage/tests/llimageworker_test.cpp | 2 + indra/newview/llappviewer.cpp | 2 +- 8 files changed, 170 insertions(+), 85 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp index c149a1fe5c..c720df7555 100644 --- a/indra/llcommon/llcommon.cpp +++ b/indra/llcommon/llcommon.cpp @@ -29,6 +29,7 @@ #include "llmemory.h" #include "llthread.h" +#include "lltrace.h" //static BOOL LLCommon::sAprInitialized = FALSE; diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index a741d342d3..0a35474b7f 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -28,6 +28,7 @@ #include "llstl.h" #include "lltimer.h" // ms_sleep() +#include "lltrace.h" //============================================================================ diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 2ff524d9ba..7384842627 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -32,6 +32,7 @@ #include "llmutex.h" #include "lltimer.h" +#include "lltrace.h" #if LL_LINUX || LL_SOLARIS #include @@ -85,7 +86,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap { LLThread *threadp = (LLThread *)datap; - sTraceData = new LLTrace::SlaveThreadTrace(); + setTraceData(new LLTrace::SlaveThreadTrace()); #if !LL_DARWIN sThreadIndex = threadp->mID; @@ -100,6 +101,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap threadp->mStatus = STOPPED; delete sTraceData.get(); + sTraceData = NULL; return NULL; } @@ -311,3 +313,13 @@ void LLThread::wakeLocked() mRunCondition->signal(); } } + +LLTrace::ThreadTrace* LLThread::getTraceData() +{ + return sTraceData.get(); +} + +void LLThread::setTraceData( LLTrace::ThreadTrace* data ) +{ + sTraceData = data; +} diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 5cd287ec39..334ea2f0da 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -30,8 +30,12 @@ #include "llapp.h" #include "llapr.h" #include "apr_thread_cond.h" -#include "lltrace.h" +#include "llmutex.h" +namespace LLTrace +{ + class ThreadTrace; +} class LL_COMMON_API LLThread { private: @@ -87,8 +91,8 @@ public: U32 getID() const { return mID; } - static LLTrace::ThreadTrace* getTraceData() { return sTraceData.get(); } - static void setTraceData(LLTrace::ThreadTrace* data) { sTraceData = data;} + static LLTrace::ThreadTrace* getTraceData(); + static void setTraceData(LLTrace::ThreadTrace* data); private: BOOL mPaused; diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 24a2b33a5f..2da4363b1d 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -55,40 +55,97 @@ MasterThreadTrace& getMasterThreadTrace() return *gMasterThreadTrace; } - - /////////////////////////////////////////////////////////////////////// // Sampler /////////////////////////////////////////////////////////////////////// +Sampler::Sampler(ThreadTrace* thread_trace) +: mElapsedSeconds(0), + mIsStarted(false), + mThreadTrace(thread_trace) +{ +} -void Sampler::stop() +Sampler::~Sampler() { - getThreadTrace()->deactivate(this); +} + +void Sampler::start() +{ + reset(); + resume(); +} + +void Sampler::reset() +{ + mF32Stats.reset(); + mS32Stats.reset(); + mStackTimers.reset(); + + mElapsedSeconds = 0.0; + mSamplingTimer.reset(); } void Sampler::resume() { - getThreadTrace()->activate(this); + if (!mIsStarted) + { + mSamplingTimer.reset(); + getThreadTrace()->activate(this); + mIsStarted = true; + } +} + +void Sampler::stop() +{ + if (mIsStarted) + { + mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); + getThreadTrace()->deactivate(this); + mIsStarted = false; + } +} + +ThreadTrace* Sampler::getThreadTrace() +{ + return mThreadTrace; +} + +void Sampler::makePrimary() +{ + mF32Stats.makePrimary(); + mS32Stats.makePrimary(); + mStackTimers.makePrimary(); } -class ThreadTrace* Sampler::getThreadTrace() +void Sampler::mergeFrom( const Sampler* other ) { - return LLThread::getTraceData(); + mF32Stats.mergeFrom(other->mF32Stats); + mS32Stats.mergeFrom(other->mS32Stats); + mStackTimers.mergeFrom(other->mStackTimers); } + /////////////////////////////////////////////////////////////////////// // MasterThreadTrace /////////////////////////////////////////////////////////////////////// ThreadTrace::ThreadTrace() { - mPrimarySampler.makePrimary(); + mPrimarySampler = createSampler(); + mPrimarySampler->makePrimary(); + mPrimarySampler->start(); } -ThreadTrace::ThreadTrace( const ThreadTrace& other ) : mPrimarySampler(other.mPrimarySampler) +ThreadTrace::ThreadTrace( const ThreadTrace& other ) +: mPrimarySampler(new Sampler(*(other.mPrimarySampler))) { - mPrimarySampler.makePrimary(); + mPrimarySampler->makePrimary(); +} + +ThreadTrace::~ThreadTrace() +{ + delete mPrimarySampler; } void ThreadTrace::activate( Sampler* sampler ) @@ -117,11 +174,13 @@ void ThreadTrace::flushPrimary() { (*it)->mergeFrom(mPrimarySampler); } - mPrimarySampler.reset(); + mPrimarySampler->reset(); } - - +Sampler* ThreadTrace::createSampler() +{ + return new Sampler(this); +} @@ -129,12 +188,23 @@ void ThreadTrace::flushPrimary() // SlaveThreadTrace /////////////////////////////////////////////////////////////////////// +SlaveThreadTrace::SlaveThreadTrace() +: ThreadTrace(getMasterThreadTrace()), + mSharedData(createSampler()) +{ + getMasterThreadTrace().addSlaveThread(this); +} + +SlaveThreadTrace::~SlaveThreadTrace() +{ + getMasterThreadTrace().removeSlaveThread(this); +} + void SlaveThreadTrace::pushToMaster() { mSharedData.copyFrom(mPrimarySampler); } - /////////////////////////////////////////////////////////////////////// // MasterThreadTrace /////////////////////////////////////////////////////////////////////// @@ -155,7 +225,7 @@ void MasterThreadTrace::addSlaveThread( class SlaveThreadTrace* child ) { LLMutexLock lock(&mSlaveListMutex); - mSlaveThreadTraces.push_back(SlaveThreadTraceProxy(child)); + mSlaveThreadTraces.push_back(SlaveThreadTraceProxy(child, createSampler())); } void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child ) @@ -175,15 +245,26 @@ void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child ) } void MasterThreadTrace::pushToMaster() -{ - -} +{} MasterThreadTrace::MasterThreadTrace() { LLThread::setTraceData(this); } +/////////////////////////////////////////////////////////////////////// +// MasterThreadTrace::SlaveThreadTraceProxy +/////////////////////////////////////////////////////////////////////// + +MasterThreadTrace::SlaveThreadTraceProxy::SlaveThreadTraceProxy( class SlaveThreadTrace* trace, Sampler* storage ) +: mSlaveTrace(trace), + mSamplerStorage(storage) +{} +MasterThreadTrace::SlaveThreadTraceProxy::~SlaveThreadTraceProxy() +{ + delete mSamplerStorage; } + +} diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 601b5ed182..a443735e69 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -32,6 +32,7 @@ #include "llmutex.h" #include "llmemory.h" +#include "lltimer.h" #include @@ -39,6 +40,7 @@ #define TOKEN_PASTE(x, y) TOKEN_PASTE_ACTUAL(x, y) #define RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer); + namespace LLTrace { void init(); @@ -135,7 +137,7 @@ namespace LLTrace static AccumulatorBuffer& getDefaultBuffer() { - static AccumulatorBuffer sBuffer; + static AccumulatorBuffer sBuffer(STATIC_ALLOC); return sBuffer; } @@ -354,54 +356,38 @@ namespace LLTrace class Sampler { public: - Sampler() {} - Sampler(const Sampler& other) - : mF32Stats(other.mF32Stats), - mS32Stats(other.mS32Stats), - mTimers(other.mTimers) - {} - - ~Sampler() - {} + ~Sampler(); - void makePrimary() - { - mF32Stats.makePrimary(); - mS32Stats.makePrimary(); - mTimers.makePrimary(); - } - - void start() - { - reset(); - resume(); - } + void makePrimary(); + void start(); void stop(); void resume(); - void mergeFrom(const Sampler& other) - { - mF32Stats.mergeFrom(other.mF32Stats); - mS32Stats.mergeFrom(other.mS32Stats); - mTimers.mergeFrom(other.mTimers); - } + void mergeFrom(const Sampler* other); - void reset() - { - mF32Stats.reset(); - mS32Stats.reset(); - mTimers.reset(); - } + void reset(); + + bool isStarted() { return mIsStarted; } private: + friend class ThreadTrace; + Sampler(class ThreadTrace* thread_trace); + + // no copy + Sampler(const Sampler& other) {} // returns data for current thread class ThreadTrace* getThreadTrace(); AccumulatorBuffer > mF32Stats; AccumulatorBuffer > mS32Stats; - AccumulatorBuffer mTimers; + AccumulatorBuffer mStackTimers; + + bool mIsStarted; + LLTimer mSamplingTimer; + F64 mElapsedSeconds; + ThreadTrace* mThreadTrace; }; class ThreadTrace @@ -410,17 +396,19 @@ namespace LLTrace ThreadTrace(); ThreadTrace(const ThreadTrace& other); - virtual ~ThreadTrace() {} + virtual ~ThreadTrace(); void activate(Sampler* sampler); void deactivate(Sampler* sampler); void flushPrimary(); + Sampler* createSampler(); + virtual void pushToMaster() = 0; - Sampler* getPrimarySampler() { return &mPrimarySampler; } + Sampler* getPrimarySampler() { return mPrimarySampler; } protected: - Sampler mPrimarySampler; + Sampler* mPrimarySampler; std::list mActiveSamplers; }; @@ -440,11 +428,11 @@ namespace LLTrace private: struct SlaveThreadTraceProxy { - SlaveThreadTraceProxy(class SlaveThreadTrace* trace) - : mSlaveTrace(trace) - {} + SlaveThreadTraceProxy(class SlaveThreadTrace* trace, Sampler* storage); + + ~SlaveThreadTraceProxy(); class SlaveThreadTrace* mSlaveTrace; - Sampler mSamplerStorage; + Sampler* mSamplerStorage; }; typedef std::list slave_thread_trace_list_t; @@ -455,18 +443,8 @@ namespace LLTrace class SlaveThreadTrace : public ThreadTrace { public: - explicit - SlaveThreadTrace() - : ThreadTrace(getMasterThreadTrace()), - mSharedData(mPrimarySampler) - { - getMasterThreadTrace().addSlaveThread(this); - } - - ~SlaveThreadTrace() - { - getMasterThreadTrace().removeSlaveThread(this); - } + SlaveThreadTrace(); + ~SlaveThreadTrace(); // call this periodically to gather stats data for master thread to consume /*virtual*/ void pushToMaster(); @@ -479,29 +457,35 @@ namespace LLTrace { public: explicit - SharedData(const Sampler& other_sampler) - : mSampler(other_sampler) - {} + SharedData(Sampler* sampler) + : mSampler(sampler) + { + } + + ~SharedData() + { + delete mSampler; + } - void copyFrom(Sampler& source) + void copyFrom(Sampler* source) { LLMutexLock lock(&mSamplerMutex); { - mSampler.mergeFrom(source); + mSampler->mergeFrom(source); } } - void copyTo(Sampler& sink) + void copyTo(Sampler* sink) { LLMutexLock lock(&mSamplerMutex); { - sink.mergeFrom(mSampler); + sink->mergeFrom(mSampler); } } private: // add a cache line's worth of unused space to avoid any potential of false sharing LLMutex mSamplerMutex; - Sampler mSampler; + Sampler* mSampler; }; SharedData mSharedData; }; diff --git a/indra/llimage/tests/llimageworker_test.cpp b/indra/llimage/tests/llimageworker_test.cpp index be7aae4eb7..29497257ac 100644 --- a/indra/llimage/tests/llimageworker_test.cpp +++ b/indra/llimage/tests/llimageworker_test.cpp @@ -31,6 +31,8 @@ #include "../llimageworker.h" // For timer class #include "../llcommon/lltimer.h" +// for lltrace class +#include "../llcommon/lltrace.h" // Tut header #include "../test/lltut.h" diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fcbef491fe..0bb87dfa6c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -60,7 +60,7 @@ #include "llcurl.h" #include "llcalc.h" #include "lltexturestats.h" -#include "lltexturestats.h" +#include "lltrace.h" #include "llviewerwindow.h" #include "llviewerdisplay.h" #include "llviewermedia.h" -- cgit v1.3 From 14b1b0b2bb6bac5bc688cc4d14c33f1b680dd3b4 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Mon, 1 Oct 2012 19:39:04 -0700 Subject: SH-3275 WIP Run viewer metrics for object update messages cleaned up API samplers are now value types with copy-on-write buffers under the hood removed coupling with LLThread --- indra/llcommon/llapr.cpp | 28 +++--- indra/llcommon/llapr.h | 28 +++--- indra/llcommon/llpointer.h | 83 ++++++++++++---- indra/llcommon/llqueuedthread.cpp | 2 +- indra/llcommon/llthread.cpp | 15 +-- indra/llcommon/llthread.h | 9 -- indra/llcommon/lltrace.cpp | 108 +++++++++----------- indra/llcommon/lltrace.h | 180 +++++++++++++++++++++++++++------- indra/llcommon/lltracesampler.cpp | 98 ++++++++++++++---- indra/llcommon/lltracesampler.h | 59 ++++++----- indra/llui/llstatbar.cpp | 36 ++----- indra/llui/llstatbar.h | 4 +- indra/llui/llstatgraph.cpp | 17 +--- indra/llui/llstatgraph.h | 7 +- indra/newview/llstatusbar.cpp | 2 +- indra/newview/llviewerstats.cpp | 13 ++- indra/newview/llviewerstats.h | 2 +- indra/newview/llviewertexturelist.cpp | 2 +- indra/newview/llworld.cpp | 2 +- 19 files changed, 424 insertions(+), 271 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index e9930c10f7..d23b70690d 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -55,7 +55,7 @@ void ll_init_apr() LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE); } - LLThreadLocalPtrBase::initAllThreadLocalStorage(); + LLThreadLocalPointerBase::initAllThreadLocalStorage(); } @@ -80,7 +80,7 @@ void ll_cleanup_apr() gCallStacksLogMutexp = NULL; } - LLThreadLocalPtrBase::destroyAllThreadLocalStorage(); + LLThreadLocalPointerBase::destroyAllThreadLocalStorage(); if (gAPRPoolp) { @@ -482,11 +482,11 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset) } // -//LLThreadLocalPtrBase +//LLThreadLocalPointerBase // -bool LLThreadLocalPtrBase::sInitialized = false; +bool LLThreadLocalPointerBase::sInitialized = false; -LLThreadLocalPtrBase::LLThreadLocalPtrBase() +LLThreadLocalPointerBase::LLThreadLocalPointerBase() : mThreadKey(NULL) { if (sInitialized) @@ -495,7 +495,7 @@ LLThreadLocalPtrBase::LLThreadLocalPtrBase() } } -LLThreadLocalPtrBase::LLThreadLocalPtrBase( const LLThreadLocalPtrBase& other) +LLThreadLocalPointerBase::LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other) : mThreadKey(NULL) { if (sInitialized) @@ -504,12 +504,12 @@ LLThreadLocalPtrBase::LLThreadLocalPtrBase( const LLThreadLocalPtrBase& other) } } -LLThreadLocalPtrBase::~LLThreadLocalPtrBase() +LLThreadLocalPointerBase::~LLThreadLocalPointerBase() { destroyStorage(); } -void LLThreadLocalPtrBase::set( void* value ) +void LLThreadLocalPointerBase::set( void* value ) { llassert(sInitialized && mThreadKey); @@ -521,7 +521,7 @@ void LLThreadLocalPtrBase::set( void* value ) } } -void LLThreadLocalPtrBase::initStorage( ) +void LLThreadLocalPointerBase::initStorage( ) { apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp); if (result != APR_SUCCESS) @@ -531,7 +531,7 @@ void LLThreadLocalPtrBase::initStorage( ) } } -void LLThreadLocalPtrBase::destroyStorage() +void LLThreadLocalPointerBase::destroyStorage() { if (sInitialized) { @@ -547,11 +547,11 @@ void LLThreadLocalPtrBase::destroyStorage() } } -void LLThreadLocalPtrBase::initAllThreadLocalStorage() +void LLThreadLocalPointerBase::initAllThreadLocalStorage() { if (!sInitialized) { - for (LLInstanceTracker::instance_iter it = beginInstances(), end_it = endInstances(); + for (LLInstanceTracker::instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it) { @@ -561,11 +561,11 @@ void LLThreadLocalPtrBase::initAllThreadLocalStorage() } } -void LLThreadLocalPtrBase::destroyAllThreadLocalStorage() +void LLThreadLocalPointerBase::destroyAllThreadLocalStorage() { if (sInitialized) { - for (LLInstanceTracker::instance_iter it = beginInstances(), end_it = endInstances(); + for (LLInstanceTracker::instance_iter it = beginInstances(), end_it = endInstances(); it != end_it; ++it) { diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 4e704998c2..6efb44a663 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -258,12 +258,12 @@ public: //******************************************************************************************************************************* }; -class LLThreadLocalPtrBase : LLInstanceTracker +class LLThreadLocalPointerBase : LLInstanceTracker { public: - LLThreadLocalPtrBase(); - LLThreadLocalPtrBase(const LLThreadLocalPtrBase& other); - ~LLThreadLocalPtrBase(); + LLThreadLocalPointerBase(); + LLThreadLocalPointerBase(const LLThreadLocalPointerBase& other); + ~LLThreadLocalPointerBase(); static void initAllThreadLocalStorage(); static void destroyAllThreadLocalStorage(); @@ -307,35 +307,35 @@ protected: }; template -class LLThreadLocalPtr : public LLThreadLocalPtrBase +class LLThreadLocalPointer : public LLThreadLocalPointerBase { public: - LLThreadLocalPtr() - : LLThreadLocalPtrBase() + LLThreadLocalPointer() + : LLThreadLocalPointerBase() {} - explicit LLThreadLocalPtr(T* value) - : LLThreadLocalPtrBase(&cleanup) + explicit LLThreadLocalPointer(T* value) + : LLThreadLocalPointerBase(&cleanup) { set(value); } - LLThreadLocalPtr(const LLThreadLocalPtr& other) - : LLThreadLocalPtrBase(other, &cleanup) + LLThreadLocalPointer(const LLThreadLocalPointer& other) + : LLThreadLocalPointerBase(other, &cleanup) { set(other.get()); } LL_FORCE_INLINE T* get() { - return (T*)LLThreadLocalPtrBase::get(); + return (T*)LLThreadLocalPointerBase::get(); } const T* get() const { - return (const T*)LLThreadLocalPtrBase::get(); + return (const T*)LLThreadLocalPointerBase::get(); } T* operator -> () @@ -358,7 +358,7 @@ public: return *(T*)get(); } - LLThreadLocalPtr& operator = (T* value) + LLThreadLocalPointer& operator = (T* value) { set((void*)value); return *this; diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h index 88c09c8dca..0fee4f0990 100644 --- a/indra/llcommon/llpointer.h +++ b/indra/llcommon/llpointer.h @@ -97,24 +97,13 @@ public: LLPointer& operator =(Type* ptr) { - if( mPointer != ptr ) - { - unref(); - mPointer = ptr; - ref(); - } - + assign(ptr); return *this; } LLPointer& operator =(const LLPointer& ptr) { - if( mPointer != ptr.mPointer ) - { - unref(); - mPointer = ptr.mPointer; - ref(); - } + assign(ptr); return *this; } @@ -122,12 +111,7 @@ public: template LLPointer& operator =(const LLPointer& ptr) { - if( mPointer != ptr.get() ) - { - unref(); - mPointer = ptr.get(); - ref(); - } + assign(ptr.get()); return *this; } @@ -144,6 +128,16 @@ protected: void ref(); void unref(); #else + + void assign(const LLPointer& ptr) + { + if( mPointer != ptr.mPointer ) + { + unref(); + mPointer = ptr.mPointer; + ref(); + } + } void ref() { if (mPointer) @@ -156,9 +150,9 @@ protected: { if (mPointer) { - Type *tempp = mPointer; + Type *temp = mPointer; mPointer = NULL; - tempp->unref(); + temp->unref(); if (mPointer != NULL) { llwarns << "Unreference did assignment to non-NULL because of destructor" << llendl; @@ -171,4 +165,51 @@ protected: Type* mPointer; }; +template +class LLCopyOnWritePointer : public LLPointer +{ +public: + typedef LLPointer ref_pointer_t; + typedef LLCopyOnWritePointer self_t; + + LLCopyOnWritePointer() + { + } + + LLCopyOnWritePointer(Type* ptr) + : LLPointer(ptr) + { + } + + Type* write() + { + makeUnique(); + return mPointer; + } + + void makeUnique() + { + if (mPointer && mPointer->getNumRefs() > 1) + { + ref_pointer_t::assign(new Type(*mPointer)); + } + } + + using ref_pointer_t::operator BOOL; + using ref_pointer_t::operator bool; + using ref_pointer_t::operator!; + + using ref_pointer_t::operator !=; + using ref_pointer_t::operator ==; + using LLPointer::operator =; + + using LLPointer::operator <; + using LLPointer::operator >; + + + operator const Type*() const { return mPointer; } + const Type* operator->() const { return mPointer; } + +}; + #endif diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 0a35474b7f..9aa449d037 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -112,7 +112,7 @@ void LLQueuedThread::shutdown() // virtual S32 LLQueuedThread::update(F32 max_time_ms) { - LLThread::getTraceData()->pushToMaster(); + LLTrace::get_thread_trace()->pushToMaster(); if (!mStarted) { diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 7384842627..c705e5103b 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -67,7 +67,6 @@ U32 __thread LLThread::sThreadID = 0; #endif U32 LLThread::sIDIter = 0; -LLThreadLocalPtr LLThread::sTraceData; LL_COMMON_API void assert_main_thread() @@ -86,7 +85,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap { LLThread *threadp = (LLThread *)datap; - setTraceData(new LLTrace::SlaveThreadTrace()); + LLTrace::ThreadTrace* thread_trace = new LLTrace::SlaveThreadTrace(); #if !LL_DARWIN sThreadIndex = threadp->mID; @@ -100,8 +99,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap // We're done with the run function, this thread is done executing now. threadp->mStatus = STOPPED; - delete sTraceData.get(); - sTraceData = NULL; + delete thread_trace; return NULL; } @@ -314,12 +312,3 @@ void LLThread::wakeLocked() } } -LLTrace::ThreadTrace* LLThread::getTraceData() -{ - return sTraceData.get(); -} - -void LLThread::setTraceData( LLTrace::ThreadTrace* data ) -{ - sTraceData = data; -} diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 334ea2f0da..82ab5f47d2 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -32,10 +32,6 @@ #include "apr_thread_cond.h" #include "llmutex.h" -namespace LLTrace -{ - class ThreadTrace; -} class LL_COMMON_API LLThread { private: @@ -91,9 +87,6 @@ public: U32 getID() const { return mID; } - static LLTrace::ThreadTrace* getTraceData(); - static void setTraceData(LLTrace::ThreadTrace* data); - private: BOOL mPaused; @@ -110,8 +103,6 @@ protected: EThreadStatus mStatus; U32 mID; - static LLThreadLocalPtr sTraceData; - //a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used. //Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes. // otherwise it will cause severe memory leaking!!! --bao diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index e487e450a9..04817fd4f4 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -27,7 +27,6 @@ #include "lltrace.h" #include "lltracesampler.h" -#include "llthread.h" namespace LLTrace { @@ -45,6 +44,12 @@ void cleanup() gMasterThreadTrace = NULL; } +LLThreadLocalPointer& get_thread_trace() +{ + static LLThreadLocalPointer s_trace_data; + return s_trace_data; + +} BlockTimer::Recorder::StackEntry BlockTimer::sCurRecorder; @@ -62,36 +67,52 @@ MasterThreadTrace& getMasterThreadTrace() ThreadTrace::ThreadTrace() { - mPrimarySampler = createSampler(); - mPrimarySampler->makePrimary(); - mPrimarySampler->start(); + get_thread_trace() = this; + mPrimarySampler.makePrimary(); + mTotalSampler.start(); } ThreadTrace::ThreadTrace( const ThreadTrace& other ) -: mPrimarySampler(new Sampler(*(other.mPrimarySampler))) +: mPrimarySampler(other.mPrimarySampler), + mTotalSampler(other.mTotalSampler) { - mPrimarySampler->makePrimary(); + get_thread_trace() = this; + mPrimarySampler.makePrimary(); + mTotalSampler.start(); } ThreadTrace::~ThreadTrace() { - delete mPrimarySampler; + get_thread_trace() = NULL; } +//TODO: remove this and use llviewerstats sampler Sampler* ThreadTrace::getPrimarySampler() { - return mPrimarySampler; + return &mPrimarySampler; } void ThreadTrace::activate( Sampler* sampler ) { - flushPrimary(); - mActiveSamplers.push_back(sampler); + for (std::list::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end(); + it != end_it; + ++it) + { + (*it)->mMeasurements.write()->mergeSamples(*mPrimarySampler.mMeasurements); + } + mPrimarySampler.mMeasurements.write()->reset(); + + sampler->initDeltas(mPrimarySampler); + + mActiveSamplers.push_front(sampler); } +//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 ThreadTrace::deactivate( Sampler* sampler ) { - sampler->mergeFrom(mPrimarySampler); + sampler->mergeDeltas(mPrimarySampler); // TODO: replace with intrusive list std::list::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler); @@ -101,31 +122,12 @@ void ThreadTrace::deactivate( Sampler* sampler ) } } -void ThreadTrace::flushPrimary() -{ - for (std::list::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end(); - it != end_it; - ++it) - { - (*it)->mergeFrom(mPrimarySampler); - } - mPrimarySampler->reset(); -} - -Sampler* ThreadTrace::createSampler() -{ - return new Sampler(this); -} - - - /////////////////////////////////////////////////////////////////////// // SlaveThreadTrace /////////////////////////////////////////////////////////////////////// SlaveThreadTrace::SlaveThreadTrace() -: ThreadTrace(getMasterThreadTrace()), - mSharedData(createSampler()) +: ThreadTrace(getMasterThreadTrace()) { getMasterThreadTrace().addSlaveThread(this); } @@ -137,34 +139,26 @@ SlaveThreadTrace::~SlaveThreadTrace() void SlaveThreadTrace::pushToMaster() { - mSharedData.copyFrom(mPrimarySampler); -} - -void SlaveThreadTrace::SharedData::copyFrom( Sampler* source ) -{ - LLMutexLock lock(&mSamplerMutex); - { - mSampler->mergeFrom(source); + mTotalSampler.stop(); + { + LLMutexLock(getMasterThreadTrace().getSlaveListMutex()); + mSharedData.copyFrom(mTotalSampler); } + mTotalSampler.start(); } -void SlaveThreadTrace::SharedData::copyTo( Sampler* sink ) +void SlaveThreadTrace::SharedData::copyFrom( const Sampler& source ) { LLMutexLock lock(&mSamplerMutex); - { - sink->mergeFrom(mSampler); - } + mSampler.mergeSamples(source); } -SlaveThreadTrace::SharedData::~SharedData() +void SlaveThreadTrace::SharedData::copyTo( Sampler& sink ) { - delete mSampler; + LLMutexLock lock(&mSamplerMutex); + sink.mergeSamples(mSampler); } -SlaveThreadTrace::SharedData::SharedData( Sampler* sampler ) : mSampler(sampler) -{} - - @@ -188,7 +182,7 @@ void MasterThreadTrace::addSlaveThread( class SlaveThreadTrace* child ) { LLMutexLock lock(&mSlaveListMutex); - mSlaveThreadTraces.push_back(new SlaveThreadTraceProxy(child, createSampler())); + mSlaveThreadTraces.push_back(new SlaveThreadTraceProxy(child)); } void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child ) @@ -211,22 +205,14 @@ void MasterThreadTrace::pushToMaster() {} MasterThreadTrace::MasterThreadTrace() -{ - LLThread::setTraceData(this); -} +{} /////////////////////////////////////////////////////////////////////// // MasterThreadTrace::SlaveThreadTraceProxy /////////////////////////////////////////////////////////////////////// -MasterThreadTrace::SlaveThreadTraceProxy::SlaveThreadTraceProxy( class SlaveThreadTrace* trace, Sampler* storage ) -: mSlaveTrace(trace), - mSamplerStorage(storage) +MasterThreadTrace::SlaveThreadTraceProxy::SlaveThreadTraceProxy( class SlaveThreadTrace* trace) +: mSlaveTrace(trace) {} -MasterThreadTrace::SlaveThreadTraceProxy::~SlaveThreadTraceProxy() -{ - delete mSamplerStorage; -} - } diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index c6f920b5e4..5ec1c821c3 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -33,6 +33,8 @@ #include "llmutex.h" #include "llmemory.h" #include "lltimer.h" +#include "llrefcount.h" +#include "lltracesampler.h" #include @@ -48,11 +50,13 @@ namespace LLTrace void init(); void cleanup(); + LLThreadLocalPointer& get_thread_trace(); + class LL_COMMON_API MasterThreadTrace& getMasterThreadTrace(); // one per thread per type template - class LL_COMMON_API AccumulatorBuffer + class LL_COMMON_API AccumulatorBuffer : public LLRefCount { static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; private: @@ -88,13 +92,23 @@ namespace LLTrace return mStorage[index]; } - void mergeFrom(const AccumulatorBuffer& other) + void mergeSamples(const AccumulatorBuffer& other) { llassert(mNextStorageSlot == other.mNextStorageSlot); for (size_t i = 0; i < mNextStorageSlot; i++) { - mStorage[i].mergeFrom(other.mStorage[i]); + mStorage[i].mergeSamples(other.mStorage[i]); + } + } + + void mergeDeltas(const AccumulatorBuffer& start, const AccumulatorBuffer& finish) + { + llassert(mNextStorageSlot == start.mNextStorageSlot && mNextStorageSlot == finish.mNextStorageSlot); + + for (size_t i = 0; i < mNextStorageSlot; i++) + { + mStorage[i].mergeDeltas(start.mStorage[i], finish.mStorage[i]); } } @@ -119,6 +133,11 @@ namespace LLTrace sPrimaryStorage = mStorage; } + bool isPrimary() const + { + return sPrimaryStorage == mStorage; + } + LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage() { return sPrimaryStorage.get(); @@ -149,9 +168,9 @@ namespace LLTrace ACCUMULATOR* mStorage; size_t mStorageSize; size_t mNextStorageSlot; - static LLThreadLocalPtr sPrimaryStorage; + static LLThreadLocalPointer sPrimaryStorage; }; - template LLThreadLocalPtr AccumulatorBuffer::sPrimaryStorage; + template LLThreadLocalPointer AccumulatorBuffer::sPrimaryStorage; template class LL_COMMON_API TraceType @@ -168,7 +187,7 @@ namespace LLTrace return AccumulatorBuffer::getPrimaryStorage()[mAccumulatorIndex]; } - ACCUMULATOR& getAccumulator(AccumulatorBuffer& buffer) { return buffer[mAccumulatorIndex]; } + ACCUMULATOR& getAccumulator(AccumulatorBuffer* buffer) { return (*buffer)[mAccumulatorIndex]; } protected: std::string mName; @@ -177,10 +196,10 @@ namespace LLTrace template - class LL_COMMON_API StatAccumulator + class LL_COMMON_API MeasurementAccumulator { public: - StatAccumulator() + MeasurementAccumulator() : mSum(0), mMin(0), mMax(0), @@ -199,9 +218,12 @@ namespace LLTrace { mMax = value; } + F32 old_mean = mMean; + mMean += ((F32)value - old_mean) / (F32)mNumSamples; + mStandardDeviation += ((F32)value - old_mean) * ((F32)value - mMean); } - void mergeFrom(const StatAccumulator& other) + void mergeSamples(const MeasurementAccumulator& other) { mSum += other.mSum; if (other.mMin < mMin) @@ -213,6 +235,28 @@ namespace LLTrace mMax = other.mMax; } mNumSamples += other.mNumSamples; + F32 weight = (F32)mNumSamples / (F32)(mNumSamples + other.mNumSamples); + mMean = mMean * weight + other.mMean * (1.f - weight); + + F32 n_1 = (F32)mNumSamples, + n_2 = (F32)other.mNumSamples; + F32 m_1 = mMean, + m_2 = other.mMean; + F32 sd_1 = mStandardDeviation, + sd_2 = other.mStandardDeviation; + // combine variance (and hence standard deviation) of 2 different sized sample groups using + // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm + F32 variance = ((((n_1 - 1.f) * sd_1 * sd_1) + + ((n_2 - 1.f) * sd_2 * sd_2) + + (((n_1 * n_2) / (n_1 + n_2)) + * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) + / (n_1 + n_2 - 1.f)); + mStandardDeviation = sqrtf(variance); + } + + void mergeDeltas(const MeasurementAccumulator& start, const MeasurementAccumulator& finish) + { + llerrs << "Delta merge invalid for measurement accumulators" << llendl; } void reset() @@ -226,23 +270,68 @@ namespace LLTrace T getSum() { return mSum; } T getMin() { return mMin; } T getMax() { return mMax; } - T getMean() { return mSum / (T)mNumSamples; } + F32 getMean() { return mMean; } + F32 getStandardDeviation() { return mStandardDeviation; } private: T mSum, mMin, mMax; + F32 mMean, + mStandardDeviation; + + U32 mNumSamples; + }; + + template + class LL_COMMON_API RateAccumulator + { + public: + RateAccumulator() + : mSum(0), + mNumSamples(0) + {} + + LL_FORCE_INLINE void add(T value) + { + mNumSamples++; + mSum += value; + } + + void mergeSamples(const RateAccumulator& other) + { + mSum += other.mSum; + mNumSamples += other.mNumSamples; + } + + void mergeDeltas(const RateAccumulator& start, const RateAccumulator& finish) + { + mSum += finish.mSum - start.mSum; + mNumSamples += finish.mNumSamples - start.mNumSamples; + } + + void reset() + { + mNumSamples = 0; + mSum = 0; + } + + T getSum() { return mSum; } + + private: + T mSum; + U32 mNumSamples; }; template - class LL_COMMON_API Stat - : public TraceType >, - public LLInstanceTracker, std::string> + class LL_COMMON_API Measurement + : public TraceType >, + public LLInstanceTracker, std::string> { public: - Stat(const std::string& name) + Measurement(const std::string& name) : TraceType(name), LLInstanceTracker(name) {} @@ -253,11 +342,30 @@ namespace LLTrace } }; - struct LL_COMMON_API TimerAccumulator + template + class LL_COMMON_API Rate + : public TraceType >, + public LLInstanceTracker, std::string> { + public: + Rate(const std::string& name) + : TraceType(name), + LLInstanceTracker(name) + {} + + void add(T value) + { + getPrimaryAccumulator().add(value); + } + }; + + class LL_COMMON_API TimerAccumulator + { + public: U32 mTotalTimeCounter, mChildTimeCounter, mCalls; + TimerAccumulator* mParent; // info for caller timer TimerAccumulator* mLastCaller; // used to bootstrap tree construction const class BlockTimer* mTimer; // points to block timer associated with this storage @@ -265,13 +373,20 @@ namespace LLTrace bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame std::vector mChildren; // currently assumed child timers - void mergeFrom(const TimerAccumulator& other) + void mergeSamples(const TimerAccumulator& other) { mTotalTimeCounter += other.mTotalTimeCounter; mChildTimeCounter += other.mChildTimeCounter; mCalls += other.mCalls; } + void mergeDeltas(const TimerAccumulator& start, const TimerAccumulator& finish) + { + mTotalTimeCounter += finish.mTotalTimeCounter - start.mTotalTimeCounter; + mChildTimeCounter += finish.mChildTimeCounter - start.mChildTimeCounter; + mCalls += finish.mCalls - start.mCalls; + } + void reset() { mTotalTimeCounter = 0; @@ -377,15 +492,13 @@ namespace LLTrace void activate(Sampler* sampler); void deactivate(Sampler* sampler); - void flushPrimary(); - - Sampler* createSampler(); virtual void pushToMaster() = 0; Sampler* getPrimarySampler(); protected: - Sampler* mPrimarySampler; + Sampler mPrimarySampler; + Sampler mTotalSampler; std::list mActiveSamplers; }; @@ -402,14 +515,15 @@ namespace LLTrace // call this periodically to gather stats data from slave threads void pullFromSlaveThreads(); + LLMutex* getSlaveListMutex() { return &mSlaveListMutex; } + private: struct SlaveThreadTraceProxy { - SlaveThreadTraceProxy(class SlaveThreadTrace* trace, Sampler* storage); + SlaveThreadTraceProxy(class SlaveThreadTrace* trace); - ~SlaveThreadTraceProxy(); class SlaveThreadTrace* mSlaveTrace; - Sampler* mSamplerStorage; + Sampler mSamplerStorage; private: //no need to copy these and then have to duplicate the storage SlaveThreadTraceProxy(const SlaveThreadTraceProxy& other) {} @@ -431,24 +545,16 @@ namespace LLTrace MasterThreadTrace* mMaster; - // this data is accessed by other threads, so give it a 64 byte alignment - // to avoid false sharing on most x86 processors - LL_ALIGNED(64) class SharedData + class SharedData { public: - explicit - SharedData(Sampler* sampler); - - ~SharedData(); - - void copyFrom(Sampler* source); - void copyTo(Sampler* sink); + void copyFrom(const Sampler& source); + void copyTo(Sampler& sink); private: - // add a cache line's worth of unused space to avoid any potential of false sharing - LLMutex mSamplerMutex; - Sampler* mSampler; + LLMutex mSamplerMutex; + Sampler mSampler; }; - SharedData mSharedData; + SharedData mSharedData; }; } diff --git a/indra/llcommon/lltracesampler.cpp b/indra/llcommon/lltracesampler.cpp index 0cf01d7a3a..17e58b96e2 100644 --- a/indra/llcommon/lltracesampler.cpp +++ b/indra/llcommon/lltracesampler.cpp @@ -26,6 +26,8 @@ #include "linden_common.h" #include "lltracesampler.h" +#include "lltrace.h" +#include "llthread.h" namespace LLTrace { @@ -34,10 +36,14 @@ namespace LLTrace // Sampler /////////////////////////////////////////////////////////////////////// -Sampler::Sampler(ThreadTrace* thread_trace) +Sampler::Sampler() : mElapsedSeconds(0), mIsStarted(false), - mThreadTrace(thread_trace) + mRatesStart(new AccumulatorBuffer >()), + mRates(new AccumulatorBuffer >()), + mMeasurements(new AccumulatorBuffer >()), + mStackTimers(new AccumulatorBuffer()), + mStackTimersStart(new AccumulatorBuffer()) { } @@ -53,9 +59,9 @@ void Sampler::start() void Sampler::reset() { - mF32Stats.reset(); - mS32Stats.reset(); - mStackTimers.reset(); + mRates.write()->reset(); + mMeasurements.write()->reset(); + mStackTimers.write()->reset(); mElapsedSeconds = 0.0; mSamplingTimer.reset(); @@ -66,7 +72,7 @@ void Sampler::resume() if (!mIsStarted) { mSamplingTimer.reset(); - getThreadTrace()->activate(this); + LLTrace::get_thread_trace()->activate(this); mIsStarted = true; } } @@ -76,28 +82,86 @@ void Sampler::stop() if (mIsStarted) { mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); - getThreadTrace()->deactivate(this); + LLTrace::get_thread_trace()->deactivate(this); mIsStarted = false; } } -ThreadTrace* Sampler::getThreadTrace() + +void Sampler::makePrimary() { - return mThreadTrace; + mRates.write()->makePrimary(); + mMeasurements.write()->makePrimary(); + mStackTimers.write()->makePrimary(); } -void Sampler::makePrimary() +bool Sampler::isPrimary() +{ + return mRates->isPrimary(); +} + +void Sampler::mergeSamples( const Sampler& other ) +{ + mRates.write()->mergeSamples(*other.mRates); + mMeasurements.write()->mergeSamples(*other.mMeasurements); + mStackTimers.write()->mergeSamples(*other.mStackTimers); +} + +void Sampler::initDeltas( const Sampler& other ) +{ + mRatesStart.write()->copyFrom(*other.mRates); + mStackTimersStart.write()->copyFrom(*other.mStackTimers); +} + + +void Sampler::mergeDeltas( const Sampler& other ) +{ + mRates.write()->mergeDeltas(*mRatesStart, *other.mRates); + mStackTimers.write()->mergeDeltas(*mStackTimersStart, *other.mStackTimers); + mMeasurements.write()->mergeSamples(*other.mMeasurements); +} + + +F32 Sampler::getSum( Rate& stat ) { - mF32Stats.makePrimary(); - mS32Stats.makePrimary(); - mStackTimers.makePrimary(); + return stat.getAccumulator(mRates).getSum(); } -void Sampler::mergeFrom( const Sampler* other ) +F32 Sampler::getSum( Measurement& stat ) { - mF32Stats.mergeFrom(other->mF32Stats); - mS32Stats.mergeFrom(other->mS32Stats); - mStackTimers.mergeFrom(other->mStackTimers); + return stat.getAccumulator(mMeasurements).getSum(); } + +F32 Sampler::getPerSec( Rate& stat ) +{ + return stat.getAccumulator(mRates).getSum() / mElapsedSeconds; +} + +F32 Sampler::getMin( Measurement& stat ) +{ + return stat.getAccumulator(mMeasurements).getMin(); +} + +F32 Sampler::getMax( Measurement& stat ) +{ + return stat.getAccumulator(mMeasurements).getMax(); +} + +F32 Sampler::getMean( Measurement& stat ) +{ + return stat.getAccumulator(mMeasurements).getMean(); +} + +F32 Sampler::getStandardDeviation( Measurement& stat ) +{ + return stat.getAccumulator(mMeasurements).getStandardDeviation(); +} + + + + + + + } diff --git a/indra/llcommon/lltracesampler.h b/indra/llcommon/lltracesampler.h index d1ca7fc9bb..e3498fb39f 100644 --- a/indra/llcommon/lltracesampler.h +++ b/indra/llcommon/lltracesampler.h @@ -30,61 +30,70 @@ #include "stdtypes.h" #include "llpreprocessor.h" -#include "lltrace.h" +#include "llpointer.h" +#include "lltimer.h" namespace LLTrace { + template class Rate; + template class Measurement; + template class AccumulatorBuffer; + template class RateAccumulator; + template class MeasurementAccumulator; + class TimerAccumulator; + class LL_COMMON_API Sampler { public: + Sampler(); + ~Sampler(); void makePrimary(); + bool isPrimary(); void start(); void stop(); void resume(); - void mergeFrom(const Sampler* other); + void mergeSamples(const Sampler& other); + void initDeltas(const Sampler& other); + void mergeDeltas(const Sampler& other); void reset(); bool isStarted() { return mIsStarted; } - F32 getSum(Stat& stat) { return stat.getAccumulator(mF32Stats).getSum(); } - F32 getMin(Stat& stat) { return stat.getAccumulator(mF32Stats).getMin(); } - F32 getMax(Stat& stat) { return stat.getAccumulator(mF32Stats).getMax(); } - F32 getMean(Stat& stat) { return stat.getAccumulator(mF32Stats).getMean(); } + F32 getSum(Rate& stat); + F32 getPerSec(Rate& stat); - S32 getSum(Stat& stat) { return stat.getAccumulator(mS32Stats).getSum(); } - S32 getMin(Stat& stat) { return stat.getAccumulator(mS32Stats).getMin(); } - S32 getMax(Stat& stat) { return stat.getAccumulator(mS32Stats).getMax(); } - S32 getMean(Stat& stat) { return stat.getAccumulator(mS32Stats).getMean(); } + F32 getSum(Measurement& stat); + F32 getMin(Measurement& stat); + F32 getMax(Measurement& stat); + F32 getMean(Measurement& stat); + F32 getStandardDeviation(Measurement& stat); F64 getSampleTime() { return mElapsedSeconds; } private: friend class ThreadTrace; - Sampler(class ThreadTrace* thread_trace); - - // no copy - Sampler(const Sampler& other) {} // returns data for current thread class ThreadTrace* getThreadTrace(); - //TODO: take snapshot at sampler start so we can simplify updates - //AccumulatorBuffer > mF32StatsStart; - //AccumulatorBuffer > mS32StatsStart; - //AccumulatorBuffer mStackTimersStart; + LLCopyOnWritePointer > > mRatesStart; + LLCopyOnWritePointer > > mRates; + LLCopyOnWritePointer > > mMeasurements; + LLCopyOnWritePointer > mStackTimersStart; + LLCopyOnWritePointer > mStackTimers; - AccumulatorBuffer > mF32Stats; - AccumulatorBuffer > mS32Stats; - AccumulatorBuffer mStackTimers; + bool mIsStarted; + LLTimer mSamplingTimer; + F64 mElapsedSeconds; + }; + + class LL_COMMON_API PeriodicSampler + { - bool mIsStarted; - LLTimer mSamplingTimer; - F64 mElapsedSeconds; - ThreadTrace* mThreadTrace; }; } diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 2d1b582598..1f8be3da62 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -47,8 +47,7 @@ LLStatBar::LLStatBar(const Params& p) mMinBar(p.bar_min), mMaxBar(p.bar_max), mStatp(LLStat::getInstance(p.stat)), - mFloatStatp(LLTrace::Stat::getInstance(p.stat)), - mIntStatp(LLTrace::Stat::getInstance(p.stat)), + mFloatStatp(LLTrace::Rate::getInstance(p.stat)), mTickSpacing(p.tick_spacing), mLabelSpacing(p.label_spacing), mPrecision(p.precision), @@ -112,40 +111,23 @@ void LLStatBar::draw() } else if (mFloatStatp) { - LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); + LLTrace::Sampler* sampler = LLTrace::get_thread_trace()->getPrimarySampler(); if (mPerSec) { current = sampler->getSum(*mFloatStatp) / sampler->getSampleTime(); - min = sampler->getMin(*mFloatStatp) / sampler->getSampleTime(); - max = sampler->getMax(*mFloatStatp) / sampler->getSampleTime(); - mean = sampler->getMean(*mFloatStatp) / sampler->getSampleTime(); + //min = sampler->getMin(*mFloatStatp) / sampler->getSampleTime(); + //max = sampler->getMax(*mFloatStatp) / sampler->getSampleTime(); + //mean = sampler->getMean(*mFloatStatp) / sampler->getSampleTime(); } else { current = sampler->getSum(*mFloatStatp); - min = sampler->getMin(*mFloatStatp); - max = sampler->getMax(*mFloatStatp); - mean = sampler->getMean(*mFloatStatp); - } - } - else if (mIntStatp) - { - LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); - if (mPerSec) - { - current = (F32)sampler->getSum(*mIntStatp) / sampler->getSampleTime(); - min = (F32)sampler->getMin(*mIntStatp) / sampler->getSampleTime(); - max = (F32)sampler->getMax(*mIntStatp) / sampler->getSampleTime(); - mean = (F32)sampler->getMean(*mIntStatp) / sampler->getSampleTime(); - } - else - { - current = (F32)sampler->getSum(*mIntStatp); - min = (F32)sampler->getMin(*mIntStatp); - max = (F32)sampler->getMax(*mIntStatp); - mean = (F32)sampler->getMean(*mIntStatp); + //min = sampler->getMin(*mFloatStatp); + //max = sampler->getMax(*mFloatStatp); + //mean = sampler->getMean(*mFloatStatp); } } + if ((mUpdatesPerSec == 0.f) || (mUpdateTimer.getElapsedTimeF32() > 1.f/mUpdatesPerSec) || (mValue == 0.f)) { diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index 8348290abf..c735e7045b 100644 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -36,6 +36,7 @@ class LLStat; class LLStatBar : public LLView { public: + struct Params : public LLInitParam::Block { Optional label; @@ -93,8 +94,7 @@ private: BOOL mDisplayMean; // If true, display mean, if false, display current value LLStat* mStatp; - LLTrace::Stat* mFloatStatp; - LLTrace::Stat* mIntStatp; + LLTrace::Rate* mFloatStatp; LLFrameTimer mUpdateTimer; LLUIString mLabel; diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index 19896c4597..e0d7623999 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -48,8 +48,7 @@ LLStatGraph::LLStatGraph(const Params& p) mPrecision(p.precision), mValue(p.value), mStatp(p.stat.legacy_stat), - mF32Statp(p.stat.f32_stat), - mS32Statp(p.stat.s32_stat) + mF32Statp(p.stat.rate_stat) { setToolTip(p.name()); @@ -86,7 +85,7 @@ void LLStatGraph::draw() } else if (mF32Statp) { - LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); + LLTrace::Sampler* sampler = LLTrace::get_thread_trace()->getPrimarySampler(); if (mPerSec) { @@ -98,19 +97,7 @@ void LLStatGraph::draw() } } - else if (mS32Statp) - { - LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); - if (mPerSec) - { - mValue = sampler->getSum(*mS32Statp) / sampler->getSampleTime(); - } - else - { - mValue = sampler->getSum(*mS32Statp); - } - } frac = (mValue - mMin) / range; frac = llmax(0.f, frac); frac = llmin(1.f, frac); diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index e7de945694..69fc36ea52 100644 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -60,8 +60,7 @@ public: struct StatParams : public LLInitParam::ChoiceBlock { Alternative legacy_stat; - Alternative* > f32_stat; - Alternative* > s32_stat; + Alternative* > rate_stat; }; struct Params : public LLInitParam::Block @@ -107,8 +106,8 @@ public: private: LLStat* mStatp; - LLTrace::Stat* mF32Statp; - LLTrace::Stat* mS32Statp; + LLTrace::Rate* mF32Statp; + LLTrace::Rate* mS32Statp; BOOL mPerSec; diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 9f499ef4ef..ab97d6465a 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -198,7 +198,7 @@ BOOL LLStatusBar::postBuild() sgp.rect(r); sgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); sgp.mouse_opaque(false); - sgp.stat.f32_stat(&STAT_KBIT); + sgp.stat.rate_stat(&STAT_KBIT); sgp.units("Kbps"); sgp.precision(0); mSGBandwidth = LLUICtrlFactory::create(sgp); diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index b1aeaef91d..e2b09a1902 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -62,7 +62,7 @@ #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived -LLTrace::Stat STAT_KBIT("kbitstat"), +LLTrace::Rate STAT_KBIT("kbitstat"), STAT_LAYERS_KBIT("layerskbitstat"), STAT_OBJECT_KBIT("objectkbitstat"), STAT_ASSET_KBIT("assetkbitstat"), @@ -263,8 +263,7 @@ LLViewerStats::LLViewerStats() : mNumNewObjectsStat("numnewobjectsstat"), mNumSizeCulledStat("numsizeculledstat"), mNumVisCulledStat("numvisculledstat"), - mLastTimeDiff(0.0), - mSampler(LLThread::getTraceData()->createSampler()) + mLastTimeDiff(0.0) { for (S32 i = 0; i < ST_COUNT; i++) { @@ -467,12 +466,12 @@ void update_statistics() stats.mFPSStat.addValue(1); F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); - STAT_LAYERS_KBIT.sample(layer_bits/1024.f); + STAT_LAYERS_KBIT.add(layer_bits/1024.f); //stats.mLayersKBitStat.addValue(layer_bits/1024.f); - STAT_OBJECT_KBIT.sample(gObjectBits/1024.f); + STAT_OBJECT_KBIT.add(gObjectBits/1024.f); //stats.mObjectKBitStat.addValue(gObjectBits/1024.f); stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); - STAT_ASSET_KBIT.sample(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); + STAT_ASSET_KBIT.add(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); //stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); @@ -510,7 +509,7 @@ void update_statistics() static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { - STAT_TEXTURE_KBIT.sample(LLViewerTextureList::sTextureBits/1024.f); + STAT_TEXTURE_KBIT.add(LLViewerTextureList::sTextureBits/1024.f); //stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8; diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index ca70660ce9..9e809dd08c 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -31,7 +31,7 @@ #include "lltextureinfo.h" #include "lltracesampler.h" -extern LLTrace::Stat STAT_KBIT, +extern LLTrace::Rate STAT_KBIT, STAT_LAYERS_KBIT, STAT_OBJECT_KBIT, STAT_ASSET_KBIT, diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 034f8edf24..21a83b1676 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -622,7 +622,7 @@ void LLViewerTextureList::updateImages(F32 max_time) } cleared = FALSE; - LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); + LLTrace::Sampler* sampler = LLTrace::getThreadTrace()->getPrimarySampler(); LLAppViewer::getTextureFetch()->setTextureBandwidth(sampler->getMean(STAT_TEXTURE_KBIT) / sampler->getSampleTime()); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 97079e0588..1e8665e229 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -704,7 +704,7 @@ void LLWorld::updateNetStats() S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits(); LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f); LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f); - STAT_KBIT.sample(bits/1024.f); + STAT_KBIT.add(bits/1024.f); //LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f); LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in); LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out); -- cgit v1.3 From dbe9742703cf14db85ec3d16c540efc68dce95a6 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 2 Oct 2012 15:37:16 -0700 Subject: SH-3404 create sampler class renamed LLTrace::ThreadTrace to LLTrace::ThreadRecorder renamed LLTrace::Sampler to LLTrace::Recording --- indra/llcommon/CMakeLists.txt | 4 +- indra/llcommon/llapr.cpp | 23 ----- indra/llcommon/llapr.h | 26 +++++- indra/llcommon/llqueuedthread.cpp | 2 +- indra/llcommon/llthread.cpp | 4 +- indra/llcommon/lltrace.cpp | 143 ++++++++++++++--------------- indra/llcommon/lltrace.h | 66 +++++++------- indra/llcommon/lltracerecording.cpp | 167 ++++++++++++++++++++++++++++++++++ indra/llcommon/lltracerecording.h | 100 ++++++++++++++++++++ indra/llcommon/lltracesampler.cpp | 167 ---------------------------------- indra/llcommon/lltracesampler.h | 100 -------------------- indra/llui/llstatbar.cpp | 20 ++-- indra/llui/llstatgraph.cpp | 8 +- indra/newview/llappviewer.cpp | 2 +- indra/newview/llviewerstats.cpp | 3 +- indra/newview/llviewerstats.h | 7 +- indra/newview/llviewertexturelist.cpp | 4 +- 17 files changed, 419 insertions(+), 427 deletions(-) create mode 100644 indra/llcommon/lltracerecording.cpp create mode 100644 indra/llcommon/lltracerecording.h delete mode 100644 indra/llcommon/lltracesampler.cpp delete mode 100644 indra/llcommon/lltracesampler.h (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index e10dbb3e4d..1ccee23e1e 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -101,7 +101,7 @@ set(llcommon_SOURCE_FILES llthreadsafequeue.cpp lltimer.cpp lltrace.cpp - lltracesampler.cpp + lltracerecording.cpp lluri.cpp lluuid.cpp llworkerthread.cpp @@ -244,7 +244,7 @@ set(llcommon_HEADER_FILES llthreadsafequeue.h lltimer.h lltrace.h - lltracesampler.h + lltracerecording.h lltreeiterators.h lltypeinfolookup.h lluri.h diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index d23b70690d..1db3aa9e89 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -486,29 +486,6 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset) // bool LLThreadLocalPointerBase::sInitialized = false; -LLThreadLocalPointerBase::LLThreadLocalPointerBase() -: mThreadKey(NULL) -{ - if (sInitialized) - { - initStorage(); - } -} - -LLThreadLocalPointerBase::LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other) -: mThreadKey(NULL) -{ - if (sInitialized) - { - initStorage(); - } -} - -LLThreadLocalPointerBase::~LLThreadLocalPointerBase() -{ - destroyStorage(); -} - void LLThreadLocalPointerBase::set( void* value ) { llassert(sInitialized && mThreadKey); diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 6efb44a663..821274aeb3 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -261,9 +261,28 @@ public: class LLThreadLocalPointerBase : LLInstanceTracker { public: - LLThreadLocalPointerBase(); - LLThreadLocalPointerBase(const LLThreadLocalPointerBase& other); - ~LLThreadLocalPointerBase(); + LLThreadLocalPointerBase() + : mThreadKey(NULL) + { + if (sInitialized) + { + initStorage(); + } + } + + LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other) + : mThreadKey(NULL) + { + if (sInitialized) + { + initStorage(); + } + } + + ~LLThreadLocalPointerBase() + { + destroyStorage(); + } static void initAllThreadLocalStorage(); static void destroyAllThreadLocalStorage(); @@ -312,7 +331,6 @@ class LLThreadLocalPointer : public LLThreadLocalPointerBase public: LLThreadLocalPointer() - : LLThreadLocalPointerBase() {} explicit LLThreadLocalPointer(T* value) diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 9aa449d037..6e2a2b140f 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -112,7 +112,7 @@ void LLQueuedThread::shutdown() // virtual S32 LLQueuedThread::update(F32 max_time_ms) { - LLTrace::get_thread_trace()->pushToMaster(); + LLTrace::get_thread_recorder()->pushToMaster(); if (!mStarted) { diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index c705e5103b..6723e427f5 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -85,7 +85,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap { LLThread *threadp = (LLThread *)datap; - LLTrace::ThreadTrace* thread_trace = new LLTrace::SlaveThreadTrace(); + LLTrace::ThreadRecorder* thread_recorder = new LLTrace::SlaveThreadRecorder(); #if !LL_DARWIN sThreadIndex = threadp->mID; @@ -99,7 +99,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap // We're done with the run function, this thread is done executing now. threadp->mStatus = STOPPED; - delete thread_trace; + delete thread_recorder; return NULL; } diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 04817fd4f4..6b4c3aeb06 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -26,28 +26,28 @@ #include "linden_common.h" #include "lltrace.h" -#include "lltracesampler.h" +#include "lltracerecording.h" namespace LLTrace { -static MasterThreadTrace* gMasterThreadTrace = NULL; +static MasterThreadRecorder* gMasterThreadRecorder = NULL; void init() { - gMasterThreadTrace = new MasterThreadTrace(); + gMasterThreadRecorder = new MasterThreadRecorder(); } void cleanup() { - delete gMasterThreadTrace; - gMasterThreadTrace = NULL; + delete gMasterThreadRecorder; + gMasterThreadRecorder = NULL; } -LLThreadLocalPointer& get_thread_trace() +LLThreadLocalPointer& get_thread_recorder() { - static LLThreadLocalPointer s_trace_data; - return s_trace_data; + static LLThreadLocalPointer s_thread_recorder; + return s_thread_recorder; } @@ -55,164 +55,161 @@ BlockTimer::Recorder::StackEntry BlockTimer::sCurRecorder; -MasterThreadTrace& getMasterThreadTrace() +MasterThreadRecorder& getMasterThreadRecorder() { - llassert(gMasterThreadTrace != NULL); - return *gMasterThreadTrace; + llassert(gMasterThreadRecorder != NULL); + return *gMasterThreadRecorder; } /////////////////////////////////////////////////////////////////////// -// MasterThreadTrace +// ThreadRecorder /////////////////////////////////////////////////////////////////////// -ThreadTrace::ThreadTrace() +ThreadRecorder::ThreadRecorder() { - get_thread_trace() = this; - mPrimarySampler.makePrimary(); - mTotalSampler.start(); + get_thread_recorder() = this; + mPrimaryRecording.makePrimary(); + mFullRecording.start(); } -ThreadTrace::ThreadTrace( const ThreadTrace& other ) -: mPrimarySampler(other.mPrimarySampler), - mTotalSampler(other.mTotalSampler) +ThreadRecorder::ThreadRecorder( const ThreadRecorder& other ) +: mPrimaryRecording(other.mPrimaryRecording), + mFullRecording(other.mFullRecording) { - get_thread_trace() = this; - mPrimarySampler.makePrimary(); - mTotalSampler.start(); + get_thread_recorder() = this; + mPrimaryRecording.makePrimary(); + mFullRecording.start(); } -ThreadTrace::~ThreadTrace() +ThreadRecorder::~ThreadRecorder() { - get_thread_trace() = NULL; + get_thread_recorder() = NULL; } -//TODO: remove this and use llviewerstats sampler -Sampler* ThreadTrace::getPrimarySampler() +//TODO: remove this and use llviewerstats recording +Recording* ThreadRecorder::getPrimaryRecording() { - return &mPrimarySampler; + return &mPrimaryRecording; } -void ThreadTrace::activate( Sampler* sampler ) +void ThreadRecorder::activate( Recording* recorder ) { - for (std::list::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end(); + for (std::list::iterator it = mActiveRecordings.begin(), end_it = mActiveRecordings.end(); it != end_it; ++it) { - (*it)->mMeasurements.write()->mergeSamples(*mPrimarySampler.mMeasurements); + (*it)->mMeasurements.write()->mergeSamples(*mPrimaryRecording.mMeasurements); } - mPrimarySampler.mMeasurements.write()->reset(); + mPrimaryRecording.mMeasurements.write()->reset(); - sampler->initDeltas(mPrimarySampler); + recorder->initDeltas(mPrimaryRecording); - mActiveSamplers.push_front(sampler); + mActiveRecordings.push_front(recorder); } //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 ThreadTrace::deactivate( Sampler* sampler ) +void ThreadRecorder::deactivate( Recording* recorder ) { - sampler->mergeDeltas(mPrimarySampler); + recorder->mergeDeltas(mPrimaryRecording); // TODO: replace with intrusive list - std::list::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler); - if (found_it != mActiveSamplers.end()) + std::list::iterator found_it = std::find(mActiveRecordings.begin(), mActiveRecordings.end(), recorder); + if (found_it != mActiveRecordings.end()) { - mActiveSamplers.erase(found_it); + mActiveRecordings.erase(found_it); } } /////////////////////////////////////////////////////////////////////// -// SlaveThreadTrace +// SlaveThreadRecorder /////////////////////////////////////////////////////////////////////// -SlaveThreadTrace::SlaveThreadTrace() -: ThreadTrace(getMasterThreadTrace()) +SlaveThreadRecorder::SlaveThreadRecorder() +: ThreadRecorder(getMasterThreadRecorder()) { - getMasterThreadTrace().addSlaveThread(this); + getMasterThreadRecorder().addSlaveThread(this); } -SlaveThreadTrace::~SlaveThreadTrace() +SlaveThreadRecorder::~SlaveThreadRecorder() { - getMasterThreadTrace().removeSlaveThread(this); + getMasterThreadRecorder().removeSlaveThread(this); } -void SlaveThreadTrace::pushToMaster() +void SlaveThreadRecorder::pushToMaster() { - mTotalSampler.stop(); + mFullRecording.stop(); { - LLMutexLock(getMasterThreadTrace().getSlaveListMutex()); - mSharedData.copyFrom(mTotalSampler); + LLMutexLock(getMasterThreadRecorder().getSlaveListMutex()); + mSharedData.copyFrom(mFullRecording); } - mTotalSampler.start(); + mFullRecording.start(); } -void SlaveThreadTrace::SharedData::copyFrom( const Sampler& source ) +void SlaveThreadRecorder::SharedData::copyFrom( const Recording& source ) { - LLMutexLock lock(&mSamplerMutex); - mSampler.mergeSamples(source); + LLMutexLock lock(&mRecorderMutex); + mRecorder.mergeSamples(source); } -void SlaveThreadTrace::SharedData::copyTo( Sampler& sink ) +void SlaveThreadRecorder::SharedData::copyTo( Recording& sink ) { - LLMutexLock lock(&mSamplerMutex); - sink.mergeSamples(mSampler); + LLMutexLock lock(&mRecorderMutex); + sink.mergeSamples(mRecorder); } - - - /////////////////////////////////////////////////////////////////////// -// MasterThreadTrace +// MasterThreadRecorder /////////////////////////////////////////////////////////////////////// -void MasterThreadTrace::pullFromSlaveThreads() +void MasterThreadRecorder::pullFromSlaveThreads() { LLMutexLock lock(&mSlaveListMutex); - for (slave_thread_trace_list_t::iterator it = mSlaveThreadTraces.begin(), end_it = mSlaveThreadTraces.end(); + for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); it != end_it; ++it) { - (*it)->mSlaveTrace->mSharedData.copyTo((*it)->mSamplerStorage); + (*it)->mRecorder->mSharedData.copyTo((*it)->mSlaveRecording); } } -void MasterThreadTrace::addSlaveThread( class SlaveThreadTrace* child ) +void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child ) { LLMutexLock lock(&mSlaveListMutex); - mSlaveThreadTraces.push_back(new SlaveThreadTraceProxy(child)); + mSlaveThreadRecorders.push_back(new SlaveThreadRecorderProxy(child)); } -void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child ) +void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child ) { LLMutexLock lock(&mSlaveListMutex); - for (slave_thread_trace_list_t::iterator it = mSlaveThreadTraces.begin(), end_it = mSlaveThreadTraces.end(); + for (slave_thread_recorder_list_t::iterator it = mSlaveThreadRecorders.begin(), end_it = mSlaveThreadRecorders.end(); it != end_it; ++it) { - if ((*it)->mSlaveTrace == child) + if ((*it)->mRecorder == child) { - mSlaveThreadTraces.erase(it); + mSlaveThreadRecorders.erase(it); break; } } } -void MasterThreadTrace::pushToMaster() +void MasterThreadRecorder::pushToMaster() {} -MasterThreadTrace::MasterThreadTrace() +MasterThreadRecorder::MasterThreadRecorder() {} /////////////////////////////////////////////////////////////////////// -// MasterThreadTrace::SlaveThreadTraceProxy +// MasterThreadRecorder::SlaveThreadTraceProxy /////////////////////////////////////////////////////////////////////// -MasterThreadTrace::SlaveThreadTraceProxy::SlaveThreadTraceProxy( class SlaveThreadTrace* trace) -: mSlaveTrace(trace) +MasterThreadRecorder::SlaveThreadRecorderProxy::SlaveThreadRecorderProxy( class SlaveThreadRecorder* recorder) +: mRecorder(recorder) {} } diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 5ec1c821c3..c5356777ae 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -34,7 +34,7 @@ #include "llmemory.h" #include "lltimer.h" #include "llrefcount.h" -#include "lltracesampler.h" +#include "lltracerecording.h" #include @@ -45,14 +45,14 @@ namespace LLTrace { - class Sampler; + class Recording; void init(); void cleanup(); - LLThreadLocalPointer& get_thread_trace(); + LLThreadLocalPointer& get_thread_recorder(); - class LL_COMMON_API MasterThreadTrace& getMasterThreadTrace(); + class LL_COMMON_API MasterThreadRecorder& getMasterThreadRecorder(); // one per thread per type template @@ -482,33 +482,33 @@ namespace LLTrace static Recorder::StackEntry sCurRecorder; }; - class LL_COMMON_API ThreadTrace + class LL_COMMON_API ThreadRecorder { public: - ThreadTrace(); - ThreadTrace(const ThreadTrace& other); + ThreadRecorder(); + ThreadRecorder(const ThreadRecorder& other); - virtual ~ThreadTrace(); + virtual ~ThreadRecorder(); - void activate(Sampler* sampler); - void deactivate(Sampler* sampler); + void activate(Recording* recording); + void deactivate(Recording* recording); virtual void pushToMaster() = 0; - Sampler* getPrimarySampler(); + Recording* getPrimaryRecording(); protected: - Sampler mPrimarySampler; - Sampler mTotalSampler; - std::list mActiveSamplers; + Recording mPrimaryRecording; + Recording mFullRecording; + std::list mActiveRecordings; }; - class LL_COMMON_API MasterThreadTrace : public ThreadTrace + class LL_COMMON_API MasterThreadRecorder : public ThreadRecorder { public: - MasterThreadTrace(); + MasterThreadRecorder(); - void addSlaveThread(class SlaveThreadTrace* child); - void removeSlaveThread(class SlaveThreadTrace* child); + void addSlaveThread(class SlaveThreadRecorder* child); + void removeSlaveThread(class SlaveThreadRecorder* child); /*virtual */ void pushToMaster(); @@ -518,41 +518,41 @@ namespace LLTrace LLMutex* getSlaveListMutex() { return &mSlaveListMutex; } private: - struct SlaveThreadTraceProxy + struct SlaveThreadRecorderProxy { - SlaveThreadTraceProxy(class SlaveThreadTrace* trace); + SlaveThreadRecorderProxy(class SlaveThreadRecorder* recorder); - class SlaveThreadTrace* mSlaveTrace; - Sampler mSamplerStorage; + class SlaveThreadRecorder* mRecorder; + Recording mSlaveRecording; private: //no need to copy these and then have to duplicate the storage - SlaveThreadTraceProxy(const SlaveThreadTraceProxy& other) {} + SlaveThreadRecorderProxy(const SlaveThreadRecorderProxy& other) {} }; - typedef std::list slave_thread_trace_list_t; + typedef std::list slave_thread_recorder_list_t; - slave_thread_trace_list_t mSlaveThreadTraces; + slave_thread_recorder_list_t mSlaveThreadRecorders; LLMutex mSlaveListMutex; }; - class LL_COMMON_API SlaveThreadTrace : public ThreadTrace + class LL_COMMON_API SlaveThreadRecorder : public ThreadRecorder { public: - SlaveThreadTrace(); - ~SlaveThreadTrace(); + SlaveThreadRecorder(); + ~SlaveThreadRecorder(); // call this periodically to gather stats data for master thread to consume /*virtual*/ void pushToMaster(); - MasterThreadTrace* mMaster; + MasterThreadRecorder* mMaster; class SharedData { public: - void copyFrom(const Sampler& source); - void copyTo(Sampler& sink); + void copyFrom(const Recording& source); + void copyTo(Recording& sink); private: - LLMutex mSamplerMutex; - Sampler mSampler; + LLMutex mRecorderMutex; + Recording mRecorder; }; SharedData mSharedData; }; diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp new file mode 100644 index 0000000000..a792d40f9d --- /dev/null +++ b/indra/llcommon/lltracerecording.cpp @@ -0,0 +1,167 @@ +/** + * @file lltracesampler.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 "lltracerecording.h" +#include "lltrace.h" +#include "llthread.h" + +namespace LLTrace +{ + +/////////////////////////////////////////////////////////////////////// +// Recording +/////////////////////////////////////////////////////////////////////// + +Recording::Recording() +: mElapsedSeconds(0), + mIsStarted(false), + mRatesStart(new AccumulatorBuffer >()), + mRates(new AccumulatorBuffer >()), + mMeasurements(new AccumulatorBuffer >()), + mStackTimers(new AccumulatorBuffer()), + mStackTimersStart(new AccumulatorBuffer()) +{ +} + +Recording::~Recording() +{ +} + +void Recording::start() +{ + reset(); + resume(); +} + +void Recording::reset() +{ + mRates.write()->reset(); + mMeasurements.write()->reset(); + mStackTimers.write()->reset(); + + mElapsedSeconds = 0.0; + mSamplingTimer.reset(); +} + +void Recording::resume() +{ + if (!mIsStarted) + { + mSamplingTimer.reset(); + LLTrace::get_thread_recorder()->activate(this); + mIsStarted = true; + } +} + +void Recording::stop() +{ + if (mIsStarted) + { + mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); + LLTrace::get_thread_recorder()->deactivate(this); + mIsStarted = false; + } +} + + +void Recording::makePrimary() +{ + mRates.write()->makePrimary(); + mMeasurements.write()->makePrimary(); + mStackTimers.write()->makePrimary(); +} + +bool Recording::isPrimary() +{ + return mRates->isPrimary(); +} + +void Recording::mergeSamples( const Recording& other ) +{ + mRates.write()->mergeSamples(*other.mRates); + mMeasurements.write()->mergeSamples(*other.mMeasurements); + mStackTimers.write()->mergeSamples(*other.mStackTimers); +} + +void Recording::initDeltas( const Recording& other ) +{ + mRatesStart.write()->copyFrom(*other.mRates); + mStackTimersStart.write()->copyFrom(*other.mStackTimers); +} + + +void Recording::mergeDeltas( const Recording& other ) +{ + mRates.write()->mergeDeltas(*mRatesStart, *other.mRates); + mStackTimers.write()->mergeDeltas(*mStackTimersStart, *other.mStackTimers); + mMeasurements.write()->mergeSamples(*other.mMeasurements); +} + + +F32 Recording::getSum( Rate& stat ) +{ + return stat.getAccumulator(mRates).getSum(); +} + +F32 Recording::getSum( Measurement& stat ) +{ + return stat.getAccumulator(mMeasurements).getSum(); +} + + +F32 Recording::getPerSec( Rate& stat ) +{ + return stat.getAccumulator(mRates).getSum() / mElapsedSeconds; +} + +F32 Recording::getMin( Measurement& stat ) +{ + return stat.getAccumulator(mMeasurements).getMin(); +} + +F32 Recording::getMax( Measurement& stat ) +{ + return stat.getAccumulator(mMeasurements).getMax(); +} + +F32 Recording::getMean( Measurement& stat ) +{ + return stat.getAccumulator(mMeasurements).getMean(); +} + +F32 Recording::getStandardDeviation( Measurement& stat ) +{ + return stat.getAccumulator(mMeasurements).getStandardDeviation(); +} + + + + + + + +} diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h new file mode 100644 index 0000000000..83dc503ea6 --- /dev/null +++ b/indra/llcommon/lltracerecording.h @@ -0,0 +1,100 @@ +/** + * @file lltracerecording.h + * @brief Sampling object for collecting runtime statistics originating from lltrace. + * + * $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$ + */ + +#ifndef LL_LLTRACERECORDING_H +#define LL_LLTRACERECORDING_H + +#include "stdtypes.h" +#include "llpreprocessor.h" + +#include "llpointer.h" +#include "lltimer.h" + +namespace LLTrace +{ + template class Rate; + template class Measurement; + template class AccumulatorBuffer; + template class RateAccumulator; + template class MeasurementAccumulator; + class TimerAccumulator; + + class LL_COMMON_API Recording + { + public: + Recording(); + + ~Recording(); + + void makePrimary(); + bool isPrimary(); + + void start(); + void stop(); + void resume(); + + void mergeSamples(const Recording& other); + void initDeltas(const Recording& other); + void mergeDeltas(const Recording& other); + + void reset(); + + bool isStarted() { return mIsStarted; } + + F32 getSum(Rate& stat); + F32 getPerSec(Rate& stat); + + F32 getSum(Measurement& stat); + F32 getMin(Measurement& stat); + F32 getMax(Measurement& stat); + F32 getMean(Measurement& stat); + F32 getStandardDeviation(Measurement& stat); + + F64 getSampleTime() { return mElapsedSeconds; } + + private: + friend class ThreadRecorder; + // returns data for current thread + class ThreadRecorder* getThreadRecorder(); + + LLCopyOnWritePointer > > mRatesStart; + LLCopyOnWritePointer > > mRates; + LLCopyOnWritePointer > > mMeasurements; + LLCopyOnWritePointer > mStackTimersStart; + LLCopyOnWritePointer > mStackTimers; + + bool mIsStarted; + LLTimer mSamplingTimer; + F64 mElapsedSeconds; + }; + + class LL_COMMON_API PeriodicRecording + { + + }; +} + +#endif // LL_LLTRACERECORDING_H diff --git a/indra/llcommon/lltracesampler.cpp b/indra/llcommon/lltracesampler.cpp deleted file mode 100644 index 17e58b96e2..0000000000 --- a/indra/llcommon/lltracesampler.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @file lltracesampler.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 "lltracesampler.h" -#include "lltrace.h" -#include "llthread.h" - -namespace LLTrace -{ - -/////////////////////////////////////////////////////////////////////// -// Sampler -/////////////////////////////////////////////////////////////////////// - -Sampler::Sampler() -: mElapsedSeconds(0), - mIsStarted(false), - mRatesStart(new AccumulatorBuffer >()), - mRates(new AccumulatorBuffer >()), - mMeasurements(new AccumulatorBuffer >()), - mStackTimers(new AccumulatorBuffer()), - mStackTimersStart(new AccumulatorBuffer()) -{ -} - -Sampler::~Sampler() -{ -} - -void Sampler::start() -{ - reset(); - resume(); -} - -void Sampler::reset() -{ - mRates.write()->reset(); - mMeasurements.write()->reset(); - mStackTimers.write()->reset(); - - mElapsedSeconds = 0.0; - mSamplingTimer.reset(); -} - -void Sampler::resume() -{ - if (!mIsStarted) - { - mSamplingTimer.reset(); - LLTrace::get_thread_trace()->activate(this); - mIsStarted = true; - } -} - -void Sampler::stop() -{ - if (mIsStarted) - { - mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); - LLTrace::get_thread_trace()->deactivate(this); - mIsStarted = false; - } -} - - -void Sampler::makePrimary() -{ - mRates.write()->makePrimary(); - mMeasurements.write()->makePrimary(); - mStackTimers.write()->makePrimary(); -} - -bool Sampler::isPrimary() -{ - return mRates->isPrimary(); -} - -void Sampler::mergeSamples( const Sampler& other ) -{ - mRates.write()->mergeSamples(*other.mRates); - mMeasurements.write()->mergeSamples(*other.mMeasurements); - mStackTimers.write()->mergeSamples(*other.mStackTimers); -} - -void Sampler::initDeltas( const Sampler& other ) -{ - mRatesStart.write()->copyFrom(*other.mRates); - mStackTimersStart.write()->copyFrom(*other.mStackTimers); -} - - -void Sampler::mergeDeltas( const Sampler& other ) -{ - mRates.write()->mergeDeltas(*mRatesStart, *other.mRates); - mStackTimers.write()->mergeDeltas(*mStackTimersStart, *other.mStackTimers); - mMeasurements.write()->mergeSamples(*other.mMeasurements); -} - - -F32 Sampler::getSum( Rate& stat ) -{ - return stat.getAccumulator(mRates).getSum(); -} - -F32 Sampler::getSum( Measurement& stat ) -{ - return stat.getAccumulator(mMeasurements).getSum(); -} - - -F32 Sampler::getPerSec( Rate& stat ) -{ - return stat.getAccumulator(mRates).getSum() / mElapsedSeconds; -} - -F32 Sampler::getMin( Measurement& stat ) -{ - return stat.getAccumulator(mMeasurements).getMin(); -} - -F32 Sampler::getMax( Measurement& stat ) -{ - return stat.getAccumulator(mMeasurements).getMax(); -} - -F32 Sampler::getMean( Measurement& stat ) -{ - return stat.getAccumulator(mMeasurements).getMean(); -} - -F32 Sampler::getStandardDeviation( Measurement& stat ) -{ - return stat.getAccumulator(mMeasurements).getStandardDeviation(); -} - - - - - - - -} diff --git a/indra/llcommon/lltracesampler.h b/indra/llcommon/lltracesampler.h deleted file mode 100644 index e3498fb39f..0000000000 --- a/indra/llcommon/lltracesampler.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file lltracesampler.h - * @brief Sampling object for collecting runtime statistics originating from lltrace. - * - * $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$ - */ - -#ifndef LL_LLTRACESAMPLER_H -#define LL_LLTRACESAMPLER_H - -#include "stdtypes.h" -#include "llpreprocessor.h" - -#include "llpointer.h" -#include "lltimer.h" - -namespace LLTrace -{ - template class Rate; - template class Measurement; - template class AccumulatorBuffer; - template class RateAccumulator; - template class MeasurementAccumulator; - class TimerAccumulator; - - class LL_COMMON_API Sampler - { - public: - Sampler(); - - ~Sampler(); - - void makePrimary(); - bool isPrimary(); - - void start(); - void stop(); - void resume(); - - void mergeSamples(const Sampler& other); - void initDeltas(const Sampler& other); - void mergeDeltas(const Sampler& other); - - void reset(); - - bool isStarted() { return mIsStarted; } - - F32 getSum(Rate& stat); - F32 getPerSec(Rate& stat); - - F32 getSum(Measurement& stat); - F32 getMin(Measurement& stat); - F32 getMax(Measurement& stat); - F32 getMean(Measurement& stat); - F32 getStandardDeviation(Measurement& stat); - - F64 getSampleTime() { return mElapsedSeconds; } - - private: - friend class ThreadTrace; - // returns data for current thread - class ThreadTrace* getThreadTrace(); - - LLCopyOnWritePointer > > mRatesStart; - LLCopyOnWritePointer > > mRates; - LLCopyOnWritePointer > > mMeasurements; - LLCopyOnWritePointer > mStackTimersStart; - LLCopyOnWritePointer > mStackTimers; - - bool mIsStarted; - LLTimer mSamplingTimer; - F64 mElapsedSeconds; - }; - - class LL_COMMON_API PeriodicSampler - { - - }; -} - -#endif // LL_LLTRACESAMPLER_H diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 1f8be3da62..bc9603804b 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -36,7 +36,7 @@ #include "llstat.h" #include "lluictrlfactory.h" -#include "lltracesampler.h" +#include "lltracerecording.h" /////////////////////////////////////////////////////////////////////////////////// @@ -111,20 +111,20 @@ void LLStatBar::draw() } else if (mFloatStatp) { - LLTrace::Sampler* sampler = LLTrace::get_thread_trace()->getPrimarySampler(); + LLTrace::Recording* recording = LLTrace::get_thread_recorder()->getPrimaryRecording(); if (mPerSec) { - current = sampler->getSum(*mFloatStatp) / sampler->getSampleTime(); - //min = sampler->getMin(*mFloatStatp) / sampler->getSampleTime(); - //max = sampler->getMax(*mFloatStatp) / sampler->getSampleTime(); - //mean = sampler->getMean(*mFloatStatp) / sampler->getSampleTime(); + current = recording->getSum(*mFloatStatp) / recording->getSampleTime(); + //min = recording->getMin(*mFloatStatp) / recording->getSampleTime(); + //max = recording->getMax(*mFloatStatp) / recording->getSampleTime(); + //mean = recording->getMean(*mFloatStatp) / recording->getSampleTime(); } else { - current = sampler->getSum(*mFloatStatp); - //min = sampler->getMin(*mFloatStatp); - //max = sampler->getMax(*mFloatStatp); - //mean = sampler->getMean(*mFloatStatp); + current = recording->getSum(*mFloatStatp); + //min = recording->getMin(*mFloatStatp); + //max = recording->getMax(*mFloatStatp); + //mean = recording->getMean(*mFloatStatp); } } diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index e0d7623999..aed9e4ec93 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -35,7 +35,7 @@ #include "llstat.h" #include "llgl.h" #include "llglheaders.h" -#include "lltracesampler.h" +#include "lltracerecording.h" //#include "llviewercontrol.h" /////////////////////////////////////////////////////////////////////////////////// @@ -85,15 +85,15 @@ void LLStatGraph::draw() } else if (mF32Statp) { - LLTrace::Sampler* sampler = LLTrace::get_thread_trace()->getPrimarySampler(); + LLTrace::Recording* recording = LLTrace::get_thread_recorder()->getPrimaryRecording(); if (mPerSec) { - mValue = sampler->getSum(*mF32Statp) / sampler->getSampleTime(); + mValue = recording->getSum(*mF32Statp) / recording->getSampleTime(); } else { - mValue = sampler->getSum(*mF32Statp); + mValue = recording->getSum(*mF32Statp); } } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0bb87dfa6c..22f3cce9e8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1222,7 +1222,7 @@ bool LLAppViewer::mainLoop() { LLFastTimer _(FTM_FRAME); LLFastTimer::nextFrame(); - LLTrace::getMasterThreadTrace().pullFromSlaveThreads(); + LLTrace::getMasterThreadRecorder().pullFromSlaveThreads(); //clear call stack records llclearcallstacks; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index e2b09a1902..a6e9643edd 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -276,12 +276,11 @@ LLViewerStats::LLViewerStats() : } mAgentPositionSnaps.reset(); - mSampler->start(); + mRecording.start(); } LLViewerStats::~LLViewerStats() { - delete mSampler; } void LLViewerStats::resetStats() diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 9e809dd08c..ca5f6c6821 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -29,7 +29,8 @@ #include "llstat.h" #include "lltextureinfo.h" -#include "lltracesampler.h" +#include "lltracerecording.h" +#include "lltrace.h" extern LLTrace::Rate STAT_KBIT, STAT_LAYERS_KBIT, @@ -297,11 +298,11 @@ public: static void recordPhaseStat(const std::string& phase_name, F32 value); }; - LLTrace::Sampler* getSampler() { return mSampler; } + LLTrace::Recording& getRecording() { return mRecording; } private: F64 mStats[ST_COUNT]; - LLTrace::Sampler* mSampler; + LLTrace::Recording mRecording; F64 mLastTimeDiff; // used for time stat updates }; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 21a83b1676..4e62cbd714 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -622,9 +622,9 @@ void LLViewerTextureList::updateImages(F32 max_time) } cleared = FALSE; - LLTrace::Sampler* sampler = LLTrace::getThreadTrace()->getPrimarySampler(); + LLTrace::Recording* recording = LLTrace::get_thread_recorder()->getPrimaryRecording(); - LLAppViewer::getTextureFetch()->setTextureBandwidth(sampler->getMean(STAT_TEXTURE_KBIT) / sampler->getSampleTime()); + LLAppViewer::getTextureFetch()->setTextureBandwidth(recording->getPerSec(STAT_TEXTURE_KBIT)); LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages); LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); -- cgit v1.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/llqueuedthread.cpp | 2 +- indra/llcommon/llthread.cpp | 1 + indra/llcommon/lltrace.cpp | 1 + indra/llcommon/lltrace.h | 88 +++++--- indra/llcommon/lltracerecording.cpp | 96 +-------- indra/llcommon/lltracerecording.h | 145 ++++++++++--- indra/llcommon/lltracethreadrecorder.cpp | 14 +- indra/llcommon/llunit.h | 176 +++++++++------- indra/llui/llstatbar.cpp | 1 + indra/llui/llstatgraph.cpp | 1 + indra/newview/lltexturefetch.cpp | 3 +- indra/newview/llviewermessage.cpp | 13 +- indra/newview/llviewerstats.cpp | 349 ++++++++++--------------------- indra/newview/llviewerstats.h | 9 +- indra/newview/llviewertexturelist.cpp | 14 +- indra/newview/llviewertexturelist.h | 3 - indra/newview/llviewerwindow.cpp | 7 +- indra/newview/llworld.cpp | 36 ++-- indra/newview/pipeline.cpp | 5 +- 19 files changed, 461 insertions(+), 503 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 6e2a2b140f..218f6dbcd0 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -28,7 +28,7 @@ #include "llstl.h" #include "lltimer.h" // ms_sleep() -#include "lltrace.h" +#include "lltracethreadrecorder.h" //============================================================================ diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 6723e427f5..cc661bab59 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -33,6 +33,7 @@ #include "lltimer.h" #include "lltrace.h" +#include "lltracethreadrecorder.h" #if LL_LINUX || LL_SOLARIS #include diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 2b1c8d8ce8..d5911ece25 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -27,6 +27,7 @@ #include "lltrace.h" #include "lltracerecording.h" +#include "lltracethreadrecorder.h" namespace LLTrace { diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d83ea77363..539a37ce31 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -32,9 +32,9 @@ #include "llmemory.h" #include "llrefcount.h" -#include "lltracerecording.h" -#include "lltracethreadrecorder.h" +//#include "lltracethreadrecorder.h" #include "llunit.h" +#include "llapr.h" #include @@ -44,6 +44,8 @@ namespace LLTrace { + class Recording; + void init(); void cleanup(); @@ -89,23 +91,23 @@ namespace LLTrace return mStorage[index]; } - void mergeSamples(const AccumulatorBuffer& other) + void addSamples(const AccumulatorBuffer& other) { llassert(mNextStorageSlot == other.mNextStorageSlot); for (size_t i = 0; i < mNextStorageSlot; i++) { - mStorage[i].mergeSamples(other.mStorage[i]); + mStorage[i].addSamples(other.mStorage[i]); } } - void mergeDeltas(const AccumulatorBuffer& start, const AccumulatorBuffer& finish) + void addDeltas(const AccumulatorBuffer& start, const AccumulatorBuffer& finish) { llassert(mNextStorageSlot == start.mNextStorageSlot && mNextStorageSlot == finish.mNextStorageSlot); for (size_t i = 0; i < mNextStorageSlot; i++) { - mStorage[i].mergeDeltas(start.mStorage[i], finish.mStorage[i]); + mStorage[i].addDeltas(start.mStorage[i], finish.mStorage[i]); } } @@ -173,8 +175,9 @@ namespace LLTrace class LL_COMMON_API TraceType { public: - TraceType(const std::string& name) - : mName(name) + TraceType(const char* name, const char* description = NULL) + : mName(name), + mDescription(description ? description : "") { mAccumulatorIndex = AccumulatorBuffer::getDefaultBuffer().reserveSlot(); } @@ -189,6 +192,7 @@ namespace LLTrace protected: std::string mName; + std::string mDescription; size_t mAccumulatorIndex; }; @@ -201,6 +205,8 @@ namespace LLTrace : mSum(0), mMin(0), mMax(0), + mMean(0), + mVarianceSum(0), mNumSamples(0) {} @@ -218,10 +224,11 @@ namespace LLTrace } F32 old_mean = mMean; mMean += ((F32)value - old_mean) / (F32)mNumSamples; - mStandardDeviation += ((F32)value - old_mean) * ((F32)value - mMean); + mVarianceSum += ((F32)value - old_mean) * ((F32)value - mMean); + mLastValue = value; } - void mergeSamples(const MeasurementAccumulator& other) + void addSamples(const MeasurementAccumulator& other) { mSum += other.mSum; if (other.mMin < mMin) @@ -240,19 +247,20 @@ namespace LLTrace n_2 = (F32)other.mNumSamples; F32 m_1 = mMean, m_2 = other.mMean; - F32 sd_1 = mStandardDeviation, - sd_2 = other.mStandardDeviation; + F32 sd_1 = getStandardDeviation(), + sd_2 = other.getStandardDeviation(); // combine variance (and hence standard deviation) of 2 different sized sample groups using // the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm - F32 variance = ((((n_1 - 1.f) * sd_1 * sd_1) - + ((n_2 - 1.f) * sd_2 * sd_2) - + (((n_1 * n_2) / (n_1 + n_2)) - * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) - / (n_1 + n_2 - 1.f)); - mStandardDeviation = sqrtf(variance); + mVarianceSum = (F32)mNumSamples + * ((((n_1 - 1.f) * sd_1 * sd_1) + + ((n_2 - 1.f) * sd_2 * sd_2) + + (((n_1 * n_2) / (n_1 + n_2)) + * ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2)))) + / (n_1 + n_2 - 1.f)); + mLastValue = other.mLastValue; } - void mergeDeltas(const MeasurementAccumulator& start, const MeasurementAccumulator& finish) + void addDeltas(const MeasurementAccumulator& start, const MeasurementAccumulator& finish) { llerrs << "Delta merge invalid for measurement accumulators" << llendl; } @@ -268,16 +276,18 @@ namespace LLTrace T getSum() const { return mSum; } T getMin() const { return mMin; } T getMax() const { return mMax; } + T getLastValue() const { return mLastValue; } F32 getMean() const { return mMean; } - F32 getStandardDeviation() const { return mStandardDeviation; } + F32 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); } private: T mSum, mMin, - mMax; + mMax, + mLastValue; F32 mMean, - mStandardDeviation; + mVarianceSum; U32 mNumSamples; }; @@ -297,13 +307,13 @@ namespace LLTrace mSum += value; } - void mergeSamples(const RateAccumulator& other) + void addSamples(const RateAccumulator& other) { mSum += other.mSum; mNumSamples += other.mNumSamples; } - void mergeDeltas(const RateAccumulator& start, const RateAccumulator& finish) + void addDeltas(const RateAccumulator& start, const RateAccumulator& finish) { mSum += finish.mSum - start.mSum; mNumSamples += finish.mNumSamples - start.mNumSamples; @@ -329,7 +339,10 @@ namespace LLTrace public LLInstanceTracker, std::string> { public: - Measurement(const std::string& name) + typedef T storage_t; + typedef T base_unit_t; + + Measurement(const char* name, const char* description = NULL) : TraceType(name), LLInstanceTracker(name) {} @@ -345,8 +358,11 @@ namespace LLTrace : public Measurement { public: + typedef typename T::storage_t storage_t; + typedef typename T::base_unit_t base_unit_t; + typedef Measurement base_measurement_t; - Measurement(const std::string& name) + Measurement(const char* name, const char* description = NULL) : Measurement(name) {} @@ -363,7 +379,10 @@ namespace LLTrace public LLInstanceTracker, std::string> { public: - Rate(const std::string& name) + typedef T storage_t; + typedef T base_unit_t; + + Rate(const char* name, const char* description = NULL) : TraceType(name), LLInstanceTracker(name) {} @@ -379,7 +398,10 @@ namespace LLTrace : public Rate { public: - Rate(const std::string& name) + typedef typename T::storage_t storage_t; + typedef typename T::base_unit_t base_unit_t; + + Rate(const char* name, const char* description = NULL) : Rate(name) {} @@ -394,7 +416,9 @@ namespace LLTrace class LL_COMMON_API Count { public: - Count(const std::string& name) + typedef typename Rate::base_unit_t base_unit_t; + + Count(const char* name) : mIncrease(name + "_increase"), mDecrease(name + "_decrease"), mTotal(name) @@ -413,7 +437,7 @@ namespace LLTrace mTotal.add(value); } private: - friend class LLTrace::Recording; + friend LLTrace::Recording; Rate mIncrease; Rate mDecrease; Rate mTotal; @@ -433,14 +457,14 @@ namespace LLTrace bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame std::vector mChildren; // currently assumed child timers - void mergeSamples(const TimerAccumulator& other) + void addSamples(const TimerAccumulator& other) { mTotalTimeCounter += other.mTotalTimeCounter; mChildTimeCounter += other.mChildTimeCounter; mCalls += other.mCalls; } - void mergeDeltas(const TimerAccumulator& start, const TimerAccumulator& finish) + void addDeltas(const TimerAccumulator& start, const TimerAccumulator& finish) { mTotalTimeCounter += finish.mTotalTimeCounter - start.mTotalTimeCounter; mChildTimeCounter += finish.mChildTimeCounter - start.mChildTimeCounter; diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index f0b17ef100..e20bf797e7 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -25,8 +25,9 @@ #include "linden_common.h" -#include "lltracerecording.h" #include "lltrace.h" +#include "lltracerecording.h" +#include "lltracethreadrecorder.h" #include "llthread.h" namespace LLTrace @@ -101,99 +102,22 @@ void Recording::makePrimary() mStackTimers.write()->makePrimary(); } -bool Recording::isPrimary() +bool Recording::isPrimary() const { return mRates->isPrimary(); } -void Recording::mergeSamples( const Recording& other ) +void Recording::addSamples( const Recording& other ) { - mRates.write()->mergeSamples(*other.mRates); - mMeasurements.write()->mergeSamples(*other.mMeasurements); - mStackTimers.write()->mergeSamples(*other.mStackTimers); + mRates.write()->addSamples(*other.mRates); + mMeasurements.write()->addSamples(*other.mMeasurements); + mStackTimers.write()->addSamples(*other.mStackTimers); } -void Recording::mergeDeltas(const Recording& baseline, const Recording& target) +void Recording::addDeltas(const Recording& baseline, const Recording& target) { - mRates.write()->mergeDeltas(*baseline.mRates, *target.mRates); - mStackTimers.write()->mergeDeltas(*baseline.mStackTimers, *target.mStackTimers); + mRates.write()->addDeltas(*baseline.mRates, *target.mRates); + mStackTimers.write()->addDeltas(*baseline.mStackTimers, *target.mStackTimers); } - -F32 Recording::getSum(const Rate& stat) -{ - return stat.getAccumulator(mRates).getSum(); -} - -F32 Recording::getPerSec(const Rate& stat) -{ - return stat.getAccumulator(mRates).getSum() / mElapsedSeconds; -} - -F32 Recording::getSum(const Measurement& stat) -{ - return stat.getAccumulator(mMeasurements).getSum(); -} - -F32 Recording::getMin(const Measurement& stat) -{ - return stat.getAccumulator(mMeasurements).getMin(); -} - -F32 Recording::getMax(const Measurement& stat) -{ - return stat.getAccumulator(mMeasurements).getMax(); -} - -F32 Recording::getMean(const Measurement& stat) -{ - return stat.getAccumulator(mMeasurements).getMean(); -} - -F32 Recording::getStandardDeviation(const Measurement& stat) -{ - return stat.getAccumulator(mMeasurements).getStandardDeviation(); -} - -F32 Recording::getSum(const Count& stat) -{ - return getSum(stat.mTotal); -} - -F32 Recording::getPerSec(const Count& stat) -{ - return getPerSec(stat.mTotal); -} - -F32 Recording::getIncrease(const Count& stat) -{ - return getSum(stat.mIncrease); -} - -F32 Recording::getIncreasePerSec(const Count& stat) -{ - return getPerSec(stat.mIncrease); -} - -F32 Recording::getDecrease(const Count& stat) -{ - return getSum(stat.mDecrease); -} - -F32 Recording::getDecreasePerSec(const Count& stat) -{ - return getPerSec(stat.mDecrease); -} - -F32 Recording::getChurn(const Count& stat) -{ - return getIncrease(stat) + getDecrease(stat); -} - -F32 Recording::getChurnPerSec(const Count& stat) -{ - return getIncreasePerSec(stat) + getDecreasePerSec(stat); -} - - } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 4d53cd9600..d0c2e754f5 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -32,16 +32,17 @@ #include "llpointer.h" #include "lltimer.h" +#include "lltrace.h" namespace LLTrace { - template class Rate; - template class Measurement; - template class Count; - template class AccumulatorBuffer; - template class RateAccumulator; - template class MeasurementAccumulator; - class TimerAccumulator; + //template class Rate; + //template class Measurement; + //template class Count; + //template class AccumulatorBuffer; + //template class RateAccumulator; + //template class MeasurementAccumulator; + //class TimerAccumulator; class LL_COMMON_API Recording { @@ -51,43 +52,125 @@ namespace LLTrace ~Recording(); void makePrimary(); - bool isPrimary(); + bool isPrimary() const; void start(); void stop(); void resume(); - - void mergeSamples(const Recording& other); - void mergeDeltas(const Recording& baseline, const Recording& target); - void reset(); void update(); + bool isStarted() const { return mIsStarted; } - bool isStarted() { return mIsStarted; } + void addSamples(const Recording& other); + void addDeltas(const Recording& baseline, const Recording& target); // Rate accessors - F32 getSum(const Rate& stat); - F32 getPerSec(const Rate& stat); + template + typename Rate::base_unit_t getSum(const Rate& stat) const + { + return (typename Rate::base_unit_t)stat.getAccumulator(mRates).getSum(); + } + + template + typename Rate::base_unit_t getPerSec(const Rate& stat) const + { + return (typename Rate::base_unit_t)stat.getAccumulator(mRates).getSum() / mElapsedSeconds; + } // Measurement accessors - F32 getSum(const Measurement& stat); - F32 getPerSec(const Measurement& stat); - F32 getMin(const Measurement& stat); - F32 getMax(const Measurement& stat); - F32 getMean(const Measurement& stat); - F32 getStandardDeviation(const Measurement& stat); + template + typename Measurement::base_unit_t getSum(const Measurement& stat) const + { + return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getSum(); + + } + + template + typename Measurement::base_unit_t getPerSec(const Measurement& stat) const + { + return (typename Rate::base_unit_t)stat.getAccumulator(mMeasurements).getSum() / mElapsedSeconds; + } + + template + typename Measurement::base_unit_t getMin(const Measurement& stat) const + { + return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getMin(); + } + + template + typename Measurement::base_unit_t getMax(const Measurement& stat) const + { + return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getMax(); + } + + template + typename Measurement::base_unit_t getMean(const Measurement& stat) const + { + return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getMean(); + } + + template + typename Measurement::base_unit_t getStandardDeviation(const Measurement& stat) const + { + return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getStandardDeviation(); + } + + template + typename Measurement::base_unit_t getLastValue(const Measurement& stat) const + { + return (typename Measurement::base_unit_t)stat.getAccumulator(mMeasurements).getLastValue(); + } // Count accessors - F32 getSum(const Count& stat); - F32 getPerSec(const Count& stat); - F32 getIncrease(const Count& stat); - F32 getIncreasePerSec(const Count& stat); - F32 getDecrease(const Count& stat); - F32 getDecreasePerSec(const Count& stat); - F32 getChurn(const Count& stat); - F32 getChurnPerSec(const Count& stat); - - F64 getSampleTime() { return mElapsedSeconds; } + template + typename Count::base_unit_t getSum(const Count& stat) const + { + return getSum(stat.mTotal); + } + + template + typename Count::base_unit_t getPerSec(const Count& stat) const + { + return getPerSec(stat.mTotal); + } + + template + typename Count::base_unit_t getIncrease(const Count& stat) const + { + return getPerSec(stat.mTotal); + } + + template + typename Count::base_unit_t getIncreasePerSec(const Count& stat) const + { + return getPerSec(stat.mIncrease); + } + + template + typename Count::base_unit_t getDecrease(const Count& stat) const + { + return getPerSec(stat.mDecrease); + } + + template + typename Count::base_unit_t getDecreasePerSec(const Count& stat) const + { + return getPerSec(stat.mDecrease); + } + + template + typename Count::base_unit_t getChurn(const Count& stat) const + { + return getIncrease(stat) + getDecrease(stat); + } + + template + typename Count::base_unit_t getChurnPerSec(const Count& stat) const + { + return getIncreasePerSec(stat) + getDecreasePerSec(stat); + } + + F64 getSampleTime() const { return mElapsedSeconds; } private: friend class ThreadRecorder; 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); } /////////////////////////////////////////////////////////////////////// diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h index 9d78df7cae..4663070c42 100644 --- a/indra/llcommon/llunit.h +++ b/indra/llcommon/llunit.h @@ -30,21 +30,24 @@ #include "stdtypes.h" #include "llpreprocessor.h" -template -struct LLUnit : public BASE_UNIT +template +struct LLUnitType : public BASE_UNIT { - typedef LLUnit unit_t; + typedef DERIVED_UNIT unit_t; typedef typename BASE_UNIT::value_t value_t; typedef void is_unit_t; - LLUnit() + LLUnitType() {} - explicit LLUnit(value_t value) + explicit LLUnitType(value_t value) : BASE_UNIT(convertToBase(value)) {} - operator value_t() { return get(); } + operator unit_t& () + { + return static_cast(*this); + } value_t get() const { @@ -53,47 +56,72 @@ struct LLUnit : public BASE_UNIT static value_t convertToBase(value_t derived_value) { - return (value_t)((F32)derived_value * DERIVED_UNIT::conversionToBaseFactor()); + return (value_t)((F32)derived_value * unit_t::conversionToBaseFactor()); } static value_t convertToDerived(value_t base_value) { - return (value_t)((F32)base_value / DERIVED_UNIT::conversionToBaseFactor()); + return (value_t)((F32)base_value / unit_t::conversionToBaseFactor()); + } + + unit_t operator + (const unit_t other) const + { + return unit_t(mValue + other.mValue); + } + + unit_t operator - (const unit_t other) const + { + return unit_t(mValue - other.mValue); + } + + unit_t operator * (value_t multiplicand) const + { + return unit_t(mValue * multiplicand); + } + + unit_t operator / (value_t divisor) const + { + return unit_t(mValue / divisor); } }; -template -struct LLUnit +template +struct LLUnitType { - typedef LLUnit unit_t; - typedef T value_t; + typedef T unit_t; + typedef typename STORAGE_TYPE value_t; typedef void is_unit_t; - LLUnit() + LLUnitType() : mValue() {} - explicit LLUnit(T value) + explicit LLUnitType(value_t value) : mValue(value) {} - unit_t& operator=(T value) + unit_t& operator=(value_t value) { setBaseValue(value); return *this; } + operator unit_t& () + { + return static_cast(*this); + } + value_t get() { return mValue; } static value_t convertToBase(value_t derived_value) { - return (value_t)1; + return (value_t)derived_value; } static value_t convertToDerived(value_t base_value) { - return (value_t)1; + return (value_t)base_value; } unit_t operator + (const unit_t other) const @@ -137,68 +165,74 @@ struct LLUnit } protected: - void setBaseValue(T value) + void setBaseValue(value_t value) { mValue = value; } - T mValue; + value_t mValue; }; -#define LL_DECLARE_BASE_UNIT(unit_name) \ - template \ - struct unit_name : public LLUnit \ - { \ - unit_name(STORAGE_TYPE value) \ - : LLUnit(value) \ - {} \ - \ - unit_name() \ - {} \ - \ - template \ - unit_name(const LLUnit& other) \ - { \ - setBaseValue(other.unit_name::get()); \ - } \ - \ - using LLUnit::operator +; \ - using LLUnit::operator +=; \ - using LLUnit::operator -; \ - using LLUnit::operator -=; \ - using LLUnit::operator *; \ - using LLUnit::operator *=; \ - using LLUnit::operator /; \ - using LLUnit::operator /=; \ +#define LL_DECLARE_BASE_UNIT(unit_name) \ + template \ + struct unit_name : public LLUnitType > \ + { \ + typedef unit_name base_unit_t; \ + typedef STORAGE_TYPE storage_t; \ + \ + unit_name(STORAGE_TYPE value) \ + : LLUnitType(value) \ + {} \ + \ + unit_name() \ + {} \ + \ + template \ + unit_name(const LLUnitType& source) \ + { \ + setBaseValue(source.unit_t::get()); \ + } \ + \ + using LLUnitType::operator +; \ + using LLUnitType::operator +=; \ + using LLUnitType::operator -; \ + using LLUnitType::operator -=; \ + using LLUnitType::operator *; \ + using LLUnitType::operator *=; \ + using LLUnitType::operator /; \ + using LLUnitType::operator /=; \ }; -#define LL_DECLARE_DERIVED_UNIT(base_unit, derived_unit, conversion_factor) \ - template \ - struct derived_unit : public LLUnit, derived_unit > \ - { \ - derived_unit(value_t value) \ - : LLUnit(value) \ - {} \ - \ - derived_unit() \ - {} \ - \ - template \ - derived_unit(const LLUnit, T>& other) \ - { \ - setBaseValue(other.base_unit::get()); \ - } \ - \ - static F32 conversionToBaseFactor() { return (F32)(conversion_factor); } \ - \ - using LLUnit::operator +; \ - using LLUnit::operator +=; \ - using LLUnit::operator -; \ - using LLUnit::operator -=; \ - using LLUnit::operator *; \ - using LLUnit::operator *=; \ - using LLUnit::operator /; \ - using LLUnit::operator /=; \ +#define LL_DECLARE_DERIVED_UNIT(base_unit, derived_unit, conversion_factor) \ + template \ + struct derived_unit : public LLUnitType, derived_unit > \ + { \ + typedef base_unit base_unit_t; \ + typedef STORAGE_TYPE storage_t; \ + \ + derived_unit(value_t value) \ + : LLUnitType(value) \ + {} \ + \ + derived_unit() \ + {} \ + \ + template \ + derived_unit(const LLUnitType, SOURCE_TYPE>& source) \ + { \ + setBaseValue(source.base_unit_t::get()); \ + } \ + \ + static F32 conversionToBaseFactor() { return (F32)(conversion_factor); } \ + \ + using LLUnitType::operator +; \ + using LLUnitType::operator +=; \ + using LLUnitType::operator -; \ + using LLUnitType::operator -=; \ + using LLUnitType::operator *; \ + using LLUnitType::operator *=; \ + using LLUnitType::operator /; \ + using LLUnitType::operator /=; \ }; namespace LLUnits diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index bc9603804b..4cbf695059 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -37,6 +37,7 @@ #include "llstat.h" #include "lluictrlfactory.h" #include "lltracerecording.h" +#include "lltracethreadrecorder.h" /////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index aed9e4ec93..1d4527aaa3 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -36,6 +36,7 @@ #include "llgl.h" #include "llglheaders.h" #include "lltracerecording.h" +#include "lltracethreadrecorder.h" //#include "llviewercontrol.h" /////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index e7538d685d..2ce5f95b54 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2316,7 +2316,8 @@ S32 LLTextureFetch::update(F32 max_time_ms) if(mCurlGetRequest) { - gTextureList.sTextureBits += mCurlGetRequest->getTotalReceivedBits(); + LLStatViewer::TEXTURE_KBIT.add >(mCurlGetRequest->getTotalReceivedBits()); + //gTextureList.sTextureBits += mCurlGetRequest->getTotalReceivedBits(); } if(mFetchDebugger) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 85ea543838..79ed093382 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -4756,18 +4756,23 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) switch (stat_id) { case LL_SIM_STAT_TIME_DILATION: - LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value); + LLStatViewer::SIM_TIME_DILATION.sample(stat_value); + //LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value); break; case LL_SIM_STAT_FPS: - LLViewerStats::getInstance()->mSimFPS.addValue(stat_value); + LLStatViewer::SIM_FPS.sample(stat_value); + //LLViewerStats::getInstance()->mSimFPS.addValue(stat_value); break; case LL_SIM_STAT_PHYSFPS: - LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value); + LLStatViewer::SIM_PHYSICS_FPS.sample(stat_value); + //LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value); break; case LL_SIM_STAT_AGENTUPS: - LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value); + LLStatViewer::SIM_AGENT_UPS.sample(stat_value); + //LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value); break; case LL_SIM_STAT_FRAMEMS: + //LLStatViewer::SIM_.sample(stat_value); LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value); break; case LL_SIM_STAT_NETMS: diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 954fa24eaa..2737d24674 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -64,32 +64,32 @@ namespace LLStatViewer { -LLTrace::Rate FPS("fpsstat"), - PACKETS_IN("packetsinstat"), - PACKETS_LOST("packetsloststat"), - PACKETS_OUT("packetsoutstat"), - TEXTURE_PACKETS("texturepacketsstat"), - TRIANGLES_DRAWN("trianglesdrawnstat"), - CHAT_COUNT("chatcount"), - IM_COUNT("imcount"), - OBJECT_CREATE("objectcreate"), - OBJECT_REZ("objectrez"), - LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay"), - LOGIN_TIMEOUTS("logintimeouts"), - FAILED_DOWNLOADS("faileddownloads"), - LSL_SAVES("lslsaves"), - ANIMATION_UPLOADS("animationuploads"), - FLY("fly"), - TELEPORT("teleport"), - DELETE_OBJECT("deleteobject"), - SNAPSHOT("snapshot"), - UPLOAD_SOUND("uploadsound"), - UPLOAD_TEXTURE("uploadtexture"), - EDIT_TEXTURE("edittexture"), - KILLED("killed"), - FRAMETIME_DOUBLED("frametimedoubled"), - TEX_BAKES("texbakes"), - TEX_REBAKES("texrebakes"); +LLTrace::Rate FPS("fpsstat"), + PACKETS_IN("packetsinstat"), + PACKETS_LOST("packetsloststat"), + PACKETS_OUT("packetsoutstat"), + TEXTURE_PACKETS("texturepacketsstat"), + TRIANGLES_DRAWN("trianglesdrawnstat"), + CHAT_COUNT("chatcount", "Chat messages sent"), + IM_COUNT("imcount", "IMs sent"), + OBJECT_CREATE("objectcreate"), + OBJECT_REZ("objectrez", "Object rez count"), + LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"), + LOGIN_TIMEOUTS("logintimeouts", "Number of login attempts that timed out"), + FAILED_DOWNLOADS("faileddownloads", "Number of times LLAssetStorage::getAssetData() has failed"), + LSL_SAVES("lslsaves", "Number of times user has saved a script"), + ANIMATION_UPLOADS("animationuploads", "Animations uploaded"), + FLY("fly", "Fly count"), + TELEPORT("teleport", "Teleport count"), + DELETE_OBJECT("deleteobject", "Objects deleted"), + SNAPSHOT("snapshot", "Snapshots taken"), + UPLOAD_SOUND("uploadsound", "Sounds uploaded"), + UPLOAD_TEXTURE("uploadtexture", "Textures uploaded"), + EDIT_TEXTURE("edittexture", "Changes to textures on objects"), + KILLED("killed", "Number of times killed"), + FRAMETIME_DOUBLED("frametimedoubled", "Ratio of frames 2x longer than previous"), + TEX_BAKES("texbakes"), + TEX_REBAKES("texrebakes"); LLTrace::Rate > KBIT("kbitstat"), LAYERS_KBIT("layerskbitstat"), OBJECT_KBIT("objectkbitstat"), @@ -98,53 +98,54 @@ LLTrace::Rate > KBIT("kbitstat"), ACTUAL_IN_KBIT("actualinkbit"), ACTUAL_OUT_KBIT("actualoutkbit"); -LLTrace::Rate > AVATAR_EDIT_TIME("avataredittimr"), - TOOLBOX_TIME("toolboxtime"), - MOUSELOOK_TIME("mouselooktime"), - FPS_10_TIME("fps10time"), - FPS_8_TIME("fps8time"), - FPS_2_TIME("fps2time"), - SIM_20_FPS_TIME("sim20fpstime"), - SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime"), - LOSS_5_PERCENT_TIME("loss5percenttime"); - -LLTrace::Measurement SIM_TIME_DILATION("simtimedilation"), - SIM_FPS("simfps"), - SIM_PHYSICS_FPS("simphysicsfps"), - SIM_AGENT_UPS("simagentups"), - SIM_SCRIPT_EPS("simscripteps"), - SIM_SKIPPED_SILHOUETTE("simsimskippedsilhouettesteps"), - SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters"), - SIM_MAIN_AGENTS("simmainagents"), - SIM_CHILD_AGENTS("simchildagents"), - SIM_OBJECTS("simobjects"), - SIM_ACTIVE_OBJECTS("simactiveobjects"), - SIM_ACTIVE_SCRIPTS("simactivescripts"), - SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun"), - SIM_IN_PACKETS_PER_SEC("siminpps"), - SIM_OUT_PACKETS_PER_SEC("simoutpps"), - SIM_PENDING_DOWNLOADS("simpendingdownloads"), - SIM_PENDING_UPLOADS("simpendinguploads"), - SIM_PENING_LOCAL_UPLOADS("simpendinglocaluploads"), - SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks"), - SIM_PHYSICS_LOD_TASKS("physicslodtasks"), - NUM_IMAGES("numimagesstat"), - NUM_RAW_IMAGES("numrawimagesstat"), - NUM_OBJECTS("numobjectsstat"), - NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), - NUM_NEW_OBJECTS("numnewobjectsstat"), - NUM_SIZE_CULLED("numsizeculledstat"), - NUM_VIS_CULLED("numvisculledstat"), - ENABLE_VBO("enablevbo"), - DELTA_BANDWIDTH("deltabandwidth"), - MAX_BANDWIDTH("maxbandwidth"), - LIGHTING_DETAIL("lightingdetail"), - VISIBLE_AVATARS("visibleavatars"), - SHADER_OBJECTS("shaderobjects"), - DRAW_DISTANCE("drawdistance"), - CHAT_BUBBLES("chatbubbles"), - WINDOW_WIDTH("windowwidth"), - WINDOW_HEIGHT("windowheight"); +LLTrace::Rate > AVATAR_EDIT_TIME("avataredittime", "Seconds in Edit Appearence"), + TOOLBOX_TIME("toolboxtime", "Seconds using Toolbox"), + MOUSELOOK_TIME("mouselooktime", "Seconds in Mouselook"), + FPS_10_TIME("fps10time", "Seconds below 10 FPS"), + FPS_8_TIME("fps8time", "Seconds below 8 FPS"), + FPS_2_TIME("fps2time", "Seconds below 2 FPS"), + SIM_20_FPS_TIME("sim20fpstime", "Seconds with sim FPS below 20"), + SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"), + LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%"); + +LLTrace::Measurement SIM_TIME_DILATION("simtimedilation"), + SIM_FPS("simfps"), + SIM_PHYSICS_FPS("simphysicsfps"), + SIM_AGENT_UPS("simagentups"), + SIM_SCRIPT_EPS("simscripteps"), + SIM_SKIPPED_SILHOUETTE("simsimskippedsilhouettesteps"), + SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters"), + SIM_MAIN_AGENTS("simmainagents"), + SIM_CHILD_AGENTS("simchildagents"), + SIM_OBJECTS("simobjects"), + SIM_ACTIVE_OBJECTS("simactiveobjects"), + SIM_ACTIVE_SCRIPTS("simactivescripts"), + SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun"), + SIM_IN_PACKETS_PER_SEC("siminpps"), + SIM_OUT_PACKETS_PER_SEC("simoutpps"), + SIM_PENDING_DOWNLOADS("simpendingdownloads"), + SIM_PENDING_UPLOADS("simpendinguploads"), + SIM_PENDING_LOCAL_UPLOADS("simpendinglocaluploads"), + SIM_PENDING_VFS_OPERATIONS("vfspendingoperations"), + SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks"), + SIM_PHYSICS_LOD_TASKS("physicslodtasks"), + NUM_IMAGES("numimagesstat"), + NUM_RAW_IMAGES("numrawimagesstat"), + NUM_OBJECTS("numobjectsstat"), + NUM_ACTIVE_OBJECTS("numactiveobjectsstat"), + NUM_NEW_OBJECTS("numnewobjectsstat"), + NUM_SIZE_CULLED("numsizeculledstat"), + NUM_VIS_CULLED("numvisculledstat"), + ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"), + DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"), + MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"), + LIGHTING_DETAIL("lightingdetail", "Lighting Detail"), + VISIBLE_AVATARS("visibleavatars", "Visible Avatars"), + SHADER_OBJECTS("shaderobjects", "Object Shaders"), + DRAW_DISTANCE("drawdistance", "Draw Distance"), + CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"), + WINDOW_WIDTH("windowwidth", "Window width"), + WINDOW_HEIGHT("windowheight", "Window height"); LLTrace::Measurement > SIM_UNACKED_BYTES("simtotalunackedbytes"), SIM_PHYSICS_MEM("physicsmemoryallocated"), @@ -166,14 +167,16 @@ LLTrace::Measurement > SIM_PHYSICS_TIME("simsimphysicsmsec SIM_SLEEP_TIME("simsleepmsec"), SIM_PUMP_IO_TIME("simpumpiomsec"), SIM_PING("simpingstat"), - LOGIN_SECONDS("loginseconds"), - REGION_CROSSING_TIME("regioncrossingtime"), - FRAME_STACKTIME("framestacktime"), - UPDATE_STACKTIME("updatestacktime"), - NETWORK_STACKTIME("networkstacktime"), - IMAGE_STACKTIME("imagestacktime"), - REBUILD_STACKTIME("rebuildstacktime"), - RENDER_STACKTIME("renderstacktime"); + FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), + FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"), + LOGIN_SECONDS("loginseconds", "Time between LoginRequest and LoginReply"), + REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"), + FRAME_STACKTIME("framestacktime", "FRAME_SECS"), + UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"), + NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"), + IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"), + REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"), + RENDER_STACKTIME("renderstacktime", "RENDER_SECS"); } class StatAttributes @@ -190,139 +193,18 @@ public: BOOL mEnabled; }; -const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] = -{ - // ST_VERSION - StatAttributes("Version", TRUE), - // ST_AVATAR_EDIT_SECONDS - StatAttributes("Seconds in Edit Appearence", FALSE), - // ST_TOOLBOX_SECONDS - StatAttributes("Seconds using Toolbox", FALSE), - // ST_CHAT_COUNT - StatAttributes("Chat messages sent", FALSE), - // ST_IM_COUNT - StatAttributes("IMs sent", FALSE), - // ST_FULLSCREEN_BOOL - StatAttributes("Fullscreen mode", FALSE), - // ST_RELEASE_COUNT - StatAttributes("Object release count", FALSE), - // ST_CREATE_COUNT - StatAttributes("Object create count", FALSE), - // ST_REZ_COUNT - StatAttributes("Object rez count", FALSE), - // ST_FPS_10_SECONDS - StatAttributes("Seconds below 10 FPS", FALSE), - // ST_FPS_2_SECONDS - StatAttributes("Seconds below 2 FPS", FALSE), - // ST_MOUSELOOK_SECONDS - StatAttributes("Seconds in Mouselook", FALSE), - // ST_FLY_COUNT - StatAttributes("Fly count", FALSE), - // ST_TELEPORT_COUNT - StatAttributes("Teleport count", FALSE), - // ST_OBJECT_DELETE_COUNT - StatAttributes("Objects deleted", FALSE), - // ST_SNAPSHOT_COUNT - StatAttributes("Snapshots taken", FALSE), - // ST_UPLOAD_SOUND_COUNT - StatAttributes("Sounds uploaded", FALSE), - // ST_UPLOAD_TEXTURE_COUNT - StatAttributes("Textures uploaded", FALSE), - // ST_EDIT_TEXTURE_COUNT - StatAttributes("Changes to textures on objects", FALSE), - // ST_KILLED_COUNT - StatAttributes("Number of times killed", FALSE), - // ST_FRAMETIME_JITTER - StatAttributes("Average delta between successive frame times", FALSE), - // ST_FRAMETIME_SLEW - StatAttributes("Average delta between frame time and mean", FALSE), - // ST_INVENTORY_TOO_LONG - StatAttributes("Inventory took too long to load", FALSE), - // ST_WEARABLES_TOO_LONG - StatAttributes("Wearables took too long to load", FALSE), - // ST_LOGIN_SECONDS - StatAttributes("Time between LoginRequest and LoginReply", FALSE), - // ST_LOGIN_TIMEOUT_COUNT - StatAttributes("Number of login attempts that timed out", FALSE), - // ST_HAS_BAD_TIMER - StatAttributes("Known bad timer if != 0.0", FALSE), - // ST_DOWNLOAD_FAILED - StatAttributes("Number of times LLAssetStorage::getAssetData() has failed", FALSE), - // ST_LSL_SAVE_COUNT - StatAttributes("Number of times user has saved a script", FALSE), - // ST_UPLOAD_ANIM_COUNT - StatAttributes("Animations uploaded", FALSE), - // ST_FPS_8_SECONDS - StatAttributes("Seconds below 8 FPS", FALSE), - // ST_SIM_FPS_20_SECONDS - StatAttributes("Seconds with sim FPS below 20", FALSE), - // ST_PHYS_FPS_20_SECONDS - StatAttributes("Seconds with physics FPS below 20", FALSE), - // ST_LOSS_05_SECONDS - StatAttributes("Seconds with packet loss > 5%", FALSE), - // ST_FPS_DROP_50_RATIO - StatAttributes("Ratio of frames 2x longer than previous", FALSE), - // ST_ENABLE_VBO - StatAttributes("Vertex Buffers Enabled", TRUE), - // ST_DELTA_BANDWIDTH - StatAttributes("Increase/Decrease in bandwidth based on packet loss", FALSE), - // ST_MAX_BANDWIDTH - StatAttributes("Max bandwidth setting", FALSE), - // ST_LIGHTING_DETAIL - StatAttributes("Lighting Detail", FALSE), - // ST_VISIBLE_AVATARS - StatAttributes("Visible Avatars", FALSE), - // ST_SHADER_OJECTS - StatAttributes("Object Shaders", FALSE), - // ST_SHADER_ENVIRONMENT - StatAttributes("Environment Shaders", FALSE), - // ST_VISIBLE_DRAW_DIST - StatAttributes("Draw Distance", FALSE), - // ST_VISIBLE_CHAT_BUBBLES - StatAttributes("Chat Bubbles Enabled", FALSE), - // ST_SHADER_AVATAR - StatAttributes("Avatar Shaders", FALSE), - // ST_FRAME_SECS - StatAttributes("FRAME_SECS", FALSE), - // ST_UPDATE_SECS - StatAttributes("UPDATE_SECS", FALSE), - // ST_NETWORK_SECS - StatAttributes("NETWORK_SECS", FALSE), - // ST_IMAGE_SECS - StatAttributes("IMAGE_SECS", FALSE), - // ST_REBUILD_SECS - StatAttributes("REBUILD_SECS", FALSE), - // ST_RENDER_SECS - StatAttributes("RENDER_SECS", FALSE), - // ST_CROSSING_AVG - StatAttributes("CROSSING_AVG", FALSE), - // ST_CROSSING_MAX - StatAttributes("CROSSING_MAX", FALSE), - // ST_LIBXUL_WIDGET_USED - StatAttributes("LibXUL Widget used", FALSE), // Unused - // ST_WINDOW_WIDTH - StatAttributes("Window width", FALSE), - // ST_WINDOW_HEIGHT - StatAttributes("Window height", FALSE), - // ST_TEX_BAKES - StatAttributes("Texture Bakes", FALSE), - // ST_TEX_REBAKES - StatAttributes("Texture Rebakes", FALSE) - -}; - LLViewerStats::LLViewerStats() : - mVFSPendingOperations("vfspendingoperations"), - mFPSStat("fpsstat"), - mPacketsInStat("packetsinstat"), - mPacketsLostStat("packetsloststat"), - mPacketsOutStat("packetsoutstat"), - mPacketsLostPercentStat("packetslostpercentstat"), - mTexturePacketsStat("texturepacketsstat"), - mActualInKBitStat("actualinkbitstat"), - mActualOutKBitStat("actualoutkbitstat"), - mTrianglesDrawnStat("trianglesdrawnstat"), - mSimTimeDilation("simtimedilation"), + //mVFSPendingOperations("vfspendingoperations"), + //mFPSStat("fpsstat"), + //mPacketsInStat("packetsinstat"), + //mPacketsLostStat("packetsloststat"), + //mPacketsOutStat("packetsoutstat"), + //mPacketsLostPercentStat("packetslostpercentstat"), + //mTexturePacketsStat("texturepacketsstat"), + //mActualInKBitStat("actualinkbitstat"), + //mActualOutKBitStat("actualoutkbitstat"), + //mTrianglesDrawnStat("trianglesdrawnstat"), + //mSimTimeDilation("simtimedilation"), mSimFPS("simfps"), mSimPhysicsFPS("simphysicsfps"), mSimAgentUPS("simagentups"), @@ -393,13 +275,14 @@ LLViewerStats::~LLViewerStats() void LLViewerStats::resetStats() { LLViewerStats& stats = LLViewerStats::instance(); - stats.mVFSPendingOperations.reset(); - stats.mPacketsInStat.reset(); - stats.mPacketsLostStat.reset(); - stats.mPacketsOutStat.reset(); - stats.mFPSStat.reset(); - stats.mTexturePacketsStat.reset(); - stats.mAgentPositionSnaps.reset(); + stats.mRecording.reset(); + //stats.mVFSPendingOperations.reset(); + //stats.mPacketsInStat.reset(); + //stats.mPacketsLostStat.reset(); + //stats.mPacketsOutStat.reset(); + //stats.mFPSStat.reset(); + //stats.mTexturePacketsStat.reset(); + //stats.mAgentPositionSnaps.reset(); } @@ -484,16 +367,9 @@ void LLViewerStats::addToMessage(LLSD &body) const { LLSD &misc = body["misc"]; - for (S32 i = 0; i < ST_COUNT; i++) - { - if (STAT_INFO[i].mEnabled) - { - // TODO: send timer value so dataserver can normalize - misc[STAT_INFO[i].mName] = mStats[i]; - llinfos << "STAT: " << STAT_INFO[i].mName << ": " << mStats[i] - << llendl; - } - } + misc["Version"] = TRUE; + //TODO RN: get last value, not mean + misc["Vertex Buffers Enabled"] = mRecording.getMean(LLStatViewer::ENABLE_VBO); body["AgentPositionSnaps"] = mAgentPositionSnaps.asLLSD(); llinfos << "STAT: AgentPositionSnaps: Mean = " << mAgentPositionSnaps.getMean() << "; StdDev = " << mAgentPositionSnaps.getStdDev() @@ -570,13 +446,15 @@ void update_statistics() stats.mSimPingStat.addValue(10000); } - stats.mFPSStat.addValue(1); + //stats.mFPSStat.addValue(1); + LLStatViewer::FPS.add(1); F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); LLStatViewer::LAYERS_KBIT.add >(layer_bits); //stats.mLayersKBitStat.addValue(layer_bits/1024.f); LLStatViewer::OBJECT_KBIT.add >(gObjectBits); //stats.mObjectKBitStat.addValue(gObjectBits/1024.f); - stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); + //stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); + LLStatViewer::SIM_PENDING_VFS_OPERATIONS.sample(LLVFile::getVFSThread()->getPending()); LLStatViewer::ASSET_KBIT.add >(gTransferManager.getTransferBitsIn(LLTCT_ASSET)); //stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); @@ -615,12 +493,7 @@ void update_statistics() static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { - LLStatViewer::TEXTURE_KBIT.add >(LLViewerTextureList::sTextureBits); - //stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); - stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); - gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8; - LLViewerTextureList::sTextureBits = 0; - LLViewerTextureList::sTexturePackets = 0; + gTotalTextureBytes = LLUnits::Bytes(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT)).get();//LLViewerTextureList::sTextureBits / 8; texture_stats_timer.reset(); } } diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index af2e915994..a14518f536 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -1,5 +1,5 @@ /** - * @file llviewerstats.h + * @file llviewerim_peningtats.h * @brief LLViewerStats class header file * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ @@ -97,7 +97,8 @@ extern LLTrace::Measurement SIM_TIME_DILATION, SIM_OUT_PACKETS_PER_SEC, SIM_PENDING_DOWNLOADS, SIM_PENDING_UPLOADS, - SIM_PENING_LOCAL_UPLOADS, + SIM_PENDING_LOCAL_UPLOADS, + SIM_PENDING_VFS_OPERATIONS, SIM_PHYSICS_PINNED_TASKS, SIM_PHYSICS_LOD_TASKS, NUM_IMAGES, @@ -138,6 +139,8 @@ extern LLTrace::Measurement > SIM_PHYSICS_TIME, SIM_SLEEP_TIME, SIM_PUMP_IO_TIME, SIM_PING, + FRAMETIME_JITTER, + FRAMETIME_SLEW, LOGIN_SECONDS, REGION_CROSSING_TIME, FRAME_STACKTIME, @@ -409,10 +412,12 @@ public: }; LLTrace::Recording& getRecording() { return mRecording; } + LLTrace::Recording& getFrameRecording() { return mFrameRecording; } private: F64 mStats[ST_COUNT]; LLTrace::Recording mRecording; + LLTrace::Recording mFrameRecording; F64 mLastTimeDiff; // used for time stat updates }; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index de3dd3c1c6..b22c0c797e 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -58,14 +58,13 @@ #include "pipeline.h" #include "llappviewer.h" #include "llxuiparser.h" +#include "lltracethreadrecorder.h" #include "llviewerdisplay.h" //////////////////////////////////////////////////////////////////////////// void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; -U32 LLViewerTextureList::sTextureBits = 0; -U32 LLViewerTextureList::sTexturePackets = 0; S32 LLViewerTextureList::sNumImages = 0; LLStat LLViewerTextureList::sNumImagesStat("Num Images", TRUE); LLStat LLViewerTextureList::sNumRawImagesStat("Num Raw Images", TRUE); @@ -624,7 +623,7 @@ void LLViewerTextureList::updateImages(F32 max_time) LLTrace::Recording* recording = LLTrace::get_thread_recorder()->getPrimaryRecording(); - LLAppViewer::getTextureFetch()->setTextureBandwidth(recording->getPerSec(LLStatViewer::TEXTURE_KBIT)); + LLAppViewer::getTextureFetch()->setTextureBandwidth(recording->getPerSec(LLStatViewer::TEXTURE_KBIT).get()); LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages); LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); @@ -1326,8 +1325,8 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d { received_size = msg->getReceiveSize() ; } - gTextureList.sTextureBits += received_size * 8; - gTextureList.sTexturePackets++; + LLStatViewer::TEXTURE_KBIT.add >(received_size); + LLStatViewer::TEXTURE_PACKETS.add(1); U8 codec; U16 packets; @@ -1399,8 +1398,9 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d { received_size = msg->getReceiveSize() ; } - gTextureList.sTextureBits += received_size * 8; - gTextureList.sTexturePackets++; + + LLStatViewer::TEXTURE_KBIT.add >(received_size); + LLStatViewer::TEXTURE_PACKETS.add(1); //llprintline("Start decode, image header..."); msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 3dda973d3f..ab6f009e28 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -201,9 +201,6 @@ private: LLFrameTimer mForceDecodeTimer; public: - static U32 sTextureBits; - static U32 sTexturePackets; - static LLStat sNumImagesStat; static LLStat sNumRawImagesStat; static LLStat sGLTexMemStat; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8b50e56fb3..4ad7c49d4b 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1402,10 +1402,11 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255))); std::string temp_str; + LLTrace::Recording& recording = LLViewerStats::instance().getRecording(); temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */ - LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(), - LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0), - LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0)); + recording.getPerSec(LLStatViewer::FPS), //mFPSStat.getMeanPerSec(), + recording.getMean(LLStatViewer::SIM_PHYSICS_FPS), //LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0), + recording.getMean(LLStatViewer::SIM_TIME_DILATION)); //LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0)); S32 len = temp_str.length(); TextOutA(hdc, 0, 0, temp_str.c_str(), len); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index bf2a58f107..056132c165 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -703,21 +703,26 @@ void LLWorld::updateNetStats() S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits(); S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits(); - LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f); - LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f); + LLStatViewer::ACTUAL_IN_KBIT.add >(actual_in_bits); + LLStatViewer::ACTUAL_OUT_KBIT.add >(actual_out_bits); + //LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f); + //LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f); LLStatViewer::KBIT.add >(bits); //LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f); - LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in); - LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out); - LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets); - if (packets_in) - { - LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in)); - } - else - { - LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f); - } + LLStatViewer::PACKETS_IN.add(packets_in); + LLStatViewer::PACKETS_OUT.add(packets_out); + LLStatViewer::PACKETS_LOST.add(packets_lost); + //LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in); + //LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out); + //LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets); + //if (packets_in) + //{ + // LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in)); + //} + //else + //{ + // LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f); + //} mLastPacketsIn = gMessageSystem->mPacketsIn; mLastPacketsOut = gMessageSystem->mPacketsOut; @@ -1129,6 +1134,7 @@ void send_agent_pause() } gObjectList.mWasPaused = TRUE; + LLViewerStats::instance().getRecording().stop(); } @@ -1158,8 +1164,8 @@ void send_agent_resume() gMessageSystem->sendReliable(regionp->getHost()); } - // Reset the FPS counter to avoid an invalid fps - LLViewerStats::getInstance()->mFPSStat.reset(); + // Resume data collection to ignore invalid rates + LLViewerStats::instance().getRecording().resume();//getInstance()->mFPSStat.reset(); LLAppViewer::instance()->resumeMainloopTimeout(); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 86791a37fb..4582de805f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -488,7 +488,7 @@ void LLPipeline::init() getPool(LLDrawPool::POOL_BUMP); getPool(LLDrawPool::POOL_GLOW); - LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); + //LLViewerStats::getInstance()->mTrianglesDrawnStat.reset(); resetFrameStats(); for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) @@ -1768,7 +1768,8 @@ void LLPipeline::resetFrameStats() { assertInitialized(); - LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); + LLStatViewer::TRIANGLES_DRAWN.add(mTrianglesDrawn); + //LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f); if (mBatchCount > 0) { -- cgit v1.3 From 5d51175cd79b15cf036cd7e6bd646a1a0777eb7f Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 20 Nov 2012 15:55:04 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system fixes to merge --- indra/llcommon/llmemory.h | 2 +- indra/llcommon/llmutex.cpp | 49 +------------ indra/llcommon/llmutex.h | 67 ----------------- indra/llcommon/llthread.cpp | 153 +-------------------------------------- indra/llcommon/llthread.h | 2 +- indra/llcommon/llunit.h | 40 +++++----- indra/llmath/llvolume.cpp | 4 + indra/newview/gpu_table.txt | 10 --- indra/newview/lltexturefetch.cpp | 12 +-- indra/newview/lltexturefetch.h | 2 +- indra/newview/lltextureview.cpp | 4 +- 11 files changed, 42 insertions(+), 303 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 3744e68956..e725bdd9fa 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -26,7 +26,7 @@ #ifndef LLMEMORY_H #define LLMEMORY_H -#include "llmemtype.h" +#include "linden_common.h" class LLMutex ; diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp index 2ce14b3a2e..e6beb9e680 100644 --- a/indra/llcommon/llmutex.cpp +++ b/indra/llcommon/llmutex.cpp @@ -86,7 +86,7 @@ void LLMutex::lock() #if LL_DARWIN mLockingThread = LLThread::currentID(); #else - mLockingThread = LLThread::sThreadIndex; + mLockingThread = LLThread::sThreadID; #endif } @@ -129,7 +129,7 @@ bool LLMutex::isSelfLocked() #if LL_DARWIN return mLockingThread == LLThread::currentID(); #else - return mLockingThread == LLThread::sThreadIndex; + return mLockingThread == LLThread::sThreadID; #endif } @@ -181,49 +181,4 @@ void LLCondition::broadcast() } -//============================================================================ - -//---------------------------------------------------------------------------- - -//static -LLMutex* LLThreadSafeRefCount::sMutex = 0; - -//static -void LLThreadSafeRefCount::initThreadSafeRefCount() -{ - if (!sMutex) - { - sMutex = new LLMutex(0); - } -} - -//static -void LLThreadSafeRefCount::cleanupThreadSafeRefCount() -{ - delete sMutex; - sMutex = NULL; -} - - -//---------------------------------------------------------------------------- - -LLThreadSafeRefCount::LLThreadSafeRefCount() : -mRef(0) -{ -} - -LLThreadSafeRefCount::~LLThreadSafeRefCount() -{ - if (mRef != 0) - { - llerrs << "deleting non-zero reference" << llendl; - } -} - -//============================================================================ - -LLResponder::~LLResponder() -{ -} - //============================================================================ diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index bd0a59b577..cbde4c47a9 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -98,71 +98,4 @@ private: LLMutex* mMutex; }; - -//============================================================================ - -// see llmemory.h for LLPointer<> definition - -class LL_COMMON_API LLThreadSafeRefCount -{ -public: - static void initThreadSafeRefCount(); // creates sMutex - static void cleanupThreadSafeRefCount(); // destroys sMutex - -private: - static LLMutex* sMutex; - -private: - LLThreadSafeRefCount(const LLThreadSafeRefCount&); // not implemented - LLThreadSafeRefCount&operator=(const LLThreadSafeRefCount&); // not implemented - -protected: - virtual ~LLThreadSafeRefCount(); // use unref() - -public: - LLThreadSafeRefCount(); - - void ref() - { - if (sMutex) sMutex->lock(); - mRef++; - if (sMutex) sMutex->unlock(); - } - - S32 unref() - { - llassert(mRef >= 1); - if (sMutex) sMutex->lock(); - S32 res = --mRef; - if (sMutex) sMutex->unlock(); - if (0 == res) - { - delete this; - return 0; - } - return res; - } - S32 getNumRefs() const - { - return mRef; - } - -private: - S32 mRef; -}; - - -//============================================================================ - -// Simple responder for self destructing callbacks -// Pure virtual class -class LL_COMMON_API LLResponder : public LLThreadSafeRefCount -{ -protected: - virtual ~LLResponder(); -public: - virtual void completed(bool success) = 0; -}; - - #endif // LL_LLTHREAD_H diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 1c86eb4f06..8ce739bf23 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -62,7 +62,7 @@ #if LL_DARWIN // statically allocated thread local storage not supported in Darwin executable formats #elif LL_WINDOWS -U32 __declspec(thread) LLThread::sThreadIndex = 0; +U32 __declspec(thread) LLThread::sThreadID = 0; #elif LL_LINUX U32 __thread LLThread::sThreadID = 0; #endif @@ -96,7 +96,7 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap LLTrace::ThreadRecorder* thread_recorder = new LLTrace::SlaveThreadRecorder(); #if !LL_DARWIN - sThreadIndex = threadp->mID; + sThreadID = threadp->mID; #endif // Run the user supplied function @@ -327,155 +327,6 @@ void LLThread::wakeLocked() //============================================================================ -LLMutex::LLMutex(apr_pool_t *poolp) : - mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD) -{ - //if (poolp) - //{ - // mIsLocalPool = FALSE; - // mAPRPoolp = poolp; - //} - //else - { - mIsLocalPool = TRUE; - apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread - } - apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); -} - - -LLMutex::~LLMutex() -{ -#if MUTEX_DEBUG - //bad assertion, the subclass LLSignal might be "locked", and that's OK - //llassert_always(!isLocked()); // better not be locked! -#endif - apr_thread_mutex_destroy(mAPRMutexp); - mAPRMutexp = NULL; - if (mIsLocalPool) - { - apr_pool_destroy(mAPRPoolp); - } -} - - -void LLMutex::lock() -{ - if(isSelfLocked()) - { //redundant lock - mCount++; - return; - } - - apr_thread_mutex_lock(mAPRMutexp); - -#if MUTEX_DEBUG - // Have to have the lock before we can access the debug info - U32 id = LLThread::currentID(); - if (mIsLocked[id] != FALSE) - llerrs << "Already locked in Thread: " << id << llendl; - mIsLocked[id] = TRUE; -#endif - -#if LL_DARWIN - mLockingThread = LLThread::currentID(); -#else - mLockingThread = sThreadID; -#endif -} - -void LLMutex::unlock() -{ - if (mCount > 0) - { //not the root unlock - mCount--; - return; - } - -#if MUTEX_DEBUG - // Access the debug info while we have the lock - U32 id = LLThread::currentID(); - if (mIsLocked[id] != TRUE) - llerrs << "Not locked in Thread: " << id << llendl; - mIsLocked[id] = FALSE; -#endif - - mLockingThread = NO_THREAD; - apr_thread_mutex_unlock(mAPRMutexp); -} - -bool LLMutex::isLocked() -{ - apr_status_t status = apr_thread_mutex_trylock(mAPRMutexp); - if (APR_STATUS_IS_EBUSY(status)) - { - return true; - } - else - { - apr_thread_mutex_unlock(mAPRMutexp); - return false; - } -} - -bool LLMutex::isSelfLocked() -{ -#if LL_DARWIN - return mLockingThread == LLThread::currentID(); -#else - return mLockingThread == sThreadID; -#endif -} - -U32 LLMutex::lockingThread() const -{ - return mLockingThread; -} - -//============================================================================ - -LLCondition::LLCondition(apr_pool_t *poolp) : - LLMutex(poolp) -{ - // base class (LLMutex) has already ensured that mAPRPoolp is set up. - - apr_thread_cond_create(&mAPRCondp, mAPRPoolp); -} - - -LLCondition::~LLCondition() -{ - apr_thread_cond_destroy(mAPRCondp); - mAPRCondp = NULL; -} - - -void LLCondition::wait() -{ - if (!isLocked()) - { //mAPRMutexp MUST be locked before calling apr_thread_cond_wait - apr_thread_mutex_lock(mAPRMutexp); -#if MUTEX_DEBUG - // avoid asserts on destruction in non-release builds - U32 id = LLThread::currentID(); - mIsLocked[id] = TRUE; -#endif - } - apr_thread_cond_wait(mAPRCondp, mAPRMutexp); -} - -void LLCondition::signal() -{ - apr_thread_cond_signal(mAPRCondp); -} - -void LLCondition::broadcast() -{ - apr_thread_cond_broadcast(mAPRCondp); -} - -//============================================================================ - //---------------------------------------------------------------------------- //static diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 94b6b6d682..75222c83f9 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -42,7 +42,7 @@ private: #if LL_DARWIN // statically allocated thread local storage not supported in Darwin executable formats #elif LL_WINDOWS - static U32 __declspec(thread) LLThread::sThreadIndex; + static U32 __declspec(thread) LLThread::sThreadID; #elif LL_LINUX static U32 __thread LLThread::sThreadID ; #endif diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h index 1fe492fdce..53570779fc 100644 --- a/indra/llcommon/llunit.h +++ b/indra/llcommon/llunit.h @@ -109,9 +109,9 @@ struct LLUnit return mValue; } - template LLUnit as() + template LLUnit as() { - return LLUnit(*this); + return LLUnit(*this); } void operator += (storage_t value) @@ -332,21 +332,27 @@ struct HighestPrecisionType > typedef typename HighestPrecisionType::type_t type_t; }; -#define LL_DECLARE_DERIVED_UNIT(base_unit_name, unit_name, conversion_factor) \ -struct unit_name \ -{ \ - typedef base_unit_name base_unit_t; \ -}; \ -template \ -struct ConversionFactor \ -{ \ - static typename HighestPrecisionType::type_t get() { return typename HighestPrecisionType::type_t(conversion_factor); } \ -}; \ - \ -template \ -struct ConversionFactor \ -{ \ - static typename HighestPrecisionType::type_t get() { return typename HighestPrecisionType::type_t(1.0 / (conversion_factor)); } \ +#define LL_DECLARE_DERIVED_UNIT(base_unit_name, unit_name, conversion_factor) \ +struct unit_name \ +{ \ + typedef base_unit_name base_unit_t; \ +}; \ +template \ +struct ConversionFactor \ +{ \ + static typename HighestPrecisionType::type_t get() \ + { \ + return typename HighestPrecisionType::type_t(conversion_factor); \ + } \ +}; \ + \ +template \ +struct ConversionFactor \ +{ \ + static typename HighestPrecisionType::type_t get() \ + { \ + return typename HighestPrecisionType::type_t(1.0 / (conversion_factor)); \ + } \ } struct Bytes { typedef Bytes base_unit_t; }; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 02c8d2b86f..54b67832ea 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6667,6 +6667,10 @@ void LLVolumeFace::resizeVertices(S32 num_verts) mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); ll_assert_aligned(mPositions, 16); mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); + if ( ((int)mNormals & 0xF) != 0 ) + { + __debugbreak(); + } ll_assert_aligned(mNormals, 16); //pad texture coordinate block end to allow for QWORD reads diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index 2a07b5ed70..5e8189caa5 100644 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -371,17 +371,10 @@ NVIDIA GTX 690M .*NVIDIA .*GTX *69*M.* 5 1 0 0 NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2 NVIDIA GT 120 .*NVIDIA .*GT *12.* 2 1 0 0 NVIDIA GT 130 .*NVIDIA .*GT *13.* 2 1 0 0 -NVIDIA GT 140 .*NVIDIA .*GT *140.* 2 1 0 0 -NVIDIA GT 150 .*NVIDIA .*GT *150.* 2 1 0 0 -NVIDIA GT 160 .*NVIDIA .*GT *160.* 2 1 0 0 NVIDIA GTS 150 .*NVIDIA .*GTS *15.* 2 1 0 0 NVIDIA 205 .*NVIDIA .*GeForce 205.* 2 1 1 3.3 NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3 NVIDIA GT 220 .*NVIDIA .*GT *22.* 2 1 1 3.3 -NVIDIA GT 230 .*NVIDIA .*GT *230.* 2 1 1 3.3 -NVIDIA GT 240 .*NVIDIA .*GT *240.* 2 1 1 3.3 -NVIDIA GT 250 .*NVIDIA .*GT *250.* 2 1 1 3.3 -NVIDIA GT 260 .*NVIDIA .*GT *260.* 2 1 1 3.3 NVIDIA GTS 240 .*NVIDIA .*GTS *24.* 4 1 1 3.3 NVIDIA GTS 250 .*NVIDIA .*GTS *25.* 4 1 1 3.3 NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 4 1 1 3.3 @@ -394,11 +387,9 @@ NVIDIA GT 320 .*NVIDIA .*GT *32.* 3 1 0 0 NVIDIA GT 330 .*NVIDIA .*GT *33.* 3 1 0 0 NVIDIA GT 340 .*NVIDIA .*GT *34.* 3 1 0 0 NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 0 -NVIDIA GT 415 .*NVIDIA .*GT *415.* 3 1 1 4.2 NVIDIA GT 420 .*NVIDIA .*GT *42.* 3 1 1 4.2 NVIDIA GT 430 .*NVIDIA .*GT *43.* 3 1 1 4.1 NVIDIA GT 440 .*NVIDIA .*GT *44.* 4 1 0 0 -NVIDIA GT 450 .*NVIDIA .*GT *45.* 4 1 0 0 NVIDIA GTS 450 .*NVIDIA .*GTS *45.* 4 1 1 4.2 NVIDIA GTX 460 .*NVIDIA .*GTX *46.* 5 1 1 4.2 NVIDIA GTX 470 .*NVIDIA .*GTX *47.* 5 1 1 4.2 @@ -407,7 +398,6 @@ NVIDIA 510 .*NVIDIA .* 510.* 3 1 0 0 NVIDIA GT 520 .*NVIDIA .*GT *52.* 3 1 1 4.2 NVIDIA GT 530 .*NVIDIA .*GT *53.* 3 1 1 4.2 NVIDIA GT 540 .*NVIDIA .*GT *54.* 3 1 1 4.2 -NVIDIA GT 550 .*NVIDIA .*GT *55.* 3 1 1 4.2 NVIDIA GTX 550 .*NVIDIA .*GTX *55.* 5 1 1 4.2 NVIDIA GTX 560 .*NVIDIA .*GTX *56.* 5 1 1 4.2 NVIDIA GTX 570 .*NVIDIA .*GTX *57.* 5 1 1 4.2 diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 885292131f..9f1c7855be 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2280,7 +2280,7 @@ void LLTextureFetchWorker::recordTextureStart(bool is_http) { mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp(); } - LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, + LLViewerAssetStatsFF::record_enqueue(LLViewerAssetType::AT_TEXTURE, is_http, LLImageBase::TYPE_AVATAR_BAKE == mType); } @@ -2291,13 +2291,13 @@ void LLTextureFetchWorker::recordTextureDone(bool is_http) { if (mMetricsStartTime) { - LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE, + LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_TEXTURE, is_http, LLImageBase::TYPE_AVATAR_BAKE == mType, LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime); mMetricsStartTime = 0; } - LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE, + LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE, is_http, LLImageBase::TYPE_AVATAR_BAKE == mType); } @@ -2826,9 +2826,9 @@ S32 LLTextureFetch::update(F32 max_time_ms) { mNetworkQueueMutex.lock(); // +Mfnq - mMaxBandwidth = band_width ; + mMaxBandwidth = band_width ; - gTextureList.sTextureBits += mHTTPTextureBits; + LLStatViewer::TEXTURE_KBIT.add(mHTTPTextureBits); mHTTPTextureBits = 0; mNetworkQueueMutex.unlock(); // -Mfnq @@ -3702,7 +3702,7 @@ AssetReportHandler stats_handler; bool TFReqSetRegion::doWork(LLTextureFetch *) { - LLViewerAssetStatsFF::set_region_thread1(mRegionHandle); + LLViewerAssetStatsFF::set_region(mRegionHandle); return true; } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 90d0c7e04b..2c1e7502e5 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -329,7 +329,7 @@ private: LLTextureInfo mTextureInfo; // XXX possible delete - U32 mHTTPTextureBits; // Mfnq + LLUnit mHTTPTextureBits; // Mfnq // XXX possible delete //debug use diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 5331bb03cb..1d54e50bb9 100755 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -514,8 +514,8 @@ void LLGLTexMemBar::draw() F32 cache_max_usage = (F32)LLTrace::Megabytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ; S32 line_height = LLFontGL::getFontMonospace()->getLineHeight(); S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f); - F32 total_texture_downloaded = (F32)gTotalTextureBytes / (1024 * 1024); - F32 total_object_downloaded = (F32)gTotalObjectBytes / (1024 * 1024); + LLUnit total_texture_downloaded = gTotalTextureData; + LLUnit total_object_downloaded = gTotalObjectData; U32 total_http_requests = LLAppViewer::getTextureFetch()->getTotalNumHTTPRequests() ; //---------------------------------------------------------------------------- LLGLSUIDefault gls_ui; -- cgit v1.3 From 68967e7b2b9416ff66cb49ae755fb33d7b81d129 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 5 Dec 2012 14:22:18 -0800 Subject: SH-3406 WIP convert fast timers to lltrace system changed thread id declaration to be local to llthread.cpp and use currentID() uniformly across platforms --- indra/llcommon/llmutex.cpp | 8 -------- indra/llcommon/llthread.cpp | 10 ++++++++-- indra/llcommon/llthread.h | 7 ------- 3 files changed, 8 insertions(+), 17 deletions(-) (limited to 'indra/llcommon/llthread.cpp') diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp index e6beb9e680..b685bb4d60 100644 --- a/indra/llcommon/llmutex.cpp +++ b/indra/llcommon/llmutex.cpp @@ -83,11 +83,7 @@ void LLMutex::lock() mIsLocked[id] = TRUE; #endif -#if LL_DARWIN mLockingThread = LLThread::currentID(); -#else - mLockingThread = LLThread::sThreadID; -#endif } void LLMutex::unlock() @@ -126,11 +122,7 @@ bool LLMutex::isLocked() bool LLMutex::isSelfLocked() { -#if LL_DARWIN return mLockingThread == LLThread::currentID(); -#else - return mLockingThread == LLThread::sThreadID; -#endif } U32 LLMutex::lockingThread() const diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 8ce739bf23..6374b5398b 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -62,9 +62,9 @@ #if LL_DARWIN // statically allocated thread local storage not supported in Darwin executable formats #elif LL_WINDOWS -U32 __declspec(thread) LLThread::sThreadID = 0; +U32 __declspec(thread) sThreadID = 0; #elif LL_LINUX -U32 __thread LLThread::sThreadID = 0; +U32 __thread sThreadID = 0; #endif U32 LLThread::sIDIter = 0; @@ -294,7 +294,13 @@ void LLThread::setQuitting() // static U32 LLThread::currentID() { +#if LL_DARWIN + // statically allocated thread local storage not supported in Darwin executable formats return (U32)apr_os_thread_current(); +#else + return sThreadID; +#endif + } // static diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 75222c83f9..92323f5fda 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -39,13 +39,6 @@ class LL_COMMON_API LLThread private: friend class LLMutex; static U32 sIDIter; -#if LL_DARWIN - // statically allocated thread local storage not supported in Darwin executable formats -#elif LL_WINDOWS - static U32 __declspec(thread) LLThread::sThreadID; -#elif LL_LINUX - static U32 __thread LLThread::sThreadID ; -#endif public: typedef enum e_thread_status -- cgit v1.3