PageRenderTime 35ms CodeModel.GetById 12ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/llfasttimer_class.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 276 lines | 175 code | 56 blank | 45 comment | 1 complexity | 402f0bedfb2b4cd82e8f8237b8907e1c MD5 | raw file
  1/**
  2 * @file llfasttimer_class.h
  3 * @brief Declaration of a fast timer.
  4 *
  5 * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_FASTTIMER_CLASS_H
 28#define LL_FASTTIMER_CLASS_H
 29
 30#include "llinstancetracker.h"
 31
 32#define FAST_TIMER_ON 1
 33#define TIME_FAST_TIMERS 0
 34#define DEBUG_FAST_TIMER_THREADS 1
 35
 36class LLMutex;
 37
 38#include <queue>
 39#include "llsd.h"
 40
 41LL_COMMON_API void assert_main_thread();
 42
 43class LL_COMMON_API LLFastTimer
 44{
 45public:
 46	class NamedTimer;
 47
 48	struct LL_COMMON_API FrameState
 49	{
 50		FrameState(NamedTimer* timerp);
 51
 52		U32 				mSelfTimeCounter;
 53		U32 				mCalls;
 54		FrameState*			mParent;		// info for caller timer
 55		FrameState*			mLastCaller;	// used to bootstrap tree construction
 56		NamedTimer*			mTimer;
 57		U16					mActiveCount;	// number of timers with this ID active on stack
 58		bool				mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame
 59	};
 60
 61	// stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
 62	class LL_COMMON_API NamedTimer
 63	:	public LLInstanceTracker<NamedTimer>
 64	{
 65		friend class DeclareTimer;
 66	public:
 67		~NamedTimer();
 68
 69		enum { HISTORY_NUM = 300 };
 70
 71		const std::string& getName() const { return mName; }
 72		NamedTimer* getParent() const { return mParent; }
 73		void setParent(NamedTimer* parent);
 74		S32 getDepth();
 75		std::string getToolTip(S32 history_index = -1);
 76
 77		typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
 78		child_const_iter beginChildren();
 79		child_const_iter endChildren();
 80		std::vector<NamedTimer*>& getChildren();
 81
 82		void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
 83		bool getCollapsed() const { return mCollapsed; }
 84
 85		U32 getCountAverage() const { return mCountAverage; }
 86		U32 getCallAverage() const { return mCallAverage; }
 87
 88		U32 getHistoricalCount(S32 history_index = 0) const;
 89		U32 getHistoricalCalls(S32 history_index = 0) const;
 90
 91		static NamedTimer& getRootNamedTimer();
 92
 93		S32 getFrameStateIndex() const { return mFrameStateIndex; }
 94
 95		FrameState& getFrameState() const;
 96
 97	private:
 98		friend class LLFastTimer;
 99		friend class NamedTimerFactory;
100
101		//
102		// methods
103		//
104		NamedTimer(const std::string& name);
105		// recursive call to gather total time from children
106		static void accumulateTimings();
107
108		// updates cumulative times and hierarchy,
109		// can be called multiple times in a frame, at any point
110		static void processTimes();
111
112		static void buildHierarchy();
113		static void resetFrame();
114		static void reset();
115
116		//
117		// members
118		//
119		S32			mFrameStateIndex;
120
121		std::string	mName;
122
123		U32 		mTotalTimeCounter;
124
125		U32 		mCountAverage;
126		U32			mCallAverage;
127
128		U32*		mCountHistory;
129		U32*		mCallHistory;
130
131		// tree structure
132		NamedTimer*					mParent;				// NamedTimer of caller(parent)
133		std::vector<NamedTimer*>	mChildren;
134		bool						mCollapsed;				// don't show children
135		bool						mNeedsSorting;			// sort children whenever child added
136	};
137
138	// used to statically declare a new named timer
139	class LL_COMMON_API DeclareTimer
140	:	public LLInstanceTracker<DeclareTimer>
141	{
142		friend class LLFastTimer;
143	public:
144		DeclareTimer(const std::string& name, bool open);
145		DeclareTimer(const std::string& name);
146
147		static void updateCachedPointers();
148
149	private:
150		NamedTimer&		mTimer;
151		FrameState*		mFrameState;
152	};
153
154public:
155	LLFastTimer(LLFastTimer::FrameState* state);
156
157	LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
158	:	mFrameState(timer.mFrameState)
159	{
160#if TIME_FAST_TIMERS
161		U64 timer_start = getCPUClockCount64();
162#endif
163#if FAST_TIMER_ON
164		LLFastTimer::FrameState* frame_state = mFrameState;
165		mStartTime = getCPUClockCount32();
166
167		frame_state->mActiveCount++;
168		frame_state->mCalls++;
169		// keep current parent as long as it is active when we are
170		frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
171
172		LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
173		mLastTimerData = *cur_timer_data;
174		cur_timer_data->mCurTimer = this;
175		cur_timer_data->mFrameState = frame_state;
176		cur_timer_data->mChildTime = 0;
177#endif
178#if TIME_FAST_TIMERS
179		U64 timer_end = getCPUClockCount64();
180		sTimerCycles += timer_end - timer_start;
181#endif
182#if DEBUG_FAST_TIMER_THREADS
183#if !LL_RELEASE
184		assert_main_thread();
185#endif
186#endif
187	}
188
189	LL_FORCE_INLINE ~LLFastTimer()
190	{
191#if TIME_FAST_TIMERS
192		U64 timer_start = getCPUClockCount64();
193#endif
194#if FAST_TIMER_ON
195		LLFastTimer::FrameState* frame_state = mFrameState;
196		U32 total_time = getCPUClockCount32() - mStartTime;
197
198		frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
199		frame_state->mActiveCount--;
200
201		// store last caller to bootstrap tree creation
202		// do this in the destructor in case of recursion to get topmost caller
203		frame_state->mLastCaller = mLastTimerData.mFrameState;
204
205		// we are only tracking self time, so subtract our total time delta from parents
206		mLastTimerData.mChildTime += total_time;
207
208		LLFastTimer::sCurTimerData = mLastTimerData;
209#endif
210#if TIME_FAST_TIMERS
211		U64 timer_end = getCPUClockCount64();
212		sTimerCycles += timer_end - timer_start;
213		sTimerCalls++;
214#endif
215	}
216
217public:
218	static LLMutex*			sLogLock;
219	static std::queue<LLSD> sLogQueue;
220	static BOOL				sLog;
221	static BOOL				sMetricLog;
222	static std::string		sLogName;
223	static bool 			sPauseHistory;
224	static bool 			sResetHistory;
225	static U64				sTimerCycles;
226	static U32				sTimerCalls;
227
228	typedef std::vector<FrameState> info_list_t;
229	static info_list_t& getFrameStateList();
230
231
232	// call this once a frame to reset timers
233	static void nextFrame();
234
235	// dumps current cumulative frame stats to log
236	// call nextFrame() to reset timers
237	static void dumpCurTimes();
238
239	// call this to reset timer hierarchy, averages, etc.
240	static void reset();
241
242	static U64 countsPerSecond();
243	static S32 getLastFrameIndex() { return sLastFrameIndex; }
244	static S32 getCurFrameIndex() { return sCurFrameIndex; }
245
246	static void writeLog(std::ostream& os);
247	static const NamedTimer* getTimerByName(const std::string& name);
248
249	struct CurTimerData
250	{
251		LLFastTimer*	mCurTimer;
252		FrameState*		mFrameState;
253		U32				mChildTime;
254	};
255	static CurTimerData		sCurTimerData;
256	static std::string sClockType;
257
258private:
259	static U32 getCPUClockCount32();
260	static U64 getCPUClockCount64();
261	static U64 sClockResolution;
262
263	static S32				sCurFrameIndex;
264	static S32				sLastFrameIndex;
265	static U64				sLastFrameTime;
266	static info_list_t*		sTimerInfos;
267
268	U32							mStartTime;
269	LLFastTimer::FrameState*	mFrameState;
270	LLFastTimer::CurTimerData	mLastTimerData;
271
272};
273
274typedef class LLFastTimer LLFastTimer;
275
276#endif // LL_LLFASTTIMER_CLASS_H