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
commit
ae6763f7fc
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue