/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. #ifndef LL_FASTTIMER_CLASS_H
  27. #define LL_FASTTIMER_CLASS_H
  28. #include "llinstancetracker.h"
  29. #define FAST_TIMER_ON 1
  30. #define TIME_FAST_TIMERS 0
  31. #define DEBUG_FAST_TIMER_THREADS 1
  32. class LLMutex;
  33. #include <queue>
  34. #include "llsd.h"
  35. LL_COMMON_API void assert_main_thread();
  36. class LL_COMMON_API LLFastTimer
  37. {
  38. public:
  39. class NamedTimer;
  40. struct LL_COMMON_API FrameState
  41. {
  42. FrameState(NamedTimer* timerp);
  43. U32 mSelfTimeCounter;
  44. U32 mCalls;
  45. FrameState* mParent; // info for caller timer
  46. FrameState* mLastCaller; // used to bootstrap tree construction
  47. NamedTimer* mTimer;
  48. U16 mActiveCount; // number of timers with this ID active on stack
  49. bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
  50. };
  51. // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
  52. class LL_COMMON_API NamedTimer
  53. : public LLInstanceTracker<NamedTimer>
  54. {
  55. friend class DeclareTimer;
  56. public:
  57. ~NamedTimer();
  58. enum { HISTORY_NUM = 300 };
  59. const std::string& getName() const { return mName; }
  60. NamedTimer* getParent() const { return mParent; }
  61. void setParent(NamedTimer* parent);
  62. S32 getDepth();
  63. std::string getToolTip(S32 history_index = -1);
  64. typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
  65. child_const_iter beginChildren();
  66. child_const_iter endChildren();
  67. std::vector<NamedTimer*>& getChildren();
  68. void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
  69. bool getCollapsed() const { return mCollapsed; }
  70. U32 getCountAverage() const { return mCountAverage; }
  71. U32 getCallAverage() const { return mCallAverage; }
  72. U32 getHistoricalCount(S32 history_index = 0) const;
  73. U32 getHistoricalCalls(S32 history_index = 0) const;
  74. static NamedTimer& getRootNamedTimer();
  75. S32 getFrameStateIndex() const { return mFrameStateIndex; }
  76. FrameState& getFrameState() const;
  77. private:
  78. friend class LLFastTimer;
  79. friend class NamedTimerFactory;
  80. //
  81. // methods
  82. //
  83. NamedTimer(const std::string& name);
  84. // recursive call to gather total time from children
  85. static void accumulateTimings();
  86. // updates cumulative times and hierarchy,
  87. // can be called multiple times in a frame, at any point
  88. static void processTimes();
  89. static void buildHierarchy();
  90. static void resetFrame();
  91. static void reset();
  92. //
  93. // members
  94. //
  95. S32 mFrameStateIndex;
  96. std::string mName;
  97. U32 mTotalTimeCounter;
  98. U32 mCountAverage;
  99. U32 mCallAverage;
  100. U32* mCountHistory;
  101. U32* mCallHistory;
  102. // tree structure
  103. NamedTimer* mParent; // NamedTimer of caller(parent)
  104. std::vector<NamedTimer*> mChildren;
  105. bool mCollapsed; // don't show children
  106. bool mNeedsSorting; // sort children whenever child added
  107. };
  108. // used to statically declare a new named timer
  109. class LL_COMMON_API DeclareTimer
  110. : public LLInstanceTracker<DeclareTimer>
  111. {
  112. friend class LLFastTimer;
  113. public:
  114. DeclareTimer(const std::string& name, bool open);
  115. DeclareTimer(const std::string& name);
  116. static void updateCachedPointers();
  117. private:
  118. NamedTimer& mTimer;
  119. FrameState* mFrameState;
  120. };
  121. public:
  122. LLFastTimer(LLFastTimer::FrameState* state);
  123. LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
  124. : mFrameState(timer.mFrameState)
  125. {
  126. #if TIME_FAST_TIMERS
  127. U64 timer_start = getCPUClockCount64();
  128. #endif
  129. #if FAST_TIMER_ON
  130. LLFastTimer::FrameState* frame_state = mFrameState;
  131. mStartTime = getCPUClockCount32();
  132. frame_state->mActiveCount++;
  133. frame_state->mCalls++;
  134. // keep current parent as long as it is active when we are
  135. frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
  136. LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
  137. mLastTimerData = *cur_timer_data;
  138. cur_timer_data->mCurTimer = this;
  139. cur_timer_data->mFrameState = frame_state;
  140. cur_timer_data->mChildTime = 0;
  141. #endif
  142. #if TIME_FAST_TIMERS
  143. U64 timer_end = getCPUClockCount64();
  144. sTimerCycles += timer_end - timer_start;
  145. #endif
  146. #if DEBUG_FAST_TIMER_THREADS
  147. #if !LL_RELEASE
  148. assert_main_thread();
  149. #endif
  150. #endif
  151. }
  152. LL_FORCE_INLINE ~LLFastTimer()
  153. {
  154. #if TIME_FAST_TIMERS
  155. U64 timer_start = getCPUClockCount64();
  156. #endif
  157. #if FAST_TIMER_ON
  158. LLFastTimer::FrameState* frame_state = mFrameState;
  159. U32 total_time = getCPUClockCount32() - mStartTime;
  160. frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
  161. frame_state->mActiveCount--;
  162. // store last caller to bootstrap tree creation
  163. // do this in the destructor in case of recursion to get topmost caller
  164. frame_state->mLastCaller = mLastTimerData.mFrameState;
  165. // we are only tracking self time, so subtract our total time delta from parents
  166. mLastTimerData.mChildTime += total_time;
  167. LLFastTimer::sCurTimerData = mLastTimerData;
  168. #endif
  169. #if TIME_FAST_TIMERS
  170. U64 timer_end = getCPUClockCount64();
  171. sTimerCycles += timer_end - timer_start;
  172. sTimerCalls++;
  173. #endif
  174. }
  175. public:
  176. static LLMutex* sLogLock;
  177. static std::queue<LLSD> sLogQueue;
  178. static BOOL sLog;
  179. static BOOL sMetricLog;
  180. static std::string sLogName;
  181. static bool sPauseHistory;
  182. static bool sResetHistory;
  183. static U64 sTimerCycles;
  184. static U32 sTimerCalls;
  185. typedef std::vector<FrameState> info_list_t;
  186. static info_list_t& getFrameStateList();
  187. // call this once a frame to reset timers
  188. static void nextFrame();
  189. // dumps current cumulative frame stats to log
  190. // call nextFrame() to reset timers
  191. static void dumpCurTimes();
  192. // call this to reset timer hierarchy, averages, etc.
  193. static void reset();
  194. static U64 countsPerSecond();
  195. static S32 getLastFrameIndex() { return sLastFrameIndex; }
  196. static S32 getCurFrameIndex() { return sCurFrameIndex; }
  197. static void writeLog(std::ostream& os);
  198. static const NamedTimer* getTimerByName(const std::string& name);
  199. struct CurTimerData
  200. {
  201. LLFastTimer* mCurTimer;
  202. FrameState* mFrameState;
  203. U32 mChildTime;
  204. };
  205. static CurTimerData sCurTimerData;
  206. static std::string sClockType;
  207. private:
  208. static U32 getCPUClockCount32();
  209. static U64 getCPUClockCount64();
  210. static U64 sClockResolution;
  211. static S32 sCurFrameIndex;
  212. static S32 sLastFrameIndex;
  213. static U64 sLastFrameTime;
  214. static info_list_t* sTimerInfos;
  215. U32 mStartTime;
  216. LLFastTimer::FrameState* mFrameState;
  217. LLFastTimer::CurTimerData mLastTimerData;
  218. };
  219. typedef class LLFastTimer LLFastTimer;
  220. #endif // LL_LLFASTTIMER_CLASS_H