Leaked source code of windows server 2003
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.

302 lines
7.3 KiB

  1. /*********************************************************************************
  2. /* File:
  3. /* ORDERPRO.CPP
  4. /* Author:
  5. /* Max-H. Windisch, SDE-T
  6. /* Date:
  7. /* October 1996
  8. /* Summary:
  9. /* Utility for sorting results generated by profile.h:
  10. /* 1) sorts all nodes by start time (requires "history" profiling)
  11. /* 2) extracts the time difference between two specified nodes
  12. /*
  13. /* (c) Copyright 1996 Microsoft-Softimage Inc.
  14. /********************************************************************************/
  15. // includes
  16. #define MAX_PROFILING_ENABLED
  17. #include <iomanip.h>
  18. #pragma warning(push, 3)
  19. #include <list>
  20. #include <vector>
  21. #include <stack>
  22. #include <map>
  23. #include <set>
  24. #include <algorithm>
  25. #pragma warning (pop)
  26. #include <profile.h>
  27. //namespace std
  28. //{
  29. // #include <set.h>
  30. //}
  31. // global markers
  32. CString g_oThreadId( "@@ThreadId=" );
  33. CString g_oRange( "@@Range=[origin(" );
  34. CString g_oRangeDuration( ",duration(" );
  35. CString g_oDeltaToPrevious( "@@DeltaToPrev=" );
  36. // the profiling line
  37. class CProfLine
  38. {
  39. protected:
  40. DWORD m_dwThreadId;
  41. CMaxLargeInteger m_oStartStamp;
  42. CString m_oLine;
  43. public:
  44. CProfLine(
  45. DWORD dwThreadId = 0,
  46. const CMaxLargeInteger &roStamp = CMaxLargeInteger(),
  47. const CString &roLine = CString() )
  48. : m_dwThreadId( dwThreadId )
  49. , m_oStartStamp( roStamp )
  50. , m_oLine( roLine )
  51. {
  52. };
  53. bool operator <( const CProfLine &o ) const
  54. {
  55. return m_oStartStamp < o.m_oStartStamp;
  56. };
  57. void FOutput( ostream &os, const CProfLine &roPrevious ) const
  58. {
  59. CMaxLargeInteger frequency;
  60. CMaxLargeInteger dtp = m_oStartStamp - roPrevious.m_oStartStamp;
  61. ::QueryPerformanceFrequency( frequency );
  62. os << "[" << g_oThreadId << setw( 4 ) << m_dwThreadId << ", ";
  63. os << g_oDeltaToPrevious << setw( 14 ) << dtp.dFInSecondsF( frequency ) << "s]";
  64. os << m_oLine << endl;
  65. };
  66. };
  67. // the file parsers base class
  68. class CResultParser
  69. {
  70. protected:
  71. ifstream m_is;
  72. public:
  73. CResultParser( const CString &roInputFileName )
  74. : m_is( (PCTSTR)roInputFileName ){};
  75. virtual void FExecute()
  76. {
  77. FParse();
  78. FOutputResults();
  79. };
  80. protected:
  81. virtual void FParse()
  82. {
  83. const unsigned long len = 400;
  84. CString line;
  85. LPTSTR buf;
  86. int i = 0;
  87. while ( !m_is.eof() )
  88. {
  89. buf = line.GetBufferSetLength( len );
  90. m_is.getline( buf, len );
  91. line.ReleaseBuffer( -1 );
  92. FProcessLine( line, i++ );
  93. }
  94. };
  95. virtual void FProcessLine( const CString &roLine, int nLineNumber ) = 0;
  96. virtual void FOutputResults() = 0;
  97. protected:
  98. bool bFGetThreadIdFromLine( const CString &roLine, DWORD &dwThreadId )
  99. {
  100. int i;
  101. if ( ( i = roLine.Find( g_oThreadId ) ) >= 0 )
  102. {
  103. CString s = roLine.Mid( i + g_oThreadId.GetLength() );
  104. dwThreadId = atoi( s );
  105. cout << "new thread=" << dwThreadId << endl;
  106. return true;
  107. }
  108. // Note: don't touch dwThreadId
  109. return false;
  110. };
  111. bool bFGetRangeFromLine( const CString &roLine, CMaxLargeInteger &roStart, CMaxLargeInteger &roDuration )
  112. {
  113. int i;
  114. CString s1;
  115. if ( ( i = roLine.Find( g_oRange ) ) >= 0 )
  116. {
  117. s1 = roLine.Mid( i + g_oRange.GetLength() );
  118. FExtractLargeInteger( s1, roStart );
  119. if ( ( i = roLine.Find( g_oRangeDuration ) ) >= 0 )
  120. {
  121. s1 = roLine.Mid( i + g_oRangeDuration.GetLength() );
  122. FExtractLargeInteger( s1, roDuration );
  123. }
  124. return true;
  125. }
  126. // Note: don't touch roStart or roDuration
  127. return false;
  128. };
  129. void FExtractLargeInteger( const CString &roLineSegment, CMaxLargeInteger &roL )
  130. {
  131. int delim1 = roLineSegment.Find( ';' );
  132. CString s2 = roLineSegment.Left( delim1 );
  133. int delim2 = roLineSegment.Find( ')' );
  134. CString s3 = roLineSegment.Mid( delim1 + 1, delim2 - delim1 - 1 );
  135. roL = CMaxLargeInteger( atoi( s2 ), atoi( s3 ) );
  136. };
  137. };
  138. // the sorting parser
  139. class CSortByStartTime
  140. : public CResultParser
  141. {
  142. protected:
  143. typedef std::less<CProfLine> PLCompare;
  144. typedef std::set<CProfLine, PLCompare> PLSet;
  145. protected:
  146. PLSet m_oSet;
  147. DWORD m_dwThreadId;
  148. CString m_oOutputFileName;
  149. public:
  150. CSortByStartTime( const CString &roInputFileName, const CString &roOutputFileName )
  151. : CResultParser( roInputFileName )
  152. , m_dwThreadId( 0 )
  153. , m_oOutputFileName( roOutputFileName ){};
  154. protected:
  155. virtual void FProcessLine( const CString &roLine, int )
  156. {
  157. CMaxLargeInteger l1, l2;
  158. if ( bFGetThreadIdFromLine( roLine, m_dwThreadId ) );
  159. else if ( bFGetRangeFromLine( roLine, l1, l2 ) )
  160. m_oSet.insert( CProfLine( m_dwThreadId, l1, roLine ) );
  161. };
  162. virtual void FOutputResults()
  163. {
  164. ofstream os( m_oOutputFileName, ios::out | ios::ate );
  165. PLSet::const_iterator j, k;
  166. for ( k = j = m_oSet.begin(); m_oSet.end() != j; j++ )
  167. {
  168. ( *j ).FOutput( os, ( *k ) );
  169. k = j;
  170. }
  171. cout << "Done!" << endl;
  172. };
  173. };
  174. // the delta parser
  175. class CComputeDelta
  176. : public CResultParser
  177. {
  178. protected:
  179. int m_nLine1, m_nLine2;
  180. CString m_oLine1, m_oLine2;
  181. public:
  182. CComputeDelta( const CString &roInputFileName, int nLine1, int nLine2 )
  183. : CResultParser( roInputFileName )
  184. , m_nLine1( nLine1 )
  185. , m_nLine2( nLine2 ){};
  186. protected:
  187. virtual void FProcessLine( const CString &roLine, int nLineNumber )
  188. {
  189. if ( nLineNumber == m_nLine1 )
  190. m_oLine1 = roLine;
  191. if ( nLineNumber == m_nLine2 )
  192. m_oLine2 = roLine;
  193. };
  194. virtual void FOutputResults()
  195. {
  196. CMaxLargeInteger l1, l2, l3, l4;
  197. if ( bFGetRangeFromLine( m_oLine1, l1, l2 ) && bFGetRangeFromLine( m_oLine2, l3, l4 ) )
  198. {
  199. CMaxLargeInteger frequency;
  200. ::QueryPerformanceFrequency( frequency );
  201. l3 = l3 + l4;
  202. cout << endl;
  203. cout << "Delta in seconds between the lines below was " << CMaxLargeInteger( l3 - l1 ).dFInSecondsF( frequency ) << endl;
  204. cout << endl;
  205. cout << m_oLine1 << endl;
  206. cout << endl;
  207. cout << m_oLine2 << endl;
  208. }
  209. else
  210. cout << "No result." << endl;
  211. cout << "Done!" << endl;
  212. };
  213. };
  214. // the little app
  215. int __cdecl main( int argc, char *argv[] )
  216. {
  217. bool bHandled = true;
  218. cout << "MINIPROFILER output flattener." << endl;
  219. // try to handle the command
  220. if ( argc >= 4 )
  221. {
  222. CString command( argv[ 1 ] );
  223. command.MakeLower();
  224. if ( CString( "sort" ) == command )
  225. CSortByStartTime( CString( argv[ 2 ] ), CString( argv[ 3 ] ) ).FExecute();
  226. else if ( CString( "diff" ) == command && argc >= 5 )
  227. CComputeDelta( CString( argv[ 2 ] ), atoi( argv[ 3 ] ), atoi( argv[ 4 ] ) ).FExecute();
  228. else
  229. bHandled = false;
  230. }
  231. else
  232. bHandled = false;
  233. // give some help if the command was not handled
  234. if ( !bHandled )
  235. {
  236. cout << endl;
  237. cout << "Please enter one of the following sets of arguments:" << endl;
  238. cout << endl;
  239. cout << " 1) the keyword <sort> + the input_result_file + the output_result_file" << endl;
  240. cout << " comment: outputs a file where nodes are sorted by start time;" << endl;
  241. cout << " requires an input file generated with history" << endl;
  242. cout << endl;
  243. cout << " 2) the keyword <diff> + the input_result_file + line_number_1 + line_number_2" << endl;
  244. cout << " comment: returns the delta t covered by those 2 lines" << endl;
  245. cout << endl;
  246. return 0;
  247. }
  248. return 0;
  249. }