added initial memory usage tracking for lltrace

master
Richard Linden 2013-10-03 14:30:34 -07:00
parent b3d42e9b99
commit 754e8752a9
13 changed files with 132 additions and 42 deletions

View File

@ -33,6 +33,8 @@
namespace LLTrace
{
MemStatHandle gTraceMemStat("LLTrace");
TraceBase::TraceBase( const char* name, const char* description )
: mName(name),
mDescription(description ? description : "")

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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();

View File

@ -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()

View File

@ -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; }

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -2983,6 +2983,17 @@
<key>Value</key>
<string>Female Shape &amp; 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>

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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"/>