Counter Strike : Global Offensive Source Code
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.

246 lines
4.8 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #if (defined(_WIN32) && (!defined(_X360) ) )
  8. #include <windows.h>
  9. #endif
  10. #include "tier0/platform.h"
  11. #include "dt_instrumentation.h"
  12. #include "utlvector.h"
  13. #include "utllinkedlist.h"
  14. #include "tier0/fasttimer.h"
  15. #include "utllinkedlist.h"
  16. #include "tier0/dbg.h"
  17. #include "tier1/utlstring.h"
  18. #include "dt_recv_decoder.h"
  19. #include "filesystem.h"
  20. #include "filesystem_engine.h"
  21. #include "tier0/icommandline.h"
  22. #include "cdll_int.h"
  23. #include "client.h"
  24. #include "common.h"
  25. #include <time.h>
  26. // memdbgon must be the last include file in a .cpp file!!!
  27. #include "tier0/memdbgon.h"
  28. bool g_bDTIEnabled = false;
  29. const char *g_pDTIFilename;
  30. class CDTIProp
  31. {
  32. public:
  33. CDTIProp()
  34. {
  35. m_nDecodes = m_nDataBits = m_nIndexBits = 0;
  36. }
  37. CUtlString m_Name;
  38. int m_nDecodes;
  39. int m_nDataBits;
  40. int m_nIndexBits;
  41. int m_nPropIndex; // Index into its CSendTablePrecalc::m_Props.
  42. };
  43. class CDTIRecvTable
  44. {
  45. public:
  46. CDTIRecvTable()
  47. {
  48. m_bSawAction = false;
  49. }
  50. CUtlString m_Name;
  51. CUtlVector<CDTIProp> m_Props;
  52. bool m_bSawAction;
  53. };
  54. CUtlLinkedList<CDTIRecvTable*, int> g_DTIRecvTables;
  55. void DTI_Init()
  56. {
  57. #if ( defined( IS_WINDOWS_PC ) && (! defined( DEDICATED ) ) )
  58. extern IVEngineClient *engineClient;
  59. if ( CommandLine()->FindParm( "-dti" ) && !g_bDTIEnabled )
  60. {
  61. g_bDTIEnabled = true;
  62. struct tm systemTime;
  63. Plat_GetLocalTime( &systemTime );
  64. char dtiFileName[MAX_PATH];
  65. V_snprintf( dtiFileName, ARRAYSIZE( dtiFileName ), "dti_client_%s_%02d%02d%02d-%02d%02d%02d.csv",
  66. engineClient->GetLevelNameShort(),
  67. (systemTime.tm_year + 1900) % 100, systemTime.tm_mon, systemTime.tm_wday,
  68. systemTime.tm_hour, systemTime.tm_min, systemTime.tm_sec );
  69. g_pDTIFilename = COM_StringCopy( dtiFileName );
  70. }
  71. #endif
  72. }
  73. void DTI_Term()
  74. {
  75. if ( g_bDTIEnabled )
  76. {
  77. DTI_Flush();
  78. g_DTIRecvTables.PurgeAndDeleteElements();
  79. delete g_pDTIFilename;
  80. g_pDTIFilename = NULL;
  81. g_bDTIEnabled = false;
  82. }
  83. }
  84. void DTI_Flush()
  85. {
  86. if ( !g_bDTIEnabled )
  87. return;
  88. FileHandle_t fp = g_pFileSystem->Open( g_pDTIFilename, "wt" );
  89. if( fp != FILESYSTEM_INVALID_HANDLE )
  90. {
  91. // Write the header.
  92. g_pFileSystem->FPrintf( fp,
  93. "Class"
  94. ",Prop"
  95. ",Decode Count"
  96. ",Total Bits"
  97. ",Avg Bits"
  98. ",Total Index Bits"
  99. ",Avg Index Bits"
  100. ",Flat prop index"
  101. ",=SUM(D:D)"
  102. "\n" );
  103. int row = 2;
  104. FOR_EACH_LL( g_DTIRecvTables, iTable )
  105. {
  106. CDTIRecvTable *pTable = g_DTIRecvTables[iTable];
  107. if ( !pTable->m_bSawAction )
  108. continue;
  109. for ( int iProp=0; iProp < pTable->m_Props.Count(); iProp++ )
  110. {
  111. CDTIProp *pProp = &pTable->m_Props[iProp];
  112. if ( pProp->m_nDecodes == 0 )
  113. continue;
  114. g_pFileSystem->FPrintf( fp,
  115. // Class/Prop names
  116. "%s"
  117. ",%s"
  118. // Decode count
  119. ",%d"
  120. // Total/Avg bits
  121. ",%d"
  122. ",%.3f"
  123. // Total/Avg index bits
  124. ",%d"
  125. ",%.3f"
  126. ",%d"
  127. ",=D%d/I$1"
  128. "\n",
  129. // Class/Prop names
  130. pTable->m_Name.String(),
  131. pProp->m_Name.String(),
  132. // Decode count
  133. pProp->m_nDecodes,
  134. // Total/Avg bits
  135. pProp->m_nDataBits,
  136. (float)pProp->m_nDataBits / pProp->m_nDecodes,
  137. // Total/Avg index bits
  138. pProp->m_nIndexBits,
  139. (float)pProp->m_nIndexBits / pProp->m_nDecodes,
  140. pProp->m_nPropIndex,
  141. row++
  142. );
  143. }
  144. }
  145. g_pFileSystem->Close( fp );
  146. Msg( "DTI: wrote client stats into %s.\n", g_pDTIFilename );
  147. }
  148. }
  149. void DTI_HookRecvDecoder( CRecvDecoder *pDecoder )
  150. {
  151. if ( !g_bDTIEnabled )
  152. return;
  153. bool dtiEnabled = CommandLine()->FindParm("-dti" ) > 0;
  154. CDTIRecvTable *pTable = new CDTIRecvTable;
  155. pTable->m_Name.Set( pDecoder->GetName() );
  156. pTable->m_Props.SetSize( pDecoder->GetNumProps() );
  157. for ( int i=0; i < pTable->m_Props.Count(); i++ )
  158. {
  159. const SendProp *pSendProp = pDecoder->GetSendProp( i );
  160. if ( !dtiEnabled )
  161. {
  162. pTable->m_Props[i].m_Name.Set( pSendProp->GetName() );
  163. }
  164. else
  165. {
  166. char *parentArrayPropName = const_cast< char * >(const_cast< SendProp * >(pSendProp)->GetParentArrayPropName());
  167. if ( parentArrayPropName )
  168. {
  169. char temp[256];
  170. V_snprintf( temp, sizeof( temp ), "%s:%s", parentArrayPropName, pSendProp->GetName() );
  171. pTable->m_Props[i].m_Name.Set( temp );
  172. }
  173. else
  174. {
  175. pTable->m_Props[i].m_Name.Set( pSendProp->GetName() );
  176. }
  177. }
  178. }
  179. g_DTIRecvTables.AddToTail( pTable );
  180. pDecoder->m_pDTITable = pTable;
  181. }
  182. void _DTI_HookDeltaBits( CRecvDecoder *pDecoder, int iProp, int nDataBits, int nIndexBits )
  183. {
  184. CDTIRecvTable *pTable = pDecoder->m_pDTITable;
  185. if ( !pTable )
  186. return;
  187. CDTIProp *pProp = &pTable->m_Props[iProp];
  188. pProp->m_nDecodes++;
  189. pProp->m_nDataBits += nDataBits;
  190. pProp->m_nIndexBits += nIndexBits;
  191. pProp->m_nPropIndex = iProp;
  192. pTable->m_bSawAction = true;
  193. }