diff options
Diffstat (limited to 'indra')
23 files changed, 391 insertions, 203 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index af3689c641..d9553b9a7e 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -216,7 +216,7 @@ endif (DARWIN) if (LINUX OR DARWIN) - set(GCC_WARNINGS "-Wall -Wno-unused-but-set-variable -Wno-sign-compare -Wno-trigraphs") + set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs") if (NOT GCC_DISABLE_FATAL_WARNINGS) set(GCC_WARNINGS "${GCC_WARNINGS} -Werror") diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 7ed1671ca8..f8f1c010f7 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -98,6 +98,7 @@ set(llcommon_SOURCE_FILES llstringtable.cpp llsys.cpp llthread.cpp + llthreadlocalstorage.cpp llthreadsafequeue.cpp lltimer.cpp lltrace.cpp diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 0556fadb26..47fa70614f 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -494,77 +494,6 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset) } // -//LLThreadLocalPointerBase -// -bool LLThreadLocalPointerBase::sInitialized = false; - -void LLThreadLocalPointerBase::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 LLThreadLocalPointerBase::initStorage( ) -{ - apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - llerrs << "Failed to allocate thread local data" << llendl; - } -} - -void LLThreadLocalPointerBase::destroyStorage() -{ - if (sInitialized) - { - 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 LLThreadLocalPointerBase::initAllThreadLocalStorage() -{ - if (!sInitialized) - { - for (LLInstanceTracker<LLThreadLocalPointerBase>::instance_iter it = beginInstances(), end_it = endInstances(); - it != end_it; - ++it) - { - (*it).initStorage(); - } - sInitialized = true; - } -} - -void LLThreadLocalPointerBase::destroyAllThreadLocalStorage() -{ - if (sInitialized) - { - //for (LLInstanceTracker<LLThreadLocalPointerBase>::instance_iter it = beginInstances(), end_it = endInstances(); - // it != end_it; - // ++it) - //{ - // (*it).destroyStorage(); - //} - sInitialized = false; - } -} - -// //******************************************************************************************************************************* //static components of LLAPRFile // diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index e6233a094e..37332da31c 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -199,10 +199,11 @@ void TimeBlock::processTimes() { TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator(); - if (accumulator->mLastCaller) + if (accumulator->mLastAccumulator) { - timer.setParent(accumulator->mLastCaller); - accumulator->mParent = accumulator->mLastCaller; + TimeBlock* parent = accumulator->mLastAccumulator->mBlock; + timer.setParent(parent); + accumulator->mParent = parent; } // no need to push up tree on first use, flag can be set spuriously accumulator->mMoveUpTree = false; @@ -250,23 +251,22 @@ void TimeBlock::processTimes() // walk up stack of active timers and accumulate current time while leaving timing structures active BlockTimer* cur_timer = stack_record->mActiveTimer; - TimeBlockAccumulator* accumulator = stack_record->mTimeBlock->getPrimaryAccumulator(); + TimeBlockAccumulator* accumulator = stack_record->mAccumulator; // root defined by parent pointing to self while(cur_timer && cur_timer->mLastTimerData.mActiveTimer != cur_timer) { U64 cumulative_time_delta = cur_time - cur_timer->mStartTime; - U64 self_time_delta = cumulative_time_delta - stack_record->mChildTime; + accumulator->mChildTimeCounter += stack_record->mChildTime; stack_record->mChildTime = 0; - accumulator->mSelfTimeCounter += self_time_delta; accumulator->mTotalTimeCounter += cumulative_time_delta; cur_timer->mStartTime = cur_time; stack_record = &cur_timer->mLastTimerData; stack_record->mChildTime += cumulative_time_delta; - if (stack_record->mTimeBlock) + if (stack_record->mAccumulator) { - accumulator = stack_record->mTimeBlock->getPrimaryAccumulator(); + accumulator = stack_record->mAccumulator; } cur_timer = cur_timer->mLastTimerData.mActiveTimer; @@ -282,7 +282,7 @@ void TimeBlock::processTimes() TimeBlock& timer = *it; TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator(); - accumulator->mLastCaller = NULL; + accumulator->mLastAccumulator = NULL; accumulator->mMoveUpTree = false; } @@ -417,10 +417,10 @@ void TimeBlock::writeLog(std::ostream& os) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TimeBlockAccumulator::TimeBlockAccumulator() -: mSelfTimeCounter(0), +: mChildTimeCounter(0), mTotalTimeCounter(0), mCalls(0), - mLastCaller(NULL), + mLastAccumulator(NULL), mActiveCount(0), mMoveUpTree(false), mParent(NULL) @@ -428,10 +428,10 @@ TimeBlockAccumulator::TimeBlockAccumulator() void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other ) { - mSelfTimeCounter += other.mSelfTimeCounter; + mChildTimeCounter += other.mChildTimeCounter; mTotalTimeCounter += other.mTotalTimeCounter; mCalls += other.mCalls; - mLastCaller = other.mLastCaller; + mLastAccumulator = other.mLastAccumulator; mActiveCount = other.mActiveCount; mMoveUpTree = other.mMoveUpTree; mParent = other.mParent; @@ -440,7 +440,7 @@ void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other ) void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other ) { mTotalTimeCounter = 0; - mSelfTimeCounter = 0; + mChildTimeCounter = 0; mCalls = 0; } diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index fb2868ff98..2d87629561 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -40,9 +40,9 @@ namespace LLTrace struct BlockTimerStackRecord { - class BlockTimer* mActiveTimer; - class TimeBlock* mTimeBlock; - U64 mChildTime; + class BlockTimer* mActiveTimer; + class TimeBlockAccumulator* mAccumulator; + U64 mChildTime; }; class ThreadTimerStack @@ -277,7 +277,7 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer) mStartTime = TimeBlock::getCPUClockCount64(); BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists(); - TimeBlockAccumulator* accumulator = cur_timer_data->mTimeBlock->getPrimaryAccumulator(); + TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator(); accumulator->mActiveCount++; // keep current parent as long as it is active when we are accumulator->mMoveUpTree |= (accumulator->mParent->getPrimaryAccumulator()->mActiveCount == 0); @@ -286,7 +286,7 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer) mLastTimerData = *cur_timer_data; // push new information cur_timer_data->mActiveTimer = this; - cur_timer_data->mTimeBlock = &timer; + cur_timer_data->mAccumulator = accumulator; cur_timer_data->mChildTime = 0; #endif } @@ -296,21 +296,22 @@ LL_FORCE_INLINE BlockTimer::~BlockTimer() #if FAST_TIMER_ON U64 total_time = TimeBlock::getCPUClockCount64() - mStartTime; BlockTimerStackRecord* cur_timer_data = ThreadTimerStack::getIfExists(); - TimeBlockAccumulator* accumulator = cur_timer_data->mTimeBlock->getPrimaryAccumulator(); + TimeBlockAccumulator* accumulator = cur_timer_data->mAccumulator; accumulator->mCalls++; - accumulator->mSelfTimeCounter += total_time - cur_timer_data->mChildTime; + accumulator->mChildTimeCounter += cur_timer_data->mChildTime; accumulator->mTotalTimeCounter += total_time; accumulator->mActiveCount--; // store last caller to bootstrap tree creation // do this in the destructor in case of recursion to get topmost caller - accumulator->mLastCaller = mLastTimerData.mTimeBlock; + accumulator->mLastAccumulator = mLastTimerData.mAccumulator; // we are only tracking self time, so subtract our total time delta from parents mLastTimerData.mChildTime += total_time; - *ThreadTimerStack::getIfExists() = mLastTimerData; + //pop stack + *cur_timer_data = mLastTimerData; #endif } diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 4ead45679f..95500753e4 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -39,6 +39,20 @@ class LLMutex ; #define LL_CHECK_MEMORY #endif +#if LL_WINDOWS +#define LL_ALIGN_OF __alignof +#else +#define LL_ALIGN_OF __align_of__ +#endif + +#if LL_WINDOWS +#define LL_DEFAULT_HEAP_ALIGN 8 +#elif LL_DARWIN +#define LL_DEFAULT_HEAP_ALIGN 16 +#elif LL_LINUX +#define LL_DEFAULT_HEAP_ALIGN 8 +#endif + inline void* ll_aligned_malloc( size_t size, int align ) { void* mem = malloc( size + (align - 1) + sizeof(void*) ); diff --git a/indra/llcommon/llthreadlocalstorage.cpp b/indra/llcommon/llthreadlocalstorage.cpp new file mode 100644 index 0000000000..7858ee5429 --- /dev/null +++ b/indra/llcommon/llthreadlocalstorage.cpp @@ -0,0 +1,101 @@ +/** + * @file llthreadlocalstorage.cpp + * @author Richard + * @date 2013-1-11 + * @brief implementation of thread local storage utility classes + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, 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 "llthreadlocalstorage.h" + +// +//LLThreadLocalPointerBase +// +bool LLThreadLocalPointerBase::sInitialized = false; + +void LLThreadLocalPointerBase::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 LLThreadLocalPointerBase::initStorage( ) +{ + apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp); + if (result != APR_SUCCESS) + { + ll_apr_warn_status(result); + llerrs << "Failed to allocate thread local data" << llendl; + } +} + +void LLThreadLocalPointerBase::destroyStorage() +{ + if (sInitialized) + { + 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 LLThreadLocalPointerBase::initAllThreadLocalStorage() +{ + if (!sInitialized) + { + for (LLInstanceTracker<LLThreadLocalPointerBase>::instance_iter it = beginInstances(), end_it = endInstances(); + it != end_it; + ++it) + { + (*it).initStorage(); + } + sInitialized = true; + } +} + +void LLThreadLocalPointerBase::destroyAllThreadLocalStorage() +{ + if (sInitialized) + { + //for (LLInstanceTracker<LLThreadLocalPointerBase>::instance_iter it = beginInstances(), end_it = endInstances(); + // it != end_it; + // ++it) + //{ + // (*it).destroyStorage(); + //} + sInitialized = false; + } +} diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h index 5a38d54eea..c8b7c5e229 100644 --- a/indra/llcommon/llthreadlocalstorage.h +++ b/indra/llcommon/llthreadlocalstorage.h @@ -151,44 +151,66 @@ public: virtual ~LLThreadLocalSingleton() { - sInstance = NULL; - sInitState = DELETED; +#if LL_DARWIN + //pthread_setspecific(sInstanceKey, NULL); +#else + sInstance = NULL; +#endif + setInitState(DELETED); } static void deleteSingleton() { - delete sInstance; - sInstance = NULL; - sInitState = DELETED; + delete getIfExists(); } static DERIVED_TYPE* getInstance() { - if (sInitState == CONSTRUCTING) + EInitState init_state = getInitState(); + if (init_state == CONSTRUCTING) { llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl; } - if (sInitState == DELETED) + if (init_state == DELETED) { llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl; } - if (!sInstance) + if (!getIfExists()) { - sInitState = CONSTRUCTING; - sInstance = new DERIVED_TYPE(); - sInitState = INITIALIZING; - sInstance->initSingleton(); - sInitState = INITIALIZED; + setInitState(CONSTRUCTING); + DERIVED_TYPE* instancep = new DERIVED_TYPE(); +#if LL_DARWIN + /*static S32 sKeyCreated = pthread_key_create(&sInstanceKey, NULL); + if (sKeyCreated != 0) + { + llerrs << "Could not create thread local storage" << llendl; + } + + S32 result = pthread_setspecific(sInstanceKey, (void*)instancep); + if (result != 0) + { + llerrs << "Could not set thread local storage" << llendl; + }*/ +#else + sInstance = instancep; +#endif + setInitState(INITIALIZING); + instancep->initSingleton(); + setInitState(INITIALIZED); } - return sInstance; + return getIfExists(); } static DERIVED_TYPE* getIfExists() { +#if LL_DARWIN + return NULL;//(DERIVED_TYPE*)pthread_getspecific(sInstanceKey); +#else return sInstance; +#endif } // Reference version of getInstance() @@ -202,16 +224,46 @@ public: // Use this to avoid accessing singletons before the can safely be constructed static bool instanceExists() { - return sInitState == INITIALIZED; + return getInitState() == INITIALIZED; } // Has this singleton already been deleted? // Use this to avoid accessing singletons from a static object's destructor static bool destroyed() { - return sInitState == DELETED; + return getInitState() == DELETED; } private: +#if LL_DARWIN + static EInitState& threadLocalInitState() + { + /*static S32 sKeyCreated = pthread_key_create(&sInitStateKey, NULL); + if (sKeyCreated != 0) + { + llerrs << "Could not create thread local storage" << llendl; + } + return *(EInitState*)pthread_getspecific(sInitStateKey);*/ + static EInitState state; + return state; + } +#endif + static EInitState getInitState() + { +#if LL_DARWIN + return threadLocalInitState(); +#else + return sInitState; +#endif + } + + static void setInitState(EInitState state) + { +#if LL_DARWIN + threadLocalInitState() = state; +#else + sInitState = state; +#endif + } LLThreadLocalSingleton(const LLThreadLocalSingleton& other); virtual void initSingleton() {} @@ -221,10 +273,13 @@ private: #elif LL_LINUX static __thread DERIVED_TYPE* sInstance; static __thread EInitState sInitState; +#elif LL_DARWIN + //static pthread_key_t sInstanceKey; + //static pthread_key_t sInitStateKey; #endif }; -#ifdef LL_WINDOWS +#if LL_WINDOWS template<typename DERIVED_TYPE> __declspec(thread) DERIVED_TYPE* LLThreadLocalSingleton<DERIVED_TYPE>::sInstance = NULL; @@ -236,6 +291,12 @@ __thread DERIVED_TYPE* LLThreadLocalSingleton<DERIVED_TYPE>::sInstance = NULL; template<typename DERIVED_TYPE> __thread typename LLThreadLocalSingleton<DERIVED_TYPE>::EInitState LLThreadLocalSingleton<DERIVED_TYPE>::sInitState = LLThreadLocalSingleton<DERIVED_TYPE>::UNINITIALIZED; +#elif LL_DARWIN +/*template<typename DERIVED_TYPE> +pthread_key_t LLThreadLocalSingleton<DERIVED_TYPE>::sInstanceKey; + +template<typename DERIVED_TYPE> +pthread_key_t LLThreadLocalSingleton<DERIVED_TYPE>::sInitStateKey;*/ #endif template<typename DERIVED_TYPE> @@ -249,7 +310,11 @@ public: LL_FORCE_INLINE static DERIVED_TYPE* getInstance() { +#if LL_DARWIN + return sInstance.get(); +#else return sInstance; +#endif } LL_FORCE_INLINE static void setInstance(DERIVED_TYPE* instance) @@ -258,18 +323,24 @@ public: } private: -#ifdef LL_WINDOWS +#if LL_WINDOWS static __declspec(thread) DERIVED_TYPE* sInstance; #elif LL_LINUX static __thread DERIVED_TYPE* sInstance; +#elif LL_DARWIN + static LLThreadLocalPointer<DERIVED_TYPE> sInstance; #endif }; +#if LL_WINDOWS template<typename DERIVED_TYPE> -#ifdef LL_WINDOWS __declspec(thread) DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL; #elif LL_LINUX +template<typename DERIVED_TYPE> __thread DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL; +#elif LL_DARWIN +template<typename DERIVED_TYPE> +LLThreadLocalPointer<DERIVED_TYPE> LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance; #endif #endif // LL_LLTHREADLOCALSTORAGE_H diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index 1a156e583e..1d3c376a58 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -446,11 +446,12 @@ namespace LLTrace // // members // - U64 mSelfTimeCounter, + U64 mChildTimeCounter, mTotalTimeCounter; U32 mCalls; + class TimeBlock* mBlock; // block associated with this accumulator class TimeBlock* mParent; // last acknowledged parent of this time block - class TimeBlock* mLastCaller; // used to bootstrap tree construction + TimeBlockAccumulator* mLastAccumulator; // used to bootstrap tree construction U16 mActiveCount; // number of timers with this ID active on stack bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame @@ -660,7 +661,58 @@ struct MemFootprint<std::list<T> > } }; -template<typename DERIVED> +template <size_t ALIGNMENT, size_t RESERVE> +void* allocAligned(size_t size) +{ + llstatic_assert((ALIGNMENT > 0) && (ALIGNMENT & (ALIGNMENT - 1)) == 0, "Alignment must be a power of 2"); + + void* padded_allocation; + const size_t aligned_reserve = (RESERVE / ALIGNMENT) + + ((RESERVE % ALIGNMENT) ? ALIGNMENT : 0); + const size_t size_with_reserve = size + aligned_reserve; + if (ALIGNMENT <= LL_DEFAULT_HEAP_ALIGN) + { + padded_allocation = malloc(size_with_reserve); + } + else + { +#if LL_WINDOWS + padded_allocation = _aligned_malloc(size_with_reserve, ALIGNMENT); +#elif LL_DARWIN + padded_allocation = ll_aligned_malloc(size_with_reserve, ALIGNMENT); +#else + if (LL_UNLIKELY(0 != posix_memalign(&padded_allocation, 16, size))) + padded_allocation = NULL; +#endif + } + return (char*)padded_allocation + aligned_reserve; +} + +template<size_t ALIGNMENT, size_t RESERVE> +void deallocAligned(void* ptr) +{ + const size_t aligned_reserve = (RESERVE / ALIGNMENT) + + ((RESERVE % ALIGNMENT) ? ALIGNMENT : 0); + + void* original_allocation = (char*)ptr - aligned_reserve; + + if (ALIGNMENT <= LL_DEFAULT_HEAP_ALIGN) + { + free(original_allocation); + } + else + { +#if LL_WINDOWS + _aligned_free(original_allocation); +#elif LL_DARWIN + ll_aligned_free(original_allocation); +#else + free(original_allocation); +#endif + } +} + +template<typename DERIVED, size_t ALIGNMENT = LL_DEFAULT_HEAP_ALIGN> class MemTrackable { template<typename TRACKED, typename TRACKED_IS_TRACKER> @@ -676,44 +728,49 @@ public: memDisclaim(mMemFootprint); } - void* operator new(size_t allocation_size) + void* operator new(size_t size) { - // reserve 8 bytes for allocation size (and preserving 8 byte alignment of structs) - void* allocation = ::operator new(allocation_size + 8); - *(size_t*)allocation = allocation_size; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize += allocation_size; + accumulator->mSize += size; accumulator->mAllocatedCount++; } - return (void*)((char*)allocation + 8); + + // reserve 4 bytes for allocation size (and preserving requested alignment) + void* allocation = allocAligned<ALIGNMENT, sizeof(size_t)>(size); + ((size_t*)allocation)[-1] = size; + + return allocation; } void operator delete(void* ptr) { - size_t* allocation_size = (size_t*)((char*)ptr - 8); + size_t allocation_size = ((size_t*)ptr)[-1]; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { - accumulator->mSize -= *allocation_size; + accumulator->mSize -= allocation_size; accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } - ::delete((char*)ptr - 8); + deallocAligned<ALIGNMENT, sizeof(size_t)>(ptr); } void *operator new [](size_t size) { - size_t* result = (size_t*)malloc(size + 8); - *result = size; MemStatAccumulator* accumulator = DERIVED::sMemStat.getPrimaryAccumulator(); if (accumulator) { accumulator->mSize += size; accumulator->mAllocatedCount++; } - return (void*)((char*)result + 8); + + // reserve 4 bytes for allocation size (and preserving requested alignment) + void* allocation = allocAligned<ALIGNMENT, sizeof(size_t)>(size); + ((size_t*)allocation)[-1] = size; + + return allocation; } void operator delete[](void* ptr) @@ -726,7 +783,7 @@ public: accumulator->mAllocatedCount--; accumulator->mDeallocatedCount++; } - ::delete[]((char*)ptr - 8); + deallocAligned<ALIGNMENT, sizeof(size_t)>(ptr); } // claim memory associated with other objects/data as our own, adding to our calculated footprint @@ -783,6 +840,8 @@ public: private: size_t mMemFootprint; + + template<typename TRACKED, typename TRACKED_IS_TRACKER = void> struct TrackMemImpl { diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index c110e64380..f45226eb9a 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -60,7 +60,7 @@ Recording::Recording( const Recording& other ) mStackTimers = other.mStackTimers; mMemStats = other.mMemStats; - LLStopWatchControlsMixin<Recording>::initTo(other.getPlayState()); + LLStopWatchControlsMixin<Recording>::setPlayState(other.getPlayState()); } @@ -179,7 +179,7 @@ LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumul LLUnit<LLUnits::Seconds, F64> Recording::getSum(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const { - return (F64)(*mStackTimers)[stat.getIndex()].mSelfTimeCounter / (F64)LLTrace::TimeBlock::countsPerSecond(); + return ((F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter - (F64)(*mStackTimers)[stat.getIndex()].mChildTimeCounter) / (F64)LLTrace::TimeBlock::countsPerSecond(); } @@ -195,7 +195,7 @@ LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccu LLUnit<LLUnits::Seconds, F64> Recording::getPerSec(const TraceType<TimeBlockAccumulator::SelfTimeAspect>& stat) const { - return (F64)(*mStackTimers)[stat.getIndex()].mSelfTimeCounter / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); + return ((F64)(*mStackTimers)[stat.getIndex()].mTotalTimeCounter - (F64)(*mStackTimers)[stat.getIndex()].mChildTimeCounter) / ((F64)LLTrace::TimeBlock::countsPerSecond() * mElapsedSeconds); } F32 Recording::getPerSec(const TraceType<TimeBlockAccumulator::CallCountAspect>& stat) const @@ -345,14 +345,14 @@ U32 Recording::getSampleCount( const TraceType<MeasurementAccumulator<S64> >& st // PeriodicRecording /////////////////////////////////////////////////////////////////////// -PeriodicRecording::PeriodicRecording( S32 num_periods, EStopWatchState state) +PeriodicRecording::PeriodicRecording( S32 num_periods, EPlayState state) : mNumPeriods(num_periods), mCurPeriod(0), mTotalValid(false), mRecordingPeriods( new Recording[num_periods]) { llassert(mNumPeriods > 0); - initTo(state); + setPlayState(state); } PeriodicRecording::PeriodicRecording(PeriodicRecording& other) @@ -377,7 +377,7 @@ PeriodicRecording::~PeriodicRecording() void PeriodicRecording::nextPeriod() { - EStopWatchState play_state = getPlayState(); + EPlayState play_state = getPlayState(); Recording& old_recording = getCurRecordingPeriod(); mCurPeriod = (mCurPeriod + 1) % mNumPeriods; old_recording.splitTo(getCurRecordingPeriod()); @@ -458,8 +458,14 @@ void PeriodicRecording::splitFrom(PeriodicRecording& other) void ExtendableRecording::extend() { + // stop recording to get latest data + mPotentialRecording.stop(); + // push the data back to accepted recording mAcceptedRecording.appendRecording(mPotentialRecording); + // flush data, so we can start from scratch mPotentialRecording.reset(); + // go back to play state we were in initially + mPotentialRecording.setPlayState(getPlayState()); } void ExtendableRecording::start() @@ -514,7 +520,7 @@ PeriodicRecording& get_frame_recording() void LLStopWatchControlsMixinCommon::start() { - switch (mState) + switch (mPlayState) { case STOPPED: handleReset(); @@ -530,12 +536,12 @@ void LLStopWatchControlsMixinCommon::start() llassert(false); break; } - mState = STARTED; + mPlayState = STARTED; } void LLStopWatchControlsMixinCommon::stop() { - switch (mState) + switch (mPlayState) { case STOPPED: break; @@ -549,12 +555,12 @@ void LLStopWatchControlsMixinCommon::stop() llassert(false); break; } - mState = STOPPED; + mPlayState = STOPPED; } void LLStopWatchControlsMixinCommon::pause() { - switch (mState) + switch (mPlayState) { case STOPPED: break; @@ -567,12 +573,12 @@ void LLStopWatchControlsMixinCommon::pause() llassert(false); break; } - mState = PAUSED; + mPlayState = PAUSED; } void LLStopWatchControlsMixinCommon::resume() { - switch (mState) + switch (mPlayState) { case STOPPED: handleStart(); @@ -586,12 +592,12 @@ void LLStopWatchControlsMixinCommon::resume() llassert(false); break; } - mState = STARTED; + mPlayState = STARTED; } void LLStopWatchControlsMixinCommon::restart() { - switch (mState) + switch (mPlayState) { case STOPPED: handleReset(); @@ -608,7 +614,7 @@ void LLStopWatchControlsMixinCommon::restart() llassert(false); break; } - mState = STARTED; + mPlayState = STARTED; } void LLStopWatchControlsMixinCommon::reset() @@ -616,21 +622,23 @@ void LLStopWatchControlsMixinCommon::reset() handleReset(); } -void LLStopWatchControlsMixinCommon::initTo( EStopWatchState state ) +void LLStopWatchControlsMixinCommon::setPlayState( EPlayState state ) { switch(state) { case STOPPED: + stop(); break; case PAUSED: + pause(); break; case STARTED: - handleStart(); + start(); break; default: llassert(false); break; } - mState = state; + mPlayState = state; } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 5105874ba1..a773c9ad91 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -39,7 +39,7 @@ class LLStopWatchControlsMixinCommon public: virtual ~LLStopWatchControlsMixinCommon() {} - enum EStopWatchState + enum EPlayState { STOPPED, PAUSED, @@ -53,19 +53,18 @@ public: virtual void restart(); virtual void reset(); - bool isStarted() const { return mState == STARTED; } - bool isPaused() const { return mState == PAUSED; } - bool isStopped() const { return mState == STOPPED; } - EStopWatchState getPlayState() const { return mState; } + bool isStarted() const { return mPlayState == STARTED; } + bool isPaused() const { return mPlayState == PAUSED; } + bool isStopped() const { return mPlayState == STOPPED; } + EPlayState getPlayState() const { return mPlayState; } + // force play state to specific value by calling appropriate handle* methods + void setPlayState(EPlayState state); protected: LLStopWatchControlsMixinCommon() - : mState(STOPPED) + : mPlayState(STOPPED) {} - // derived classes can call this from their copy constructor in order - // to duplicate play state of source - void initTo(EStopWatchState state); private: // trigger active behavior (without reset) virtual void handleStart(){}; @@ -74,7 +73,7 @@ private: // clear accumulated state, can be called while started virtual void handleReset(){}; - EStopWatchState mState; + EPlayState mPlayState; }; template<typename DERIVED> @@ -245,7 +244,7 @@ namespace LLTrace : public LLStopWatchControlsMixin<PeriodicRecording> { public: - PeriodicRecording(S32 num_periods, EStopWatchState state = STOPPED); + PeriodicRecording(S32 num_periods, EPlayState state = STOPPED); PeriodicRecording(PeriodicRecording& recording); ~PeriodicRecording(); diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 7b493a651e..bc1d19e72c 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -43,7 +43,7 @@ ThreadRecorder::ThreadRecorder() TimeBlock& root_time_block = TimeBlock::getRootTimeBlock(); ThreadTimerStack* timer_stack = ThreadTimerStack::getInstance(); - timer_stack->mTimeBlock = &root_time_block; + timer_stack->mAccumulator = root_time_block.getPrimaryAccumulator(); timer_stack->mActiveTimer = NULL; mNumTimeBlockTreeNodes = AccumulatorBuffer<TimeBlockAccumulator>::getDefaultBuffer()->size(); @@ -61,7 +61,9 @@ ThreadRecorder::ThreadRecorder() tree_node.mBlock = &time_block; tree_node.mParent = &root_time_block; - it->getPrimaryAccumulator()->mParent = &root_time_block; + TimeBlockAccumulator* accumulator = it->getPrimaryAccumulator(); + accumulator->mParent = &root_time_block; + accumulator->mBlock = &time_block; } mRootTimer = new BlockTimer(root_time_block); diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h index c600883607..c2a31b7604 100644 --- a/indra/llcommon/llunit.h +++ b/indra/llcommon/llunit.h @@ -301,13 +301,13 @@ LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator - (SCALAR_TYPE first, LLUnitImp template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> LLUnit<UNIT_TYPE, STORAGE_TYPE> operator * (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> second) { - return LLUnit<UNIT_TYPE, STORAGE_TYPE>(first * second.value()); + return LLUnit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first * second.value())); } template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> LLUnit<UNIT_TYPE, STORAGE_TYPE> operator * (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) { - return LLUnit<UNIT_TYPE, STORAGE_TYPE>(first.value() * second); + return LLUnit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first.value() * second)); } template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> @@ -350,7 +350,7 @@ SCALAR_TYPE operator / (SCALAR_TYPE first, LLUnit<UNIT_TYPE, STORAGE_TYPE> secon template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> LLUnit<UNIT_TYPE, STORAGE_TYPE> operator / (LLUnit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) { - return LLUnit<UNIT_TYPE, STORAGE_TYPE>(first.value() / second); + return LLUnit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first.value() / second)); } template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> @@ -363,7 +363,7 @@ STORAGE_TYPE1 operator / (LLUnit<UNIT_TYPE1, STORAGE_TYPE1> first, LLUnit<UNIT_T template<typename UNIT_TYPE, typename STORAGE_TYPE, typename SCALAR_TYPE> LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> operator / (LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE> first, SCALAR_TYPE second) { - return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>(first.value() / second); + return LLUnitImplicit<UNIT_TYPE, STORAGE_TYPE>((STORAGE_TYPE)(first.value() / second)); } template<typename UNIT_TYPE1, typename STORAGE_TYPE1, typename UNIT_TYPE2, typename STORAGE_TYPE2> diff --git a/indra/media_plugins/webkit/mac_volume_catcher.cpp b/indra/media_plugins/webkit/mac_volume_catcher.cpp index 8a06bb8487..c20bcd374d 100644 --- a/indra/media_plugins/webkit/mac_volume_catcher.cpp +++ b/indra/media_plugins/webkit/mac_volume_catcher.cpp @@ -38,6 +38,7 @@ #include <Carbon/Carbon.h> #include <QuickTime/QuickTime.h> #include <AudioUnit/AudioUnit.h> +#include <list> struct VolumeCatcherStorage; diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 9521287a45..161f550bb6 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -60,7 +60,9 @@ const U32 SILHOUETTE_HIGHLIGHT = 0; // All data for new renderer goes into this class. LL_ALIGN_PREFIX(16) -class LLDrawable : public LLViewerOctreeEntryData, public LLTrace::MemTrackable<LLDrawable> +class LLDrawable +: public LLViewerOctreeEntryData, + public LLTrace::MemTrackable<LLDrawable> { public: LLDrawable(const LLDrawable& rhs) : LLViewerOctreeEntryData(rhs) @@ -76,16 +78,6 @@ public: static void initClass(); - void* operator new(size_t size) - { - return ll_aligned_malloc_16(size); - } - - void operator delete(void* ptr) - { - ll_aligned_free_16(ptr); - } - LLDrawable(LLViewerObject *vobj, bool new_entry = false); void markDead(); // Mark this drawable as dead @@ -93,7 +85,7 @@ public: BOOL isNew() const { return !isState(BUILT); } BOOL isLight() const; - + virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE); LLSpatialGroup* getSpatialGroup()const {return (LLSpatialGroup*)getGroup();} @@ -115,7 +107,7 @@ public: const LLQuaternion& getRotation() const { return mXform.getRotation(); } F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); } S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; } - + void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); } LLXformMatrix* getXform() { return &mXform; } @@ -290,33 +282,33 @@ public: ANIMATED_CHILD = 0x20000000, ACTIVE_CHILD = 0x40000000, } EDrawableFlags; - + public: LLXformMatrix mXform; // vis data LLPointer<LLDrawable> mParent; - F32 mDistanceWRTCamera; - + F32 mDistanceWRTCamera; + static F32 sCurPixelAngle; //current pixels per radian static LLTrace::MemStat sMemStat; private: typedef std::vector<LLFace*> face_list_t; - U32 mState; - S32 mRenderType; - LLPointer<LLViewerObject> mVObjp; - face_list_t mFaces; - LLPointer<LLDrawable> mSpatialBridge; - - F32 mRadius; - S32 mGeneration; + U32 mState; + S32 mRenderType; + LLPointer<LLViewerObject> mVObjp; + face_list_t mFaces; + LLPointer<LLDrawable> mSpatialBridge; - LLVector3 mCurrentScale; + F32 mRadius; + S32 mGeneration; - static U32 sNumZombieDrawables; + LLVector3 mCurrentScale; + + static U32 sNumZombieDrawables; static LLDynamicArrayPtr<LLPointer<LLDrawable> > sDeadList; } LL_ALIGN_POSTFIX(16); diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 7a960f7baa..bafd245aa0 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -358,7 +358,7 @@ void LLSceneMonitor::calcDiffAggregate() glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject); } - gl_draw_scaled_target(0, 0, mDiff->getWidth() * mDiffPixelRatio, mDiff->getHeight() * mDiffPixelRatio, mDiff); + gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff); if(mHasNewDiff) { @@ -440,8 +440,8 @@ void LLSceneMonitorView::draw() } F32 ratio = LLSceneMonitor::getInstance()->getDiffPixelRatio(); - S32 height = target->getHeight() * ratio; - S32 width = target->getWidth() * ratio; + S32 height = (S32)(target->getHeight() * ratio); + S32 width = (S32)(target->getWidth() * ratio); //S32 height = (S32) (gViewerWindow->getWindowRectScaled().getHeight()*0.5f); //S32 width = (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.5f); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 01f9151ab4..fba636e8ef 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -3746,11 +3746,12 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher) main_stats.getStats(stats, true); //LLSD merged_llsd = main_stats.asLLSD(); + bool initial_report = !reporting_started; stats.session_id = mSessionID; stats.agent_id = mAgentID; stats.message = "ViewerAssetMetrics"; stats.sequence = static_cast<bool>(report_sequence); - stats.initial = static_cast<bool>(!reporting_started); + stats.initial = initial_report; stats.break_ = static_cast<bool>(LLTextureFetch::svMetricsDataBreak); LLSD sd; diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp index b4da9521f4..890394dd22 100644 --- a/indra/newview/llviewerassetstats.cpp +++ b/indra/newview/llviewerassetstats.cpp @@ -297,7 +297,7 @@ LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src) it->second.makeUnique(); } - LLStopWatchControlsMixin<LLViewerAssetStats>::initTo(src.getPlayState()); + LLStopWatchControlsMixin<LLViewerAssetStats>::setPlayState(src.getPlayState()); } void LLViewerAssetStats::handleStart() diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index 5bcaeb85da..a35c551949 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -324,4 +324,4 @@ protected: S32 mRes; }; -#endif
\ No newline at end of file +#endif diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index f44c8ffe46..45d43bdf74 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1001,7 +1001,10 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) { if(vo_entry->getState() >= LLVOCacheEntry::WAITING) { - iter = mImpl->mVisibleEntries.erase(iter); + LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter; + ++next_iter; + mImpl->mVisibleEntries.erase(iter); + iter = next_iter; } else { diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 077c9f43a4..136a4d0a9e 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -394,7 +394,7 @@ void update_statistics() static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { - gTotalTextureData = LLTrace::Bytes(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT)).value(); + gTotalTextureData = LLTrace::Bytes(LLViewerStats::instance().getRecording().getSum(LLStatViewer::TEXTURE_KBIT)); texture_stats_timer.reset(); } } diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index 2d5292b5f3..482f6a77a3 100644 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -216,7 +216,10 @@ void LLViewerStatsRecorder::writeToLog( F32 interval ) << "Texture Fetch bps\t" << "\n"; - fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); + if (fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ) != data_msg.str().size()) + { + llwarns << "Failed to write log file." << llendl; + } } else { @@ -249,7 +252,10 @@ void LLViewerStatsRecorder::writeToLog( F32 interval ) << "\t" << (mTextureFetchSize * 8 / delta_time) << "\n"; - fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); + if (fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ) != data_msg.str().size()) + { + llwarns << "Failed to write log file." << llendl; + } clearStats(); } diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 7f17fd3e56..717f215d3d 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -394,7 +394,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) segment->flush(); } - llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32()) << "seconds" << llendl; + llinfos << "completed in " << llformat("%.2f", timer.getElapsedTimeF32().value()) << "seconds" << llendl; } #else mStripsVerts = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB); |