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.

199 lines
5.6 KiB

  1. #ifndef __FUSION_PERFCLOCKING
  2. #define __FUSION_PERFCLOCKING
  3. typedef struct _tagFUSION_PERF_INFO
  4. {
  5. LARGE_INTEGER AccumulatedCycles;
  6. LARGE_INTEGER LineHits;
  7. BOOL bInitialized;
  8. int iSourceLine;
  9. CHAR *pSourceFile;
  10. CHAR *pStatement;
  11. #ifdef __cplusplus
  12. _tagFUSION_PERF_INFO() { AccumulatedCycles.QuadPart = LineHits.QuadPart = 0; bInitialized = FALSE; }
  13. #endif
  14. } FUSION_PERF_INFO, *PFUSION_PERF_INFO;
  15. #if defined(DBG) && defined(FUSION_PROFILING)
  16. #define PERFINFOTIME( pPerfInfo, statement ) \
  17. { \
  18. if ( !(pPerfInfo)->bInitialized ) { \
  19. (pPerfInfo)->iSourceLine = __LINE__; \
  20. (pPerfInfo)->pSourceFile = __FILE__; \
  21. (pPerfInfo)->pStatement = (#statement); \
  22. (pPerfInfo)->bInitialized = TRUE; \
  23. } \
  24. TIMEANDACCUMULATE( (pPerfInfo)->AccumulatedCycles, statement ); \
  25. (pPerfInfo)->LineHits.QuadPart++; \
  26. }
  27. #define CLOCKINTO( destiny ) \
  28. __asm { __asm cpuid __asm rdtsc }; \
  29. __asm { mov destiny.HighPart, edx }; \
  30. __asm { mov destiny.LowPart, eax };
  31. #define STARTCLOCK( destination, lag ) \
  32. { \
  33. LARGE_INTEGER __start, __stop; \
  34. LARGE_INTEGER *__pdest = &(destination), *__plag = &(lag); \
  35. CLOCKINTO( __start );
  36. #define STOPCLOCK() \
  37. CLOCKINTO( __stop ); \
  38. __pdest->QuadPart = __stop.QuadPart - ( __start.QuadPart + __plag->QuadPart ); \
  39. }
  40. #define STARTCLOCKACCUMULATE( accum, lag ) \
  41. { \
  42. LARGE_INTEGER __start, __stop; \
  43. LARGE_INTEGER *__acc = &(accum), *__plag = &(lag); \
  44. CLOCKINTO( __start ); \
  45. #define STOPCLOCKACCUMULATE() \
  46. CLOCKINTO( __stop ); \
  47. __acc->QuadPart += ( __stop.QuadPart - ( __start.QuadPart + __plag->QuadPart ) ); \
  48. }
  49. #define TIMEANDACCUMULATE( accumulator, statement ) \
  50. TIMEANDACCUMULATEWITHLAG( accumulator, statement, CpuIdLag )
  51. #define TIMEANDACCUMULATEWITHLAG( accumulator, statement, lag ) \
  52. STARTCLOCKACCUMULATE( accumulator, lag ); \
  53. statement; \
  54. STOPCLOCKACCUMULATE();
  55. #define FUSIONPERF_DUMP_TARGET_MASK ( 0x0000000F )
  56. #define FUSIONPERF_DUMP_TO_DEBUGGER ( 0x00000001 )
  57. #define FUSIONPERF_DUMP_TO_STDOUT ( 0x00000002 )
  58. #define FUSIONPERF_DUMP_TO_STDERR ( 0x00000003 )
  59. #define FUSIONPERF_DUMP_ALL_MASK ( 0x00000F00 )
  60. #define FUSIONPERF_DUMP_ALL_STATISTICS ( 0x00000100 )
  61. #define FUSIONPERF_DUMP_ALL_SOURCEINFO ( 0x00000200 )
  62. #define FUSIONPERF_DUMP_ALL_CONCISE ( 0x00000400 )
  63. #define FUSIONPERF_DUMP_TALLYS ( 0x00001000 )
  64. inline static VOID
  65. FusionpDumpPerfInfo( DWORD dwFlags, PFUSION_PERF_INFO pInfo )
  66. {
  67. /*
  68. NTRAID#NTBUG9-591616-2002/03/31-JayKrell
  69. large frame
  70. */
  71. CStringBuffer sbTemp;
  72. if ( dwFlags & FUSIONPERF_DUMP_ALL_SOURCEINFO )
  73. {
  74. /*
  75. NTRAID#NTBUG9-591616-2002/03/31-JayKrell
  76. missing check for error
  77. */
  78. sbTemp.Win32Format(
  79. L"Perf: %S(%d) - Hit %I64d times\n\t%I64d cycles total, %I64d average\n\t%S\n",
  80. pInfo->pSourceFile,
  81. pInfo->iSourceLine,
  82. pInfo->LineHits.QuadPart,
  83. pInfo->AccumulatedCycles.QuadPart,
  84. pInfo->AccumulatedCycles.QuadPart / pInfo->LineHits.QuadPart,
  85. pInfo->pStatement
  86. );
  87. }
  88. else if ( dwFlags & FUSIONPERF_DUMP_ALL_CONCISE )
  89. {
  90. /*
  91. NTRAID#NTBUG9-591616-2002/03/31-JayKrell
  92. missing check for error
  93. */
  94. sbTemp.Win32Format(
  95. L"%S(%d) - Hit %I64d times %I64d cycles total %I64d average\n",
  96. pInfo->pSourceFile,
  97. pInfo->iSourceLine,
  98. pInfo->LineHits.QuadPart,
  99. pInfo->AccumulatedCycles.QuadPart,
  100. pInfo->AccumulatedCycles.QuadPart / pInfo->LineHits.QuadPart
  101. );
  102. }
  103. else
  104. {
  105. /*
  106. NTRAID#NTBUG9-591616-2002/03/31-JayKrell
  107. missing check for error
  108. */
  109. sbTemp.Win32Format(
  110. L"Perf: %S(%d) - Hit %I64d times, \n\t%I64d cycles total, %I64d average\n",
  111. pInfo->pSourceFile,
  112. pInfo->iSourceLine,
  113. pInfo->LineHits.QuadPart,
  114. pInfo->AccumulatedCycles.QuadPart,
  115. pInfo->AccumulatedCycles.QuadPart / pInfo->LineHits.QuadPart
  116. );
  117. }
  118. switch ( dwFlags & FUSIONPERF_DUMP_TARGET_MASK )
  119. {
  120. case FUSIONPERF_DUMP_TO_DEBUGGER:
  121. OutputDebugStringW( static_cast<PCWSTR>(sbTemp) );
  122. break;
  123. case FUSIONPERF_DUMP_TO_STDOUT:
  124. wprintf( static_cast<PCWSTR>(sbTemp) );
  125. break;
  126. case FUSIONPERF_DUMP_TO_STDERR:
  127. fwprintf( stderr, static_cast<PCWSTR>(sbTemp) );
  128. break;
  129. }
  130. }
  131. inline static VOID
  132. FusionpReportPerfInfo( DWORD dwFlags, FUSION_PERF_INFO Info[], SIZE_T cInfo )
  133. {
  134. LARGE_INTEGER liAveragedTotalHits, liRawTotalCycles;
  135. liAveragedTotalHits.QuadPart = 0;
  136. liRawTotalCycles.QuadPart = 0;
  137. for ( SIZE_T i = 0; i < cInfo; i++ )
  138. {
  139. if ( dwFlags & FUSIONPERF_DUMP_ALL_STATISTICS )
  140. {
  141. FusionpDumpPerfInfo( dwFlags, Info + i );
  142. }
  143. liAveragedTotalHits.QuadPart +=
  144. ( Info[i].AccumulatedCycles.QuadPart / Info[i].LineHits.QuadPart );
  145. liRawTotalCycles.QuadPart += Info[i].AccumulatedCycles.QuadPart;
  146. }
  147. wprintf( L"Perf: Profiled %Iu statements, cyclecount average per set %I64d\n"
  148. L" %I64d total cycles in this set",
  149. cInfo,
  150. liAveragedTotalHits.QuadPart,
  151. liRawTotalCycles.QuadPart
  152. );
  153. }
  154. #define PERFINFOSINGLESTATEMENT( statement ) \
  155. { \
  156. FUSION_PERF_INFO __dumpinfo; \
  157. TIMEANDACCUMULATE( &__dumpinfo, statement ); \
  158. FusionpDumpPerfInfo( FUSIONPERF_DUMP_TO_STDOUT, &__dumpinfo ); \
  159. }
  160. #else
  161. #define PERFINFOTIME( pDump, statement ) statement;
  162. #define TIMEANDACCUMULATE( a, s ) s;
  163. #define TIMEANDACCUMULATEWITHLAG( a, s, l ) s;
  164. #define FusionpReportPerfInfo( a, b, c )
  165. #define FusionpDumpPerfInfo( a, b )
  166. #define PERFINFOSINGLESTATEMENT( statement ) statement;
  167. #endif
  168. #endif