diff options
Diffstat (limited to 'engine/dt_instrumentation.cpp')
| -rw-r--r-- | engine/dt_instrumentation.cpp | 239 |
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; +} + + + |