summaryrefslogtreecommitdiff
path: root/engine/dt_instrumentation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engine/dt_instrumentation.cpp')
-rw-r--r--engine/dt_instrumentation.cpp239
1 files changed, 239 insertions, 0 deletions
diff --git a/engine/dt_instrumentation.cpp b/engine/dt_instrumentation.cpp
new file mode 100644
index 0000000..6e93b82
--- /dev/null
+++ b/engine/dt_instrumentation.cpp
@@ -0,0 +1,239 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#if (defined(_WIN32) && (!defined(_X360) ) )
+#include <windows.h>
+#endif
+#include "tier0/platform.h"
+#include "tier0/icommandline.h"
+#include "dt_instrumentation.h"
+#include "utlvector.h"
+#include "utllinkedlist.h"
+#include "tier0/fasttimer.h"
+#include "utllinkedlist.h"
+#include "tier0/dbg.h"
+#include "tier1/utlstring.h"
+#include "dt_recv_decoder.h"
+#include "filesystem.h"
+#include "filesystem_engine.h"
+#include "cdll_int.h"
+#include "client.h"
+#include "common.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+bool g_bDTIEnabled = false;
+const char *g_pDTIFilename;
+
+
+class CDTIProp
+{
+public:
+ CDTIProp()
+ {
+ m_nDecodes = m_nDataBits = m_nIndexBits = 0;
+ }
+
+ CUtlString m_Name;
+ int m_nDecodes;
+ int m_nDataBits;
+ int m_nIndexBits;
+};
+
+
+class CDTIRecvTable
+{
+public:
+ CDTIRecvTable()
+ {
+ m_bSawAction = false;
+ }
+
+ CUtlString m_Name;
+ CUtlVector<CDTIProp> m_Props;
+ bool m_bSawAction;
+};
+
+
+CUtlLinkedList<CDTIRecvTable*, int> g_DTIRecvTables;
+
+
+void DTI_Init()
+{
+#if ( defined( IS_WINDOWS_PC ) && (! defined( SWDS ) ) )
+ extern IVEngineClient *engineClient;
+ if ( CommandLine()->FindParm( "-dti" ) && !g_bDTIEnabled )
+ {
+ g_bDTIEnabled = true;
+
+ SYSTEMTIME systemTime;
+ GetLocalTime( &systemTime );
+
+ char dtiFileName[MAX_PATH];
+ char dtiLevelName[MAX_PATH];
+ V_FileBase( engineClient->GetLevelName(), dtiLevelName, ARRAYSIZE( dtiLevelName ) );
+ V_snprintf( dtiFileName, ARRAYSIZE( dtiFileName ), "dti_client_%s_%02d%02d%02d-%02d%02d%02d.csv",
+ dtiLevelName,
+ systemTime.wYear % 100, systemTime.wMonth, systemTime.wDay,
+ systemTime.wHour, systemTime.wMinute, systemTime.wSecond );
+ g_pDTIFilename = COM_StringCopy( dtiFileName );
+ }
+#endif
+}
+
+
+void DTI_Term()
+{
+ if ( g_bDTIEnabled )
+ {
+ DTI_Flush();
+ g_DTIRecvTables.PurgeAndDeleteElements();
+ delete g_pDTIFilename;
+ g_pDTIFilename = NULL;
+ g_bDTIEnabled = false;
+ }
+}
+
+
+void DTI_Flush()
+{
+ if ( !g_bDTIEnabled )
+ return;
+
+ FileHandle_t fp = g_pFileSystem->Open( g_pDTIFilename, "wt" );
+ if( fp != FILESYSTEM_INVALID_HANDLE )
+ {
+ // Write the header.
+ g_pFileSystem->FPrintf( fp,
+ "Class"
+ ",Prop"
+ ",Decode Count"
+ ",Total Bits"
+ ",Avg Bits"
+ ",Total Index Bits"
+ ",Avg Index Bits"
+ ",=SUM(D:D)"
+ "\n" );
+
+ int row = 2;
+
+ FOR_EACH_LL( g_DTIRecvTables, iTable )
+ {
+ CDTIRecvTable *pTable = g_DTIRecvTables[iTable];
+
+ if ( !pTable->m_bSawAction )
+ continue;
+
+ for ( int iProp=0; iProp < pTable->m_Props.Count(); iProp++ )
+ {
+ CDTIProp *pProp = &pTable->m_Props[iProp];
+
+ if ( pProp->m_nDecodes == 0 )
+ continue;
+
+ g_pFileSystem->FPrintf( fp,
+ // Class/Prop names
+ "%s"
+ ",%s"
+
+ // Decode count
+ ",%d"
+
+ // Total/Avg bits
+ ",%d"
+ ",%.3f"
+
+ // Total/Avg index bits
+ ",%d"
+ ",%.3f"
+ ",=D%d/H$1"
+
+ "\n",
+
+ // Class/Prop names
+ pTable->m_Name.String(),
+ pProp->m_Name.String(),
+
+ // Decode count
+ pProp->m_nDecodes,
+
+ // Total/Avg bits
+ pProp->m_nDataBits,
+ (float)pProp->m_nDataBits / pProp->m_nDecodes,
+
+ // Total/Avg index bits
+ pProp->m_nIndexBits,
+ (float)pProp->m_nIndexBits / pProp->m_nDecodes,
+ row++
+ );
+ }
+ }
+
+ g_pFileSystem->Close( fp );
+
+ Msg( "DTI: wrote client stats into %s.\n", g_pDTIFilename );
+ }
+}
+
+
+void DTI_HookRecvDecoder( CRecvDecoder *pDecoder )
+{
+ if ( !g_bDTIEnabled )
+ return;
+
+ bool dtiEnabled = CommandLine()->FindParm("-dti" ) > 0;
+
+ CDTIRecvTable *pTable = new CDTIRecvTable;
+ pTable->m_Name.Set( pDecoder->GetName() );
+
+ pTable->m_Props.SetSize( pDecoder->GetNumProps() );
+ for ( int i=0; i < pTable->m_Props.Count(); i++ )
+ {
+ const SendProp *pSendProp = pDecoder->GetSendProp( i );
+ if ( !dtiEnabled )
+ {
+ pTable->m_Props[i].m_Name.Set( pSendProp->GetName() );
+ }
+ else
+ {
+ char *parentArrayPropName = const_cast< char * >(const_cast< SendProp * >(pSendProp)->GetParentArrayPropName());
+ if ( parentArrayPropName )
+ {
+ char temp[256];
+ V_snprintf( temp, sizeof( temp ), "%s:%s", parentArrayPropName, pSendProp->GetName() );
+ pTable->m_Props[i].m_Name.Set( temp );
+ }
+ else
+ {
+ pTable->m_Props[i].m_Name.Set( pSendProp->GetName() );
+ }
+ }
+ }
+
+ g_DTIRecvTables.AddToTail( pTable );
+
+ pDecoder->m_pDTITable = pTable;
+}
+
+
+void _DTI_HookDeltaBits( CRecvDecoder *pDecoder, int iProp, int nDataBits, int nIndexBits )
+{
+ CDTIRecvTable *pTable = pDecoder->m_pDTITable;
+ if ( !pTable )
+ return;
+
+ CDTIProp *pProp = &pTable->m_Props[iProp];
+ pProp->m_nDecodes++;
+ pProp->m_nDataBits += nDataBits;
+ pProp->m_nIndexBits += nIndexBits;
+
+ pTable->m_bSawAction = true;
+}
+
+
+