profile.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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. /////////////////////////////////////////////////////////////////////////EA-V1
  19. // $File: //depot/GeneralsMD/Staging/code/Libraries/Source/profile/profile.h $
  20. // $Author: mhoffe $
  21. // $Revision: #4 $
  22. // $DateTime: 2003/08/14 13:43:29 $
  23. //
  24. // ©2003 Electronic Arts
  25. //
  26. // Profiling module
  27. //////////////////////////////////////////////////////////////////////////////
  28. #ifdef _MSC_VER
  29. # pragma once
  30. #endif
  31. #ifndef PROFILE_H // Include guard
  32. #define PROFILE_H
  33. #if defined(_DEBUG) && defined(_INTERNAL)
  34. #error "Only either _DEBUG or _INTERNAL should ever be defined"
  35. #endif
  36. // Define which libraries to use.
  37. #if defined(_INTERNAL)
  38. # pragma comment (lib,"profileinternal.lib")
  39. #elif defined(_DEBUG)
  40. # pragma comment (lib,"profiledebug.lib")
  41. #elif defined(_PROFILE)
  42. # pragma comment (lib,"profileprofile.lib")
  43. #else
  44. # pragma comment (lib,"profile.lib")
  45. #endif
  46. // include all our public header files (use double quotes here)
  47. #include "profile_doc.h"
  48. #include "profile_highlevel.h"
  49. #include "profile_funclevel.h"
  50. #include "profile_result.h"
  51. /**
  52. \brief Functions common to both profilers.
  53. */
  54. class Profile
  55. {
  56. friend class ProfileCmdInterface;
  57. // nobody can construct this class
  58. Profile();
  59. public:
  60. /**
  61. \brief Starts range recording.
  62. \param range name of range to record, ==NULL for "frame"
  63. */
  64. static void StartRange(const char *range=0);
  65. /**
  66. \brief Appends profile data to the last recorded frame
  67. of the given range.
  68. \param range name of range to record, ==NULL for "frame"
  69. */
  70. static void AppendRange(const char *range=0);
  71. /**
  72. \brief Stops range recording.
  73. \note After this call the recorded range data will be available
  74. as a new range frame.
  75. \param range name of range to record, ==NULL for "frame"
  76. */
  77. static void StopRange(const char *range=0);
  78. /**
  79. \brief Determines if any range recording is enabled or not.
  80. \return true if range profiling is enabled, false if not
  81. */
  82. static bool IsEnabled(void);
  83. /**
  84. \brief Determines the number of known (recorded) range frames.
  85. Note that if function level profiling is enabled then the number
  86. of recorded high level frames is the same as the number of recorded
  87. function level frames.
  88. \return number of recorded range frames
  89. */
  90. static unsigned GetFrameCount(void);
  91. /**
  92. \brief Determines the range name of a recorded range frame.
  93. \note A unique number will be added to the frame name, separated by
  94. a ':', e.g. 'frame:3'
  95. \param frame number of recorded frame
  96. \return range name
  97. */
  98. static const char *GetFrameName(unsigned frame);
  99. /**
  100. \brief Resets all 'total' counter values to 0.
  101. This function does not change any recorded frames.
  102. */
  103. static void ClearTotals(void);
  104. /**
  105. \brief Determines number of CPU clock cycles per second.
  106. \note This value is cached internally so this function is
  107. quite fast.
  108. \return number of CPU clock cycles per second
  109. */
  110. static _int64 GetClockCyclesPerSecond(void);
  111. /**
  112. \brief Add the given result function interface.
  113. \param func factory function
  114. \param name factory name
  115. \param arg description of optional parameters the factory function recognizes
  116. */
  117. static void AddResultFunction(ProfileResultInterface* (*func)(int, const char * const *),
  118. const char *name, const char *arg);
  119. private:
  120. /** \internal
  121. \brief Simple recursive pattern matcher.
  122. \param str string to match
  123. \param pattern pattern, only wildcard valid is '*'
  124. \return true if string matches pattern, false if not
  125. */
  126. static bool SimpleMatch(const char *str, const char *pattern);
  127. /// known frame names
  128. struct FrameName
  129. {
  130. /// frame name
  131. char *name;
  132. /// number of recorded frames for this name
  133. unsigned frames;
  134. /// are we currently recording?
  135. bool isRecording;
  136. /// should current frame be appended to last frame with same name
  137. bool doAppend;
  138. /// internal index for function level profiler
  139. int funcIndex;
  140. /// internal index for high level profiler
  141. int highIndex;
  142. /// global frame number of last recorded frame for this range, -1 if none
  143. int lastGlobalIndex;
  144. };
  145. /// \internal pattern list entry
  146. struct PatternListEntry
  147. {
  148. /// next entry
  149. PatternListEntry *next;
  150. /// active (true) or inactive (false)?
  151. bool isActive;
  152. /// pattern itself (dynamic allocated memory)
  153. char *pattern;
  154. };
  155. /** \internal
  156. First pattern list list entry. A singly linked list is
  157. okay for this because checking patterns is a costly
  158. operation anyway and is therefore cached.
  159. */
  160. static PatternListEntry *firstPatternEntry;
  161. /// \internal last pattern list entry for fast additions to list at end
  162. static PatternListEntry *lastPatternEntry;
  163. /// number of recorded frames
  164. static unsigned m_rec;
  165. /// names of recorded frames
  166. static char **m_recNames;
  167. /// number of known frame names
  168. static unsigned m_names;
  169. /// list of known frame names
  170. static FrameName *m_frameNames;
  171. /// CPU clock cycles/second
  172. static _int64 m_clockCycles;
  173. };
  174. #endif // PROFILE_H