wwprofile.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWDebug *
  23. * *
  24. * $Archive:: /Commando/Code/wwdebug/wwprofile.h $*
  25. * *
  26. * $Author:: Jani_p $*
  27. * *
  28. * $Modtime:: 3/25/02 2:05p $*
  29. * *
  30. * $Revision:: 14 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if _MSC_VER >= 1000
  36. #pragma once
  37. #endif // _MSC_VER >= 1000
  38. //#define ENABLE_TIME_AND_MEMORY_LOG
  39. #ifndef WWPROFILE_H
  40. #define WWPROFILE_H
  41. #include "wwstring.h"
  42. #ifdef _UNIX
  43. typedef signed long long __int64;
  44. typedef signed long long _int64;
  45. #endif
  46. // enable profiling by default in debug mode.
  47. #ifdef WWDEBUG
  48. #define ENABLE_WWPROFILE
  49. #endif
  50. extern unsigned WWProfile_Get_System_Time(); // timeGetTime() wrapper
  51. class FileClass;
  52. /*
  53. ** A node in the WWProfile Hierarchy Tree
  54. */
  55. class WWProfileHierachyNodeClass {
  56. public:
  57. WWProfileHierachyNodeClass( const char * name, WWProfileHierachyNodeClass * parent );
  58. ~WWProfileHierachyNodeClass( void );
  59. WWProfileHierachyNodeClass * Get_Sub_Node( const char * name );
  60. WWProfileHierachyNodeClass * Get_Parent( void ) { return Parent; }
  61. WWProfileHierachyNodeClass * Get_Sibling( void ) { return Sibling; }
  62. WWProfileHierachyNodeClass * Get_Child( void ) { return Child; }
  63. void Reset( void );
  64. void Call( void );
  65. bool Return( void );
  66. const char * Get_Name( void ) { return Name; }
  67. int Get_Total_Calls( void ) { return TotalCalls; }
  68. float Get_Total_Time( void ) { return TotalTime; }
  69. WWProfileHierachyNodeClass* Clone_Hierarchy(WWProfileHierachyNodeClass* parent);
  70. void Write_To_File(FileClass* file,int recursion);
  71. int Get_Total_Calls() const { return TotalCalls; }
  72. float Get_Total_Time() const { return TotalTime; }
  73. void Set_Total_Calls(int calls) { TotalCalls=calls; }
  74. void Set_Total_Time(float time) { TotalTime=time; }
  75. protected:
  76. const char * Name;
  77. int TotalCalls;
  78. float TotalTime;
  79. __int64 StartTime;
  80. int RecursionCounter;
  81. WWProfileHierachyNodeClass * Parent;
  82. WWProfileHierachyNodeClass * Child;
  83. WWProfileHierachyNodeClass * Sibling;
  84. };
  85. /*
  86. ** An iterator to navigate through the tree
  87. */
  88. class WWProfileIterator
  89. {
  90. public:
  91. // Access all the children of the current parent
  92. void First(void);
  93. void Next(void);
  94. bool Is_Done(void);
  95. void Enter_Child( void ); // Make the current child the new parent
  96. void Enter_Child( int index ); // Make the given child the new parent
  97. void Enter_Parent( void ); // Make the current parent's parent the new parent
  98. // Access the current child
  99. const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); }
  100. int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); }
  101. float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); }
  102. // Access the current parent
  103. const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); }
  104. int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); }
  105. float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); }
  106. protected:
  107. WWProfileHierachyNodeClass * CurrentParent;
  108. WWProfileHierachyNodeClass * CurrentChild;
  109. WWProfileIterator( WWProfileHierachyNodeClass * start );
  110. friend class WWProfileManager;
  111. };
  112. /*
  113. ** An iterator to walk through the tree in depth first order
  114. */
  115. class WWProfileInOrderIterator
  116. {
  117. public:
  118. void First(void);
  119. void Next(void);
  120. bool Is_Done(void);
  121. // Access the current node
  122. const char * Get_Current_Name( void ) { return CurrentNode->Get_Name(); }
  123. int Get_Current_Total_Calls( void ) { return CurrentNode->Get_Total_Calls(); }
  124. float Get_Current_Total_Time( void ) { return CurrentNode->Get_Total_Time(); }
  125. protected:
  126. WWProfileHierachyNodeClass * CurrentNode;
  127. WWProfileInOrderIterator( void );
  128. friend class WWProfileManager;
  129. };
  130. /*
  131. ** The Manager for the WWProfile system
  132. */
  133. class WWProfileManager {
  134. public:
  135. static void Start_Profile( const char * name );
  136. static void Stop_Profile( void );
  137. static void Start_Root_Profile( const char * name );
  138. static void Stop_Root_Profile( void );
  139. static void Reset( void );
  140. static void Increment_Frame_Counter( void );
  141. static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; }
  142. static float Get_Time_Since_Reset( void );
  143. static WWProfileIterator * Get_Iterator( void );
  144. static void Release_Iterator( WWProfileIterator * iterator );
  145. static WWProfileInOrderIterator * Get_In_Order_Iterator( void );
  146. static void Release_In_Order_Iterator( WWProfileInOrderIterator * iterator );
  147. static WWProfileHierachyNodeClass * Get_Root( void ) { return &Root; }
  148. static void Begin_Collecting();
  149. static void End_Collecting(const char* filename);
  150. private:
  151. static WWProfileHierachyNodeClass Root;
  152. static WWProfileHierachyNodeClass * CurrentNode;
  153. static WWProfileHierachyNodeClass * CurrentRootNode;
  154. static int FrameCounter;
  155. static __int64 ResetTime;
  156. friend class WWProfileInOrderIterator;
  157. };
  158. /*
  159. ** WWProfileSampleClass is a simple way to profile a function's scope
  160. ** Use the WWPROFILE macro at the start of scope to time
  161. */
  162. class WWProfileSampleClass {
  163. bool IsRoot;
  164. public:
  165. WWProfileSampleClass( const char * name, bool is_root ) : IsRoot(is_root)
  166. {
  167. if (IsRoot) WWProfileManager::Start_Root_Profile( name );
  168. else WWProfileManager::Start_Profile( name );
  169. }
  170. ~WWProfileSampleClass( void )
  171. {
  172. if (IsRoot) WWProfileManager::Stop_Root_Profile();
  173. else WWProfileManager::Stop_Profile();
  174. }
  175. };
  176. #ifdef ENABLE_WWPROFILE
  177. #define WWPROFILE( name ) WWProfileSampleClass _wwprofile( name, false )
  178. #define WWROOTPROFILE( name ) WWProfileSampleClass _wwprofile( name, true )
  179. #else
  180. #define WWPROFILE( name )
  181. #define WWROOTPROFILE( name )
  182. #endif
  183. /*
  184. ** WWTimeIt is like WWProfile, but it doesn't save anything, it just times one routine, regardless of thread
  185. */
  186. class WWTimeItClass {
  187. public:
  188. WWTimeItClass( const char * name );
  189. ~WWTimeItClass( void );
  190. private:
  191. const char * Name;
  192. __int64 Time;
  193. };
  194. #ifdef ENABLE_WWPROFILE
  195. #define WWTIMEIT( name ) WWTimeItClass _wwtimeit( name )
  196. #else
  197. #define WWTIMEIT( name )
  198. #endif
  199. /*
  200. ** TSS 06/27/01
  201. ** WWMeasureItClass is like WWTimeItClass, but it pokes the result into the given float,
  202. ** and can be used in the release build.
  203. */
  204. class WWMeasureItClass {
  205. public:
  206. WWMeasureItClass( float * p_result );
  207. ~WWMeasureItClass( void );
  208. private:
  209. __int64 Time;
  210. float * PResult;
  211. };
  212. // ----------------------------------------------------------------------------
  213. //
  214. // Use the first macro to log time and memory usage within the stack segment.
  215. // Use the second macro to log intermediate values. The intermediate values are
  216. // calculated from the previous intermediate log, so you can log how much each
  217. // item takes by placing the macro after each of the
  218. //
  219. // ----------------------------------------------------------------------------
  220. #ifdef ENABLE_TIME_AND_MEMORY_LOG
  221. #define WWLOG_PREPARE_TIME_AND_MEMORY(t) WWMemoryAndTimeLog memory_and_time_log(t)
  222. #define WWLOG_INTERMEDIATE(t) memory_and_time_log.Log_Intermediate(t)
  223. #else
  224. #define WWLOG_PREPARE_TIME_AND_MEMORY(t)
  225. #define WWLOG_INTERMEDIATE(t)
  226. #endif
  227. struct WWMemoryAndTimeLog
  228. {
  229. unsigned TimeStart;
  230. unsigned IntermediateTimeStart;
  231. int AllocCountStart;
  232. int IntermediateAllocCountStart;
  233. int AllocSizeStart;
  234. int IntermediateAllocSizeStart;
  235. StringClass Name;
  236. static unsigned TabCount;
  237. WWMemoryAndTimeLog(const char* name);
  238. ~WWMemoryAndTimeLog();
  239. void Log_Intermediate(const char* text);
  240. };
  241. #endif // WWPROFILE_H