Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
7.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. //
  8. //-----------------------------------------------------------------------------
  9. // $Log: $
  10. //
  11. // $NoKeywords: $
  12. //=============================================================================//
  13. #include <string.h>
  14. #include <stdlib.h>
  15. #include "basetypes.h"
  16. #include "measure_section.h"
  17. #include "convar.h"
  18. // Static members
  19. CMeasureSection *CMeasureSection::s_pSections = 0;
  20. int CMeasureSection::s_nCount = 0;
  21. double CMeasureSection::m_dNextResort = 0.0;
  22. ConVar measure_resort( "measure_resort", "1.0", 0, "How often to re-sort profiling sections\n" );
  23. ConVar game_speeds( "game_speeds","0" );
  24. extern ConVar host_speeds;
  25. //-----------------------------------------------------------------------------
  26. // Purpose: Creates a profiling section
  27. // Input : *name - name of the section ( allocated on stack hopefully )
  28. //-----------------------------------------------------------------------------
  29. CMeasureSection::CMeasureSection( const char *name )
  30. {
  31. // Just point at name since it's static
  32. m_pszName = name;
  33. // Clear accumulators
  34. Reset();
  35. SortReset();
  36. m_dMaxTime.Init();
  37. // Link into master list
  38. m_pNext = s_pSections;
  39. s_pSections = this;
  40. // Update count
  41. s_nCount++;
  42. }
  43. //-----------------------------------------------------------------------------
  44. // Purpose: Destroys the object
  45. //-----------------------------------------------------------------------------
  46. CMeasureSection::~CMeasureSection( void )
  47. {
  48. m_pNext = NULL;
  49. s_nCount--;
  50. }
  51. //-----------------------------------------------------------------------------
  52. // Purpose:
  53. //-----------------------------------------------------------------------------
  54. void CMeasureSection::UpdateMax( void )
  55. {
  56. if (m_dMaxTime.IsLessThan(m_dAccumulatedTime))
  57. {
  58. m_dMaxTime.Init();
  59. CCycleCount::Add(m_dMaxTime,m_dAccumulatedTime,m_dMaxTime);
  60. }
  61. }
  62. //-----------------------------------------------------------------------------
  63. // Purpose:
  64. //-----------------------------------------------------------------------------
  65. void CMeasureSection::Reset( void )
  66. {
  67. m_dAccumulatedTime.Init();
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Purpose:
  71. //-----------------------------------------------------------------------------
  72. void CMeasureSection::SortReset( void )
  73. {
  74. m_dTotalTime.Init();
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose:
  78. // Output : const char
  79. //-----------------------------------------------------------------------------
  80. const char *CMeasureSection::GetName( void )
  81. {
  82. return m_pszName;
  83. }
  84. //-----------------------------------------------------------------------------
  85. // Purpose:
  86. // Output :
  87. //-----------------------------------------------------------------------------
  88. CCycleCount const& CMeasureSection::GetTotalTime( void )
  89. {
  90. return m_dTotalTime;
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Purpose:
  94. // Output :
  95. //-----------------------------------------------------------------------------
  96. CCycleCount const& CMeasureSection::GetTime( void )
  97. {
  98. return m_dAccumulatedTime;
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Purpose:
  102. // Output :
  103. //-----------------------------------------------------------------------------
  104. CCycleCount const& CMeasureSection::GetMaxTime( void )
  105. {
  106. return m_dMaxTime;
  107. }
  108. //-----------------------------------------------------------------------------
  109. // Purpose: Accumulates a timeslice
  110. // Input : time -
  111. //-----------------------------------------------------------------------------
  112. void CMeasureSection::AddTime( CCycleCount const &rCount )
  113. {
  114. CCycleCount::Add(m_dAccumulatedTime, rCount, m_dAccumulatedTime);
  115. CCycleCount::Add(m_dTotalTime, rCount, m_dTotalTime);
  116. }
  117. //-----------------------------------------------------------------------------
  118. // Purpose:
  119. // Output : CMeasureSection
  120. //-----------------------------------------------------------------------------
  121. CMeasureSection *CMeasureSection::GetNext( void )
  122. {
  123. return m_pNext;
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Purpose:
  127. // Output : CMeasureSection
  128. //-----------------------------------------------------------------------------
  129. CMeasureSection *CMeasureSection::GetList( void )
  130. {
  131. return s_pSections;
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Purpose: Compares accumulated time for two sections
  135. // Input : ppms1 -
  136. // ppms2 -
  137. // Output : static int
  138. //-----------------------------------------------------------------------------
  139. static int SectionCompare( const void* ppms1,const void* ppms2 )
  140. {
  141. CMeasureSection* pms1 = *(CMeasureSection**)ppms1;
  142. CMeasureSection* pms2 = *(CMeasureSection**)ppms2;
  143. if ( pms1->GetTotalTime().IsLessThan(pms2->GetTotalTime()) )
  144. return 1;
  145. else
  146. return -1;
  147. }
  148. //-----------------------------------------------------------------------------
  149. // Purpose: Sorts sections by time usage
  150. //-----------------------------------------------------------------------------
  151. void CMeasureSection::SortSections( void )
  152. {
  153. // Not enough to be sortable
  154. if ( s_nCount <= 1 )
  155. return;
  156. CMeasureSection *sortarray[ 128 ];
  157. CMeasureSection *ms;
  158. memset(sortarray,sizeof(CMeasureSection*)*128,0);
  159. ms = GetList();
  160. int i;
  161. int c = 0;
  162. while ( ms )
  163. {
  164. sortarray[ c++ ] = ms;
  165. ms = ms->GetNext();
  166. }
  167. // Sort the array alphabetically
  168. qsort( sortarray, c , sizeof( CMeasureSection * ), SectionCompare );
  169. // Fix next pointers
  170. for ( i = 0; i < c-1; i++ )
  171. {
  172. sortarray[ i ]->m_pNext = sortarray[ i + 1 ];
  173. }
  174. sortarray[i]->m_pNext = NULL;
  175. // Point head of list at it
  176. s_pSections = sortarray[ 0 ];
  177. }
  178. //-----------------------------------------------------------------------------
  179. // Purpose: Creates an instance for timing a section
  180. // Input : *ms -
  181. //-----------------------------------------------------------------------------
  182. CMeasureSectionInstance::CMeasureSectionInstance( CMeasureSection *ms )
  183. {
  184. // Remember where to put accumulated time
  185. m_pMS = ms;
  186. if ( host_speeds.GetInt() < 3 && !game_speeds.GetInt())
  187. return;
  188. // Get initial timestamp
  189. m_Timer.Start();
  190. }
  191. //-----------------------------------------------------------------------------
  192. // Purpose:
  193. //-----------------------------------------------------------------------------
  194. CMeasureSectionInstance::~CMeasureSectionInstance( void )
  195. {
  196. if ( host_speeds.GetInt() < 3 && !game_speeds.GetInt())
  197. return;
  198. // Get final timestamp
  199. m_Timer.End();
  200. // Add time to section
  201. m_pMS->AddTime( m_Timer.GetDuration() );
  202. }
  203. //-----------------------------------------------------------------------------
  204. // Purpose: Re-sort all data and determine whether sort keys should be reset too ( after
  205. // re-doing sort if needed ).
  206. //-----------------------------------------------------------------------------
  207. void ResetTimeMeasurements( void )
  208. {
  209. #if defined( _DEBUG ) || defined( FORCE_MEASURE )
  210. bool sort_reset = false;
  211. // Time to redo sort?
  212. if ( measure_resort.GetFloat() > 0.0 &&
  213. GetRealTime() >= CMeasureSection::m_dNextResort )
  214. {
  215. // Redo it
  216. CMeasureSection::SortSections();
  217. // Set next time
  218. CMeasureSection::m_dNextResort = GetRealTime() + measure_resort.GetFloat();
  219. // Flag to reset sort accumulator, too
  220. sort_reset = true;
  221. }
  222. // Iterate through the sections now
  223. CMeasureSection *p = CMeasureSection::GetList();
  224. while ( p )
  225. {
  226. // Reset regular accum.
  227. p->Reset();
  228. // Reset sort accum less often
  229. if ( sort_reset )
  230. {
  231. p->SortReset();
  232. }
  233. p = p->GetNext();
  234. }
  235. #endif
  236. }