summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/CMakeLists.txt1
-rw-r--r--indra/llcommon/llapr.cpp71
-rw-r--r--indra/llcommon/llfasttimer.cpp28
-rw-r--r--indra/llcommon/llfasttimer.h19
-rw-r--r--indra/llcommon/llmemory.h14
-rw-r--r--indra/llcommon/llthreadlocalstorage.cpp101
-rw-r--r--indra/llcommon/llthreadlocalstorage.h109
-rw-r--r--indra/llcommon/lltrace.h91
-rw-r--r--indra/llcommon/lltracerecording.cpp46
-rw-r--r--indra/llcommon/lltracerecording.h21
-rw-r--r--indra/llcommon/lltracethreadrecorder.cpp6
-rw-r--r--indra/llcommon/llunit.h8
12 files changed, 350 insertions, 165 deletions
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>