added initial memory usage tracking for lltrace
parent
b3d42e9b99
commit
754e8752a9
|
|
@ -33,6 +33,8 @@
|
|||
namespace LLTrace
|
||||
{
|
||||
|
||||
MemStatHandle gTraceMemStat("LLTrace");
|
||||
|
||||
TraceBase::TraceBase( const char* name, const char* description )
|
||||
: mName(name),
|
||||
mDescription(description ? description : "")
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ struct MeasureMem<std::basic_string<T>, IS_MEM_TRACKABLE, IS_BYTES>
|
|||
|
||||
|
||||
template<typename T>
|
||||
inline void claim_footprint(MemStatHandle& measurement, const T& value)
|
||||
inline void claim_alloc(MemStatHandle& measurement, const T& value)
|
||||
{
|
||||
S32 size = MeasureMem<T>::measureFootprint(value);
|
||||
if(size == 0) return;
|
||||
|
|
@ -330,7 +330,7 @@ inline void claim_footprint(MemStatHandle& measurement, const T& value)
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
inline void disclaim_footprint(MemStatHandle& measurement, const T& value)
|
||||
inline void disclaim_alloc(MemStatHandle& measurement, const T& value)
|
||||
{
|
||||
S32 size = MeasureMem<T>::measureFootprint(value);
|
||||
if(size == 0) return;
|
||||
|
|
@ -370,25 +370,25 @@ public:
|
|||
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
claim_footprint(sMemStat, size);
|
||||
claim_alloc(sMemStat, size);
|
||||
return ll_aligned_malloc(ALIGNMENT, size);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr, size_t size)
|
||||
{
|
||||
disclaim_footprint(sMemStat, size);
|
||||
disclaim_alloc(sMemStat, size);
|
||||
ll_aligned_free(ALIGNMENT, ptr);
|
||||
}
|
||||
|
||||
void* operator new [](size_t size)
|
||||
{
|
||||
claim_footprint(sMemStat, size);
|
||||
claim_alloc(sMemStat, size);
|
||||
return ll_aligned_malloc(ALIGNMENT, size);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr, size_t size)
|
||||
{
|
||||
disclaim_footprint(sMemStat, size);
|
||||
disclaim_alloc(sMemStat, size);
|
||||
ll_aligned_free(ALIGNMENT, ptr);
|
||||
}
|
||||
|
||||
|
|
@ -397,7 +397,7 @@ public:
|
|||
void claimMem(const CLAIM_T& value) const
|
||||
{
|
||||
S32 size = MeasureMem<CLAIM_T>::measureFootprint(value);
|
||||
claim_footprint(sMemStat, size);
|
||||
claim_alloc(sMemStat, size);
|
||||
mMemFootprint += size;
|
||||
}
|
||||
|
||||
|
|
@ -406,7 +406,7 @@ public:
|
|||
void disclaimMem(const CLAIM_T& value) const
|
||||
{
|
||||
S32 size = MeasureMem<CLAIM_T>::measureFootprint(value);
|
||||
disclaim_footprint(sMemStat, size);
|
||||
disclaim_alloc(sMemStat, size);
|
||||
mMemFootprint -= size;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,18 +26,36 @@
|
|||
#include "linden_common.h"
|
||||
|
||||
#include "lltraceaccumulators.h"
|
||||
#include "lltrace.h"
|
||||
#include "lltracethreadrecorder.h"
|
||||
|
||||
namespace LLTrace
|
||||
{
|
||||
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// AccumulatorBufferGroup
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccumulatorBufferGroup::AccumulatorBufferGroup()
|
||||
{}
|
||||
{
|
||||
/*claim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
claim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
claim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
claim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
claim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemStatAccumulator));*/
|
||||
}
|
||||
|
||||
AccumulatorBufferGroup::~AccumulatorBufferGroup()
|
||||
{
|
||||
/*disclaim_alloc(gTraceMemStat, mCounts.capacity() * sizeof(CountAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mSamples.capacity() * sizeof(SampleAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mEvents.capacity() * sizeof(EventAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mStackTimers.capacity() * sizeof(TimeBlockAccumulator));
|
||||
disclaim_alloc(gTraceMemStat, mMemStats.capacity() * sizeof(MemStatAccumulator));*/
|
||||
}
|
||||
|
||||
void AccumulatorBufferGroup::handOffTo(AccumulatorBufferGroup& other)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -188,6 +188,11 @@ namespace LLTrace
|
|||
return getNumIndices();
|
||||
}
|
||||
|
||||
size_t capacity() const
|
||||
{
|
||||
return mStorageSize;
|
||||
}
|
||||
|
||||
static size_t getNumIndices()
|
||||
{
|
||||
return sNextStorageSlot;
|
||||
|
|
@ -536,6 +541,7 @@ namespace LLTrace
|
|||
struct AccumulatorBufferGroup : public LLRefCount
|
||||
{
|
||||
AccumulatorBufferGroup();
|
||||
~AccumulatorBufferGroup();
|
||||
|
||||
void handOffTo(AccumulatorBufferGroup& other);
|
||||
void makeCurrent();
|
||||
|
|
|
|||
|
|
@ -25,15 +25,18 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "lltracerecording.h"
|
||||
|
||||
#include "lltrace.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "lltracerecording.h"
|
||||
#include "lltracethreadrecorder.h"
|
||||
#include "llthread.h"
|
||||
|
||||
namespace LLTrace
|
||||
{
|
||||
|
||||
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Recording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -42,12 +45,15 @@ Recording::Recording(EPlayState state)
|
|||
: mElapsedSeconds(0),
|
||||
mInHandOff(false)
|
||||
{
|
||||
claim_alloc(gTraceMemStat, sizeof(*this));
|
||||
mBuffers = new AccumulatorBufferGroup();
|
||||
claim_alloc(gTraceMemStat, mBuffers);
|
||||
setPlayState(state);
|
||||
}
|
||||
|
||||
Recording::Recording( const Recording& other )
|
||||
{
|
||||
claim_alloc(gTraceMemStat, sizeof(*this));
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +79,9 @@ Recording& Recording::operator = (const Recording& other)
|
|||
|
||||
Recording::~Recording()
|
||||
{
|
||||
disclaim_alloc(gTraceMemStat, sizeof(*this));
|
||||
disclaim_alloc(gTraceMemStat, mBuffers);
|
||||
|
||||
if (isStarted() && LLTrace::get_thread_recorder().notNull())
|
||||
{
|
||||
LLTrace::get_thread_recorder()->deactivate(mBuffers.write());
|
||||
|
|
@ -330,6 +339,12 @@ PeriodicRecording::PeriodicRecording( S32 num_periods, EPlayState state)
|
|||
mRecordingPeriods(num_periods ? num_periods : 1)
|
||||
{
|
||||
setPlayState(state);
|
||||
claim_alloc(gTraceMemStat, sizeof(*this));
|
||||
}
|
||||
|
||||
PeriodicRecording::~PeriodicRecording()
|
||||
{
|
||||
disclaim_alloc(gTraceMemStat, sizeof(*this));
|
||||
}
|
||||
|
||||
void PeriodicRecording::nextPeriod()
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ namespace LLTrace
|
|||
class ThreadRecorder* getThreadRecorder();
|
||||
|
||||
LLTimer mSamplingTimer;
|
||||
F64Seconds mElapsedSeconds;
|
||||
F64Seconds mElapsedSeconds;
|
||||
LLCopyOnWritePointer<AccumulatorBufferGroup> mBuffers;
|
||||
bool mInHandOff;
|
||||
|
||||
|
|
@ -324,6 +324,7 @@ namespace LLTrace
|
|||
{
|
||||
public:
|
||||
PeriodicRecording(S32 num_periods, EPlayState state = STOPPED);
|
||||
~PeriodicRecording();
|
||||
|
||||
void nextPeriod();
|
||||
S32 getNumRecordedPeriods() { return mNumPeriods; }
|
||||
|
|
|
|||
|
|
@ -27,9 +27,11 @@
|
|||
|
||||
#include "lltracethreadrecorder.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "lltrace.h"
|
||||
|
||||
namespace LLTrace
|
||||
{
|
||||
extern MemStatHandle gTraceMemStat;
|
||||
|
||||
static ThreadRecorder* sMasterThreadRecorder = NULL;
|
||||
|
||||
|
|
@ -55,6 +57,7 @@ void ThreadRecorder::init()
|
|||
timer_stack->mActiveTimer = NULL;
|
||||
|
||||
mNumTimeBlockTreeNodes = AccumulatorBuffer<TimeBlockAccumulator>::getDefaultBuffer()->size();
|
||||
|
||||
mTimeBlockTreeNodes = new TimeBlockTreeNode[mNumTimeBlockTreeNodes];
|
||||
|
||||
activate(&mThreadRecordingBuffers);
|
||||
|
|
@ -76,10 +79,14 @@ void ThreadRecorder::init()
|
|||
timer_stack->mActiveTimer = mRootTimer;
|
||||
|
||||
TimeBlock::getRootTimeBlock().getCurrentAccumulator().mActiveCount = 1;
|
||||
|
||||
claim_alloc(gTraceMemStat, sizeof(*this));
|
||||
claim_alloc(gTraceMemStat, sizeof(BlockTimer));
|
||||
claim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
}
|
||||
|
||||
|
||||
ThreadRecorder::ThreadRecorder(ThreadRecorder& master)
|
||||
ThreadRecorder::ThreadRecorder( ThreadRecorder& master )
|
||||
: mMasterRecorder(&master)
|
||||
{
|
||||
init();
|
||||
|
|
@ -91,6 +98,10 @@ ThreadRecorder::~ThreadRecorder()
|
|||
{
|
||||
LLThreadLocalSingletonPointer<BlockTimerStackRecord>::setInstance(NULL);
|
||||
|
||||
disclaim_alloc(gTraceMemStat, sizeof(*this));
|
||||
disclaim_alloc(gTraceMemStat, sizeof(BlockTimer));
|
||||
disclaim_alloc(gTraceMemStat, sizeof(TimeBlockTreeNode) * mNumTimeBlockTreeNodes);
|
||||
|
||||
deactivate(&mThreadRecordingBuffers);
|
||||
|
||||
delete mRootTimer;
|
||||
|
|
@ -135,9 +146,9 @@ void ThreadRecorder::activate( AccumulatorBufferGroup* recording, bool from_hand
|
|||
mActiveRecordings.back()->mPartialRecording.makeCurrent();
|
||||
}
|
||||
|
||||
ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording )
|
||||
ThreadRecorder::active_recording_list_t::iterator ThreadRecorder::bringUpToDate( AccumulatorBufferGroup* recording )
|
||||
{
|
||||
if (mActiveRecordings.empty()) return mActiveRecordings.rend();
|
||||
if (mActiveRecordings.empty()) return mActiveRecordings.end();
|
||||
|
||||
mActiveRecordings.back()->mPartialRecording.sync();
|
||||
TimeBlock::updateTimes();
|
||||
|
|
@ -174,15 +185,14 @@ ThreadRecorder::active_recording_list_t::reverse_iterator ThreadRecorder::bringU
|
|||
LL_WARNS() << "Recording not active on this thread" << LL_ENDL;
|
||||
}
|
||||
|
||||
return it;
|
||||
return (++it).base();
|
||||
}
|
||||
|
||||
void ThreadRecorder::deactivate( AccumulatorBufferGroup* recording )
|
||||
{
|
||||
active_recording_list_t::reverse_iterator it = bringUpToDate(recording);
|
||||
if (it != mActiveRecordings.rend())
|
||||
active_recording_list_t::iterator recording_to_remove = bringUpToDate(recording);
|
||||
if (recording_to_remove != mActiveRecordings.end())
|
||||
{
|
||||
active_recording_list_t::iterator recording_to_remove = (++it).base();
|
||||
bool was_current = (*recording_to_remove)->mPartialRecording.isCurrent();
|
||||
llassert((*recording_to_remove)->mTargetRecording == recording);
|
||||
delete *recording_to_remove;
|
||||
|
|
@ -216,25 +226,33 @@ void ThreadRecorder::ActiveRecording::movePartialToTarget()
|
|||
|
||||
// called by child thread
|
||||
void ThreadRecorder::addChildRecorder( class ThreadRecorder* child )
|
||||
{ LLMutexLock lock(&mChildListMutex);
|
||||
mChildThreadRecorders.push_back(child);
|
||||
{
|
||||
{ LLMutexLock lock(&mChildListMutex);
|
||||
mChildThreadRecorders.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
// called by child thread
|
||||
void ThreadRecorder::removeChildRecorder( class ThreadRecorder* child )
|
||||
{ LLMutexLock lock(&mChildListMutex);
|
||||
|
||||
for (child_thread_recorder_list_t::iterator it = mChildThreadRecorders.begin(), end_it = mChildThreadRecorders.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
if ((*it) == child)
|
||||
{
|
||||
mChildThreadRecorders.erase(it);
|
||||
break;
|
||||
{
|
||||
{ LLMutexLock lock(&mChildListMutex);
|
||||
for (child_thread_recorder_list_t::iterator it = mChildThreadRecorders.begin(), end_it = mChildThreadRecorders.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
if ((*it) == child)
|
||||
{
|
||||
// FIXME: this won't do any good, as the child stores the "pushed" values internally
|
||||
// and it is in the process of being deleted.
|
||||
// We need a way to finalize the stats from the outgoing thread, but the storage
|
||||
// for those stats needs to be outside the child's thread recorder
|
||||
//(*it)->pushToParent();
|
||||
mChildThreadRecorders.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadRecorder::pushToParent()
|
||||
{
|
||||
|
|
@ -269,7 +287,7 @@ void ThreadRecorder::pullFromChildren()
|
|||
}
|
||||
|
||||
|
||||
void set_master_thread_recorder(ThreadRecorder* recorder)
|
||||
void set_master_thread_recorder( ThreadRecorder* recorder )
|
||||
{
|
||||
sMasterThreadRecorder = recorder;
|
||||
}
|
||||
|
|
@ -291,7 +309,7 @@ const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder()
|
|||
return get_thread_recorder_ptr();
|
||||
}
|
||||
|
||||
void set_thread_recorder(ThreadRecorder* recorder)
|
||||
void set_thread_recorder( ThreadRecorder* recorder )
|
||||
{
|
||||
get_thread_recorder_ptr() = recorder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace LLTrace
|
|||
|
||||
void activate(AccumulatorBufferGroup* recording, bool from_handoff = false);
|
||||
void deactivate(AccumulatorBufferGroup* recording);
|
||||
active_recording_list_t::reverse_iterator bringUpToDate(AccumulatorBufferGroup* recording);
|
||||
active_recording_list_t::iterator bringUpToDate(AccumulatorBufferGroup* recording);
|
||||
|
||||
void addChildRecorder(class ThreadRecorder* child);
|
||||
void removeChildRecorder(class ThreadRecorder* child);
|
||||
|
|
|
|||
|
|
@ -1190,7 +1190,7 @@ void LLVertexBuffer::createGLBuffer(U32 size)
|
|||
mMappedData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
|
||||
disclaimMem(mSize);
|
||||
mSize = size;
|
||||
disclaimMem(mSize);
|
||||
claimMem(mSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2272,10 +2272,10 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
|
|||
|
||||
if (unsatisfied_mask & (1 << TYPE_INDEX))
|
||||
{
|
||||
llinfos << "Missing indices" << llendl;
|
||||
LL_INFOS() << "Missing indices" << LL_ENDL;
|
||||
}
|
||||
|
||||
llerrs << "Shader consumption mismatches data provision." << llendl;
|
||||
LL_ERRS() << "Shader consumption mismatches data provision." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2983,6 +2983,17 @@
|
|||
<key>Value</key>
|
||||
<string>Female Shape & Outfit</string>
|
||||
</map>
|
||||
<key>DefaultLoginLocation</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Startup destination default (if not specified on command line)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
</map>
|
||||
<key>DefaultMaleAvatar</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -2653,10 +2653,26 @@ bool LLAppViewer::initConfiguration()
|
|||
// What can happen is that someone can use IE (or potentially
|
||||
// other browsers) and do the rough equivalent of command
|
||||
// injection and steal passwords. Phoenix. SL-55321
|
||||
std::string CmdLineLoginLocation(gSavedSettings.getString("CmdLineLoginLocation"));
|
||||
if(! CmdLineLoginLocation.empty())
|
||||
|
||||
std::string starting_location;
|
||||
|
||||
std::string cmd_line_login_location(gSavedSettings.getString("CmdLineLoginLocation"));
|
||||
if(! cmd_line_login_location.empty())
|
||||
{
|
||||
LLSLURL start_slurl(CmdLineLoginLocation);
|
||||
starting_location = cmd_line_login_location;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string default_login_location(gSavedSettings.getString("DefaultLoginLocation"));
|
||||
if (! default_login_location.empty())
|
||||
{
|
||||
starting_location = default_login_location;
|
||||
}
|
||||
}
|
||||
|
||||
if (! starting_location.empty())
|
||||
{
|
||||
LLSLURL start_slurl(starting_location);
|
||||
LLStartUp::setStartSLURL(start_slurl);
|
||||
if(start_slurl.getType() == LLSLURL::LOCATION)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4756,7 +4756,7 @@ bool LLViewerObject::isImageAlphaBlended(const U8 te) const
|
|||
case GL_RGB: break;
|
||||
default:
|
||||
{
|
||||
llwarns << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << llendl;
|
||||
LL_WARNS() << "Unexpected tex format in LLViewerObject::isImageAlphaBlended...returning no alpha." << LL_ENDL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,9 @@
|
|||
</stat_view>
|
||||
<stat_view name="memory"
|
||||
label="Memory Usage">
|
||||
<stat_bar name="LLTrace"
|
||||
label="LLTrace"
|
||||
stat="LLTrace"/>
|
||||
<stat_bar name="LLView"
|
||||
label="UI"
|
||||
stat="LLView"/>
|
||||
|
|
|
|||
Loading…
Reference in New Issue