Automated merge with bundle:c:\code\viewer-interesting+c:\users\richard\appdata\local\temp\thg.sszl0v\ssh__richard@hg.lindenlab.com_richard_viewer-interesting_kkjl59.hg

meow-7.2.2
Richard Linden 2013-05-30 19:00:08 -07:00
commit ae6763f7fc
6 changed files with 47 additions and 32 deletions

View File

@ -313,11 +313,6 @@ template<typename DERIVED_TYPE>
class LLThreadLocalSingletonPointer
{
public:
void operator =(DERIVED_TYPE* value)
{
setInstance(value);
}
LL_FORCE_INLINE static DERIVED_TYPE* getInstance()
{
#if LL_DARWIN
@ -328,7 +323,7 @@ public:
#endif
}
LL_FORCE_INLINE static void setInstance(DERIVED_TYPE* instance)
static void setInstance(DERIVED_TYPE* instance)
{
#if LL_DARWIN
createTLSKey();
@ -339,6 +334,7 @@ public:
}
private:
#if LL_WINDOWS
static __declspec(thread) DERIVED_TYPE* sInstance;
#elif LL_LINUX

View File

@ -35,6 +35,7 @@
#include "llunit.h"
#include "llapr.h"
#include "llthreadlocalstorage.h"
#include "lltimer.h"
#include <list>
@ -75,7 +76,6 @@ void set_thread_recorder(class ThreadRecorder*);
class MasterThreadRecorder& getUIThreadRecorder();
// one per thread per type
template<typename ACCUMULATOR>
class AccumulatorBuffer : public LLRefCount
{
@ -104,9 +104,9 @@ public:
~AccumulatorBuffer()
{
if (LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance() == mStorage)
if (isPrimary())
{
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(getDefaultBuffer()->mStorage);
LLThreadLocalSingletonPointer<ACCUMULATOR>::setInstance(NULL);
}
delete[] mStorage;
}
@ -169,7 +169,8 @@ public:
LL_FORCE_INLINE static ACCUMULATOR* getPrimaryStorage()
{
return LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance();
ACCUMULATOR* accumulator = LLThreadLocalSingletonPointer<ACCUMULATOR>::getInstance();
return accumulator ? accumulator : sDefaultBuffer->mStorage;
}
// NOTE: this is not thread-safe. We assume that slots are reserved in the main thread before any child threads are spawned
@ -222,25 +223,27 @@ public:
static self_t* getDefaultBuffer()
{
// this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data
// so as not to trigger an access violation
static self_t* sBuffer = new AccumulatorBuffer(StaticAllocationMarker());
static bool sInitialized = false;
if (!sInitialized)
{
sBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE);
// this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data
// so as not to trigger an access violation
sDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker());
sInitialized = true;
sDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE);
}
return sBuffer;
return sDefaultBuffer;
}
private:
ACCUMULATOR* mStorage;
size_t mStorageSize;
static size_t sNextStorageSlot;
static self_t* sDefaultBuffer;
};
template<typename ACCUMULATOR> size_t AccumulatorBuffer<ACCUMULATOR>::sNextStorageSlot = 0;
template<typename ACCUMULATOR> AccumulatorBuffer<ACCUMULATOR>* AccumulatorBuffer<ACCUMULATOR>::sDefaultBuffer = NULL;
template<typename ACCUMULATOR>
class TraceType

View File

@ -490,8 +490,9 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other )
{
if (mAutoResize)
{
for (S32 other_index = (other.mCurPeriod + 2) % other_recording_count;
other_index != other.mCurPeriod;
for (S32 other_index = (other.mCurPeriod + 2) % other_recording_count,
end_index = (other.mCurPeriod + 1) % other_recording_count;
other_index != end_index;
other_index = (other_index + 1) % other_recording_count)
{
llassert(other.mRecordingPeriods[other_index].getDuration() != 0.f

View File

@ -336,12 +336,12 @@ namespace LLTrace
}
template <typename T>
typename T getPeriodMin(const TraceType<SampleAccumulator<T> >& stat, size_t num_periods = U32_MAX) const
T getPeriodMin(const TraceType<SampleAccumulator<T> >& stat, size_t num_periods = U32_MAX) const
{
size_t total_periods = mRecordingPeriods.size();
num_periods = llmin(num_periods, total_periods);
typename T min_val = std::numeric_limits<T>::max();
T min_val = std::numeric_limits<T>::max();
for (S32 i = 1; i <= num_periods; i++)
{
S32 index = (mCurPeriod + total_periods - i) % total_periods;
@ -351,7 +351,7 @@ namespace LLTrace
}
template <typename T>
typename T getPeriodMin(const TraceType<EventAccumulator<T> >& stat, size_t num_periods = U32_MAX) const
T getPeriodMin(const TraceType<EventAccumulator<T> >& stat, size_t num_periods = U32_MAX) const
{
size_t total_periods = mRecordingPeriods.size();
num_periods = llmin(num_periods, total_periods);

View File

@ -202,14 +202,21 @@ SlaveThreadRecorder::~SlaveThreadRecorder()
mMasterRecorder.removeSlaveThread(this);
}
void SlaveThreadRecorder::pushToMaster()
bool SlaveThreadRecorder::pushToMaster()
{
mThreadRecording.stop();
if (mPushCount != mMasterRecorder.getPullCount())
{
LLMutexLock(mMasterRecorder.getSlaveListMutex());
mSharedData.appendFrom(mThreadRecording);
mThreadRecording.stop();
{
LLMutexLock(mMasterRecorder.getSlaveListMutex());
mSharedData.appendFrom(mThreadRecording);
}
mThreadRecording.start();
mPushCount = mMasterRecorder.getPullCount();
return true;
}
mThreadRecording.start();
return false;
}
void SlaveThreadRecorder::SharedData::appendFrom( const Recording& source )
@ -264,6 +271,8 @@ void MasterThreadRecorder::pullFromSlaveThreads()
(*it)->mSharedData.mergeTo(target_recording_buffers);
(*it)->mSharedData.reset();
}
mPullCount++;
}
void MasterThreadRecorder::addSlaveThread( class SlaveThreadRecorder* child )
@ -289,8 +298,10 @@ void MasterThreadRecorder::removeSlaveThread( class SlaveThreadRecorder* child )
}
}
void MasterThreadRecorder::pushToMaster()
{}
bool MasterThreadRecorder::pushToMaster()
{
return false;
}
MasterThreadRecorder::MasterThreadRecorder()
{}

View File

@ -49,7 +49,7 @@ namespace LLTrace
void deactivate(Recording* recording);
active_recording_list_t::reverse_iterator bringUpToDate(Recording* recording);
virtual void pushToMaster() = 0;
virtual bool pushToMaster() = 0;
TimeBlockTreeNode* getTimeBlockTreeNode(S32 index);
@ -80,19 +80,22 @@ namespace LLTrace
void addSlaveThread(class SlaveThreadRecorder* child);
void removeSlaveThread(class SlaveThreadRecorder* child);
/*virtual */ void pushToMaster();
/*virtual */ bool pushToMaster();
// call this periodically to gather stats data from slave threads
void pullFromSlaveThreads();
LLMutex* getSlaveListMutex() { return &mSlaveListMutex; }
U32 getPullCount() { return mPullCount; }
private:
typedef std::list<class SlaveThreadRecorder*> slave_thread_recorder_list_t;
slave_thread_recorder_list_t mSlaveThreadRecorders;
LLMutex mSlaveListMutex;
slave_thread_recorder_list_t mSlaveThreadRecorders; // list of slave thread recorders associated with this master
LLMutex mSlaveListMutex; // protects access to slave list
LLAtomicU32 mPullCount; // number of times data has been pulled from slaves
};
class LL_COMMON_API SlaveThreadRecorder : public ThreadRecorder
@ -102,7 +105,7 @@ namespace LLTrace
~SlaveThreadRecorder();
// call this periodically to gather stats data for master thread to consume
/*virtual*/ void pushToMaster();
/*virtual*/ bool pushToMaster();
MasterThreadRecorder* mMaster;
@ -119,6 +122,7 @@ namespace LLTrace
};
SharedData mSharedData;
MasterThreadRecorder& mMasterRecorder;
U32 mPushCount;
};
}