diff options
-rw-r--r-- | indra/llcommon/llfasttimer.cpp | 30 | ||||
-rw-r--r-- | indra/llcommon/llfasttimer.h | 11 | ||||
-rw-r--r-- | indra/llcommon/llthreadlocalstorage.h | 74 | ||||
-rw-r--r-- | indra/llcommon/lltracethreadrecorder.cpp | 6 |
4 files changed, 75 insertions, 46 deletions
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 37332da31c..b4a422816e 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -183,7 +183,6 @@ void TimeBlock::processTimes() { get_clock_count(); // good place to calculate clock frequency U64 cur_time = getCPUClockCount64(); - BlockTimerStackRecord* stack_record = ThreadTimerStack::getInstance(); // set up initial tree for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(), end_it = LLInstanceTracker<TimeBlock>::endInstances(); @@ -202,6 +201,7 @@ void TimeBlock::processTimes() if (accumulator->mLastAccumulator) { TimeBlock* parent = accumulator->mLastAccumulator->mBlock; + llassert(parent); timer.setParent(parent); accumulator->mParent = parent; } @@ -250,26 +250,28 @@ 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->mAccumulator; + BlockTimerStackRecord* stack_record = ThreadTimerStack::getInstance(); + BlockTimer* cur_timer = stack_record->mActiveTimer; + TimeBlockAccumulator* accumulator = stack_record->mAccumulator; + + llassert(accumulator); + // root defined by parent pointing to self - while(cur_timer && cur_timer->mLastTimerData.mActiveTimer != cur_timer) + while(cur_timer && cur_timer->mParentTimerData.mActiveTimer != cur_timer) { U64 cumulative_time_delta = cur_time - cur_timer->mStartTime; + + accumulator->mTotalTimeCounter += cumulative_time_delta; accumulator->mChildTimeCounter += stack_record->mChildTime; stack_record->mChildTime = 0; - accumulator->mTotalTimeCounter += cumulative_time_delta; cur_timer->mStartTime = cur_time; - stack_record = &cur_timer->mLastTimerData; - stack_record->mChildTime += cumulative_time_delta; - if (stack_record->mAccumulator) - { - accumulator = stack_record->mAccumulator; - } + stack_record = &cur_timer->mParentTimerData; + accumulator = stack_record->mAccumulator; + cur_timer = stack_record->mActiveTimer; - cur_timer = cur_timer->mLastTimerData.mActiveTimer; + stack_record->mChildTime += cumulative_time_delta; } @@ -423,7 +425,8 @@ TimeBlockAccumulator::TimeBlockAccumulator() mLastAccumulator(NULL), mActiveCount(0), mMoveUpTree(false), - mParent(NULL) + mParent(NULL), + mBlock(NULL) {} void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other ) @@ -435,6 +438,7 @@ void TimeBlockAccumulator::addSamples( const TimeBlockAccumulator& other ) mActiveCount = other.mActiveCount; mMoveUpTree = other.mMoveUpTree; mParent = other.mParent; + mBlock = other.mBlock; } void TimeBlockAccumulator::reset( const TimeBlockAccumulator* other ) diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 2d87629561..06de8ea6ee 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -74,7 +74,7 @@ public: private: U64 mStartTime; - BlockTimerStackRecord mLastTimerData; + BlockTimerStackRecord mParentTimerData; }; // stores a "named" timer instance to be reused via multiple BlockTimer stack instances @@ -280,10 +280,11 @@ LL_FORCE_INLINE BlockTimer::BlockTimer(TimeBlock& timer) TimeBlockAccumulator* accumulator = timer.getPrimaryAccumulator(); accumulator->mActiveCount++; // keep current parent as long as it is active when we are + llassert(accumulator->mParent); accumulator->mMoveUpTree |= (accumulator->mParent->getPrimaryAccumulator()->mActiveCount == 0); // store top of stack - mLastTimerData = *cur_timer_data; + mParentTimerData = *cur_timer_data; // push new information cur_timer_data->mActiveTimer = this; cur_timer_data->mAccumulator = accumulator; @@ -305,13 +306,13 @@ LL_FORCE_INLINE BlockTimer::~BlockTimer() // store last caller to bootstrap tree creation // do this in the destructor in case of recursion to get topmost caller - accumulator->mLastAccumulator = mLastTimerData.mAccumulator; + accumulator->mLastAccumulator = mParentTimerData.mAccumulator; // we are only tracking self time, so subtract our total time delta from parents - mLastTimerData.mChildTime += total_time; + mParentTimerData.mChildTime += total_time; //pop stack - *cur_timer_data = mLastTimerData; + *cur_timer_data = mParentTimerData; #endif } diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h index c8b7c5e229..fd44589299 100644 --- a/indra/llcommon/llthreadlocalstorage.h +++ b/indra/llcommon/llthreadlocalstorage.h @@ -152,7 +152,7 @@ public: virtual ~LLThreadLocalSingleton() { #if LL_DARWIN - //pthread_setspecific(sInstanceKey, NULL); + pthread_setspecific(sInstanceKey, NULL); #else sInstance = NULL; #endif @@ -182,17 +182,12 @@ public: 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; - } - + createTLSInstance(); S32 result = pthread_setspecific(sInstanceKey, (void*)instancep); if (result != 0) { llerrs << "Could not set thread local storage" << llendl; - }*/ + } #else sInstance = instancep; #endif @@ -207,7 +202,7 @@ public: static DERIVED_TYPE* getIfExists() { #if LL_DARWIN - return NULL;//(DERIVED_TYPE*)pthread_getspecific(sInstanceKey); + return (DERIVED_TYPE*)pthread_getspecific(sInstanceKey); #else return sInstance; #endif @@ -235,22 +230,29 @@ public: } private: #if LL_DARWIN - static EInitState& threadLocalInitState() + static void createTLSInitState() + { + static S32 key_created = pthread_key_create(&sInitStateKey, NULL); + if (key_created != 0) + { + llerrs << "Could not create thread local storage" << llendl; + } + } + + static void createTLSInstance() { - /*static S32 sKeyCreated = pthread_key_create(&sInitStateKey, NULL); - if (sKeyCreated != 0) + static S32 key_created = pthread_key_create(&sInstanceKey, NULL); + if (key_created != 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(); + createTLSInitState(); + return (EInitState)(int)pthread_getspecific(sInitStateKey); #else return sInitState; #endif @@ -259,7 +261,8 @@ private: static void setInitState(EInitState state) { #if LL_DARWIN - threadLocalInitState() = state; + createTLSInitState(); + pthread_setspecific(sInitStateKey, (void*)state); #else sInitState = state; #endif @@ -274,8 +277,8 @@ private: static __thread DERIVED_TYPE* sInstance; static __thread EInitState sInitState; #elif LL_DARWIN - //static pthread_key_t sInstanceKey; - //static pthread_key_t sInitStateKey; + static pthread_key_t sInstanceKey; + static pthread_key_t sInitStateKey; #endif }; @@ -292,11 +295,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> +template<typename DERIVED_TYPE> pthread_key_t LLThreadLocalSingleton<DERIVED_TYPE>::sInstanceKey; template<typename DERIVED_TYPE> -pthread_key_t LLThreadLocalSingleton<DERIVED_TYPE>::sInitStateKey;*/ +pthread_key_t LLThreadLocalSingleton<DERIVED_TYPE>::sInitStateKey; + #endif template<typename DERIVED_TYPE> @@ -305,13 +309,14 @@ class LLThreadLocalSingletonPointer public: void operator =(DERIVED_TYPE* value) { - sInstance = value; + setInstance(value); } - + LL_FORCE_INLINE static DERIVED_TYPE* getInstance() { #if LL_DARWIN - return sInstance.get(); + createTLSKey(); + return (DERIVED_TYPE*)pthread_getspecific(sInstanceKey); #else return sInstance; #endif @@ -319,7 +324,12 @@ public: LL_FORCE_INLINE static void setInstance(DERIVED_TYPE* instance) { +#if LL_DARWIN + createTLSKey(); + pthread_setspecific(sInstanceKey, (void*)instance); +#else sInstance = instance; +#endif } private: @@ -328,7 +338,19 @@ private: #elif LL_LINUX static __thread DERIVED_TYPE* sInstance; #elif LL_DARWIN - static LLThreadLocalPointer<DERIVED_TYPE> sInstance; + static void TLSError() + { + llerrs << "Could not create thread local storage" << llendl; + } + static void createTLSKey() + { + static S32 key_created = pthread_key_create(&sInstanceKey, NULL); + if (key_created != 0) + { + llerrs << "Could not create thread local storage" << llendl; + } + } + static pthread_key_t sInstanceKey; #endif }; @@ -340,7 +362,7 @@ 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; +pthread_key_t LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstanceKey; #endif #endif // LL_LLTHREADLOCALSTORAGE_H diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index bc1d19e72c..7c5995a104 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -43,14 +43,16 @@ ThreadRecorder::ThreadRecorder() TimeBlock& root_time_block = TimeBlock::getRootTimeBlock(); ThreadTimerStack* timer_stack = ThreadTimerStack::getInstance(); - timer_stack->mAccumulator = root_time_block.getPrimaryAccumulator(); - timer_stack->mActiveTimer = NULL; mNumTimeBlockTreeNodes = AccumulatorBuffer<TimeBlockAccumulator>::getDefaultBuffer()->size(); mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes]; mThreadRecording.start(); + timer_stack->mAccumulator = root_time_block.getPrimaryAccumulator(); + timer_stack->mActiveTimer = NULL; + + // initialize time block parent pointers for (LLInstanceTracker<TimeBlock>::instance_iter it = LLInstanceTracker<TimeBlock>::beginInstances(), end_it = LLInstanceTracker<TimeBlock>::endInstances(); it != end_it; |