diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 1738c16dea4be7ef1ac72c80a0f4a01e9b3fdf48..a741d342d30d072bfdef97bb9b0232f88f87921c 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -111,6 +111,8 @@ void LLQueuedThread::shutdown()
 // virtual
 S32 LLQueuedThread::update(F32 max_time_ms)
 {
+	LLThread::getTraceData()->pushToMaster();
+
 	if (!mStarted)
 	{
 		if (!mThreaded)
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 2e6eb085dcc02001f5638bbb6ac119f80586f8de..2ff524d9bab7b368f340749fd531750ce3ce2fee 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -66,7 +66,7 @@ U32 __thread LLThread::sThreadID = 0;
 #endif
 
 U32 LLThread::sIDIter = 0;
-LLThreadLocalPtr<LLTrace::SlaveThreadTrace> LLThread::sTraceData;
+LLThreadLocalPtr<LLTrace::ThreadTrace> LLThread::sTraceData;
 
 
 LL_COMMON_API void assert_main_thread()
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 6889fab2c197deab3d35111165f5a1dbf9a37fb9..5cd287ec39f6c3f0f0185240223f1a9216a84b0b 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -87,7 +87,8 @@ class LL_COMMON_API LLThread
 
 	U32 getID() const { return mID; }
 
-	static LLTrace::ThreadTraceData* getTraceData() { return sTraceData.get(); }
+	static LLTrace::ThreadTrace* getTraceData() { return sTraceData.get(); }
+	static void setTraceData(LLTrace::ThreadTrace* data) { sTraceData = data;}
 
 private:
 	BOOL				mPaused;
@@ -105,7 +106,7 @@ class LL_COMMON_API LLThread
 	EThreadStatus		mStatus;
 	U32					mID;
 
-	static LLThreadLocalPtr<LLTrace::SlaveThreadTrace> sTraceData;
+	static LLThreadLocalPtr<LLTrace::ThreadTrace> sTraceData;
 
 	//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
 	//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp
index 8cedcafd10eec028e490178efb253199384abf6e..24a2b33a5f1addc271c802a3f6eb6a8662f381b1 100644
--- a/indra/llcommon/lltrace.cpp
+++ b/indra/llcommon/lltrace.cpp
@@ -72,11 +72,69 @@ void Sampler::resume()
 	getThreadTrace()->activate(this);
 }
 
-class ThreadTraceData* Sampler::getThreadTrace()
+class ThreadTrace* Sampler::getThreadTrace()
 {
 	return LLThread::getTraceData();
 }
 
+///////////////////////////////////////////////////////////////////////
+// MasterThreadTrace
+///////////////////////////////////////////////////////////////////////
+
+ThreadTrace::ThreadTrace()
+{
+	mPrimarySampler.makePrimary();
+}
+
+ThreadTrace::ThreadTrace( const ThreadTrace& other ) :	mPrimarySampler(other.mPrimarySampler)
+{
+	mPrimarySampler.makePrimary();
+}
+
+void ThreadTrace::activate( Sampler* sampler )
+{
+	flushPrimary();
+	mActiveSamplers.push_back(sampler);
+}
+
+void ThreadTrace::deactivate( Sampler* sampler )
+{
+	sampler->mergeFrom(mPrimarySampler);
+
+	// TODO: replace with intrusive list
+	std::list<Sampler*>::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler);
+	if (found_it != mActiveSamplers.end())
+	{
+		mActiveSamplers.erase(found_it);
+	}
+}
+
+void ThreadTrace::flushPrimary()
+{
+	for (std::list<Sampler*>::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end();
+		it != end_it;
+		++it)
+	{
+		(*it)->mergeFrom(mPrimarySampler);
+	}
+	mPrimarySampler.reset();
+}
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////
+// SlaveThreadTrace
+///////////////////////////////////////////////////////////////////////
+
+void SlaveThreadTrace::pushToMaster()
+{
+	mSharedData.copyFrom(mPrimarySampler);
+}
+
+
 ///////////////////////////////////////////////////////////////////////
 // MasterThreadTrace
 ///////////////////////////////////////////////////////////////////////
@@ -116,5 +174,16 @@ void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child )
 	}
 }
 
+void MasterThreadTrace::pushToMaster()
+{
+
+}
+
+MasterThreadTrace::MasterThreadTrace()
+{
+	LLThread::setTraceData(this);
+}
+
+
 }
 
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index e4bec0a64406651039291200a62da76b5efa7057..601b5ed182faf46a6ec1286cfbc67f50c2779c4b 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -396,7 +396,7 @@ namespace LLTrace
 
 	private:
 		// returns data for current thread
-		class ThreadTraceData* getThreadTrace(); 
+		class ThreadTrace* getThreadTrace(); 
 
 		AccumulatorBuffer<StatAccumulator<F32> >	mF32Stats;
 		AccumulatorBuffer<StatAccumulator<S32> >	mS32Stats;
@@ -404,48 +404,19 @@ namespace LLTrace
 		AccumulatorBuffer<TimerAccumulator>			mTimers;
 	};
 
-	class ThreadTraceData
+	class ThreadTrace
 	{
 	public:
-		ThreadTraceData()
-		{
-			mPrimarySampler.makePrimary();
-		}
-
-		ThreadTraceData(const ThreadTraceData& other)
-		:	mPrimarySampler(other.mPrimarySampler)
-		{
-			mPrimarySampler.makePrimary();
-		}
+		ThreadTrace();
+		ThreadTrace(const ThreadTrace& other);
 
-		void activate(Sampler* sampler)
-		{
-			flushPrimary();
-			mActiveSamplers.push_back(sampler);
-		}
+		virtual ~ThreadTrace() {}
 
-		void deactivate(Sampler* sampler)
-		{
-			sampler->mergeFrom(mPrimarySampler);
-
-			// TODO: replace with intrusive list
-			std::list<Sampler*>::iterator found_it = std::find(mActiveSamplers.begin(), mActiveSamplers.end(), sampler);
-			if (found_it != mActiveSamplers.end())
-			{
-				mActiveSamplers.erase(found_it);
-			}
-		}
+		void activate(Sampler* sampler);
+		void deactivate(Sampler* sampler);
+		void flushPrimary();
 
-		void flushPrimary()
-		{
-			for (std::list<Sampler*>::iterator it = mActiveSamplers.begin(), end_it = mActiveSamplers.end();
-				it != end_it;
-				++it)
-			{
-				(*it)->mergeFrom(mPrimarySampler);
-			}
-			mPrimarySampler.reset();
-		}
+		virtual void pushToMaster() = 0;
 
 		Sampler* getPrimarySampler() { return &mPrimarySampler; }
 	protected:
@@ -453,15 +424,16 @@ namespace LLTrace
 		std::list<Sampler*>		mActiveSamplers;
 	};
 
-	class MasterThreadTrace : public ThreadTraceData
+	class MasterThreadTrace : public ThreadTrace
 	{
 	public:
-		MasterThreadTrace()
-		{}
+		MasterThreadTrace();
 
 		void addSlaveThread(class SlaveThreadTrace* child);
 		void removeSlaveThread(class SlaveThreadTrace* child);
 
+		/*virtual */ void pushToMaster();
+
 		// call this periodically to gather stats data from slave threads
 		void pullFromSlaveThreads();
 
@@ -480,12 +452,12 @@ namespace LLTrace
 		LLMutex							mSlaveListMutex;
 	};
 
-	class SlaveThreadTrace : public ThreadTraceData
+	class SlaveThreadTrace : public ThreadTrace
 	{
 	public:
 		explicit 
 		SlaveThreadTrace()
-		:	ThreadTraceData(getMasterThreadTrace()),
+		:	ThreadTrace(getMasterThreadTrace()),
 			mSharedData(mPrimarySampler)
 		{
 			getMasterThreadTrace().addSlaveThread(this);
@@ -497,10 +469,7 @@ namespace LLTrace
 		}
 
 		// call this periodically to gather stats data for master thread to consume
-		void pushToParent()
-		{
-			mSharedData.copyFrom(mPrimarySampler);
-		}
+		/*virtual*/ void pushToMaster();
 
 		MasterThreadTrace* 	mMaster;
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c3ac6151695f7e8541b140bf58a4f80e6e57f574..fcbef491fef7095e5f6c445f8b395d9e07c06bda 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1222,6 +1222,7 @@ bool LLAppViewer::mainLoop()
 	{
 		LLFastTimer _(FTM_FRAME);
 		LLFastTimer::nextFrame(); 
+		LLTrace::getMasterThreadTrace().pullFromSlaveThreads();
 
 		//clear call stack records
 		llclearcallstacks;