Team Fortress 2 Source Code as on 22/4/2020
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.

239 lines
4.7 KiB

  1. //========= Copyright 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 "tier0/icommandline.h"
  12. #include "dt_instrumentation.h"
  13. #include "utlvector.h"
  14. #include "utllinkedlist.h"
  15. #include "tier0/fasttimer.h"
  16. #include "utllinkedlist.h"
  17. #include "tier0/dbg.h"
  18. #include "tier1/utlstring.h"
  19. #include "dt_recv_decoder.h"
  20. #include "filesystem.h"
  21. #include "filesystem_engine.h"
  22. #include "cdll_int.h"
  23. #include "client.h"
  24. #include "common.h"
  25. // memdbgon must be the last include file in a .cpp file!!!
  26. #include "tier0/memdbgon.h"
  27. bool g_bDTIEnabled = false;
  28. const char *g_pDTIFilename;
  29. class CDTIProp
  30. {
  31. public:
  32. CDTIProp()
  33. {
  34. m_nDecodes = m_nDataBits = m_nIndexBits = 0;
  35. }
  36. CUtlString m_Name;
  37. int m_nDecodes;
  38. int m_nDataBits;
  39. int m_nIndexBits;
  40. };
  41. class CDTIRecvTable
  42. {
  43. public:
  44. CDTIRecvTable()
  45. {
  46. m_bSawAction = false;
  47. }
  48. CUtlString m_Name;
  49. CUtlVector<CDTIProp> m_Props;
  50. bool m_bSawAction;
  51. };
  52. CUtlLinkedList<CDTIRecvTable*, int> g_DTIRecvTables;
  53. void DTI_Init()
  54. {
  55. #if ( defined( IS_WINDOWS_PC ) && (! defined( SWDS ) ) )
  56. extern IVEngineClient *engineClient;
  57. if ( CommandLine()->FindParm( "-dti" ) && !g_bDTIEnabled )
  58. {
  59. g_bDTIEnabled = true;
  60. SYSTEMTIME systemTime;
  61. GetLocalTime( &systemTime );
  62. char dtiFileName[MAX_PATH];
  63. char dtiLevelName[MAX_PATH];
  64. V_FileBase( engineClient->GetLevelName(), dtiLevelName, ARRAYSIZE( dtiLevelName ) );
  65. V_snprintf( dtiFileName, ARRAYSIZE( dtiFileName ), "dti_client_%s_%02d%02d%02d-%02d%02d%02d.csv",
  66. dtiLevelName,
  67. systemTime.wYear % 100, systemTime.wMonth, systemTime.wDay,
  68. systemTime.wHour, systemTime.wMinute, systemTime.wSecond );
  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. ",=SUM(D:D)"
  101. "\n" );
  102. int row = 2;
  103. FOR_EACH_LL( g_DTIRecvTables, iTable )
  104. {
  105. CDTIRecvTable *pTable = g_DTIRecvTables[iTable];
  106. if ( !pTable->m_bSawAction )
  107. continue;
  108. for ( int iProp=0; iProp < pTable->m_Props.Count(); iProp++ )
  109. {
  110. CDTIProp *pProp = &pTable->m_Props[iProp];
  111. if ( pProp->m_nDecodes == 0 )
  112. continue;
  113. g_pFileSystem->FPrintf( fp,
  114. // Class/Prop names
  115. "%s"
  116. ",%s"
  117. // Decode count
  118. ",%d"
  119. // Total/Avg bits
  120. ",%d"
  121. ",%.3f"
  122. // Total/Avg index bits
  123. ",%d"
  124. ",%.3f"
  125. ",=D%d/H$1"
  126. "\n",
  127. // Class/Prop names
  128. pTable->m_Name.String(),
  129. pProp->m_Name.String(),
  130. // Decode count
  131. pProp->m_nDecodes,
  132. // Total/Avg bits
  133. pProp->m_nDataBits,
  134. (float)pProp->m_nDataBits / pProp->m_nDecodes,
  135. // Total/Avg index bits
  136. pProp->m_nIndexBits,
  137. (float)pProp->m_nIndexBits / pProp->m_nDecodes,
  138. row++
  139. );
  140. }
  141. }
  142. g_pFileSystem->Close( fp );
  143. Msg( "DTI: wrote client stats into %s.\n", g_pDTIFilename );
  144. }
  145. }
  146. void DTI_HookRecvDecoder( CRecvDecoder *pDecoder )
  147. {
  148. if ( !g_bDTIEnabled )
  149. return;
  150. bool dtiEnabled = CommandLine()->FindParm("-dti" ) > 0;
  151. CDTIRecvTable *pTable = new CDTIRecvTable;
  152. pTable->m_Name.Set( pDecoder->GetName() );
  153. pTable->m_Props.SetSize( pDecoder->GetNumProps() );
  154. for ( int i=0; i < pTable->m_Props.Count(); i++ )
  155. {
  156. const SendProp *pSendProp = pDecoder->GetSendProp( i );
  157. if ( !dtiEnabled )
  158. {
  159. pTable->m_Props[i].m_Name.Set( pSendProp->GetName() );
  160. }
  161. else
  162. {
  163. char *parentArrayPropName = const_cast< char * >(const_cast< SendProp * >(pSendProp)->GetParentArrayPropName());
  164. if ( parentArrayPropName )
  165. {
  166. char temp[256];
  167. V_snprintf( temp, sizeof( temp ), "%s:%s", parentArrayPropName, pSendProp->GetName() );
  168. pTable->m_Props[i].m_Name.Set( temp );
  169. }
  170. else
  171. {
  172. pTable->m_Props[i].m_Name.Set( pSendProp->GetName() );
  173. }
  174. }
  175. }
  176. g_DTIRecvTables.AddToTail( pTable );
  177. pDecoder->m_pDTITable = pTable;
  178. }
  179. void _DTI_HookDeltaBits( CRecvDecoder *pDecoder, int iProp, int nDataBits, int nIndexBits )
  180. {
  181. CDTIRecvTable *pTable = pDecoder->m_pDTITable;
  182. if ( !pTable )
  183. return;
  184. CDTIProp *pProp = &pTable->m_Props[iProp];
  185. pProp->m_nDecodes++;
  186. pProp->m_nDataBits += nDataBits;
  187. pProp->m_nIndexBits += nIndexBits;
  188. pTable->m_bSawAction = true;
  189. }