hxchkpt.h
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:17k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. /* These Macros are useful when trying to tune performance to see approximately how long in milliseconds certain lines of
  36.  * code are taking.  The output will display approximately how long it took for the lines between checkpoints.
  37.  * 
  38.  * Available macros in this file and how to use them:
  39.  * 
  40.  * HX_ENABLE_CHECKPOINTS_FOR_MODULE(pModuleName, pOutputFileName)
  41.  * This macro should be used once for the entire dll or exe you are compiling.  It declares a global that is used by the
  42.  * entire module.  A good place to put this for example would be in the dllmain.cpp file.
  43.  *
  44.  * pModuleName - The name of the directory in which the dll or exe you are compiling is located.  This is used 
  45.  * in the log when printing out the file name.
  46.  * pOutputFileName - The name of the output file name where checkpoint data is dumped
  47.  * 
  48.  * HX_LOG_INITIAL_CHECKPOINT(pFunctionName)
  49.  * This macro should be used once at the beginning of each function or method you are interested in timing.
  50.  * 
  51.  * pFunctionName - The name of the function that the checkpoints are in
  52.  *
  53.  * HX_LOG_CHECKPOINT(pComment)
  54.  * This macro should be used whenver timing blocks of code are of interest.  This can be used repeatedly in each function.
  55.  *
  56.  * pComment - The comment passed in will be dumped to the log file.  It is used as a hint to what was being executed
  57.  * for this checkpoint instead of having to refer back to the code.
  58.  *
  59.  * HX_LOG_BLOCK( pComment )
  60.  * This macro logs entry to and exit from a brace delimited block. It writes out two checkpoints - the entry checkpoint 
  61.  * will be the comment prefixed with 'Enter', the exit checkpoint will be the comment prefixed with 'Exit'
  62.  * Note that this macro cannot be used in the same block as HX_LOG_INITIAL_CHECKPOINT.
  63.  *
  64.  * pComment - An identifier for the block. Since blocks often correspond to functions this will often be the function name.
  65.  *
  66.  *     
  67.  * LOG FILE FORMAT
  68.  * The log file is written to in append mode and is several fields delimited by a ;
  69.  * It can easily be loaded into a spreadsheet app since all of them should be able to read delimted text files.
  70.  * Here is a breakdown of the individual fields:
  71.  * Field1: Time elapsed since the last checkpoint
  72.  * Field2: Time elapsed since the first checkpoint in the function
  73.  * Field3: Time elapsed since the first checkpoint in the module
  74.  * Field4: Tick count as reported from the OS
  75.  * Field5: Path to file name
  76.  * Field6: Function name
  77.  * Field7: Line Number of checkpoint
  78.  * Field8: Comment about what the checkpoint is timing
  79.  */
  80. #ifndef _HXCHKPT_H_
  81. #define _HXCHKPT_H_
  82. #if defined( ENABLE_CHECKPOINTS2 ) || defined( ENABLE_PERFORMANCE2 )
  83. #include "hxperf.h"
  84. #elif defined( ENABLE_CHECKPOINTS )
  85. #include "hlxclib/stdio.h"
  86. #include "hxtick.h"
  87. #include "hxmap.h"
  88. #define MAX_CHECKPOINTLISTS_PER_MODULE 256
  89. #define MAX_CHECKPOINTS_PER_FUNCTION 1024
  90. #define MAX_ACCUMULATORS_PER_FUNCTION 64
  91. // This class represents the data that is unique per checkpoint
  92. class CHXCheckpoint
  93. {
  94. public:
  95.     CHXCheckpoint() :
  96. m_ulLineNumber(0),
  97. m_ulTime(0)
  98.     {
  99.     }
  100.     ~CHXCheckpoint()
  101.     {
  102.     }
  103.     // These are public members for access speed since the checkpoint code should be as lightweight as possible.  I am
  104.     // also trying to reduce the number of lines of code since this is all inline in a header file.
  105.     UINT32 m_ulLineNumber;
  106.     UINT32 m_ulTime;
  107.     char m_pStaticComment[ 64 ]; /* Flawfinder: ignore */
  108. };
  109. class CHXAccumCheckpoint : 
  110.     public CHXCheckpoint
  111. {
  112. public:
  113.     CHXAccumCheckpoint() :
  114. CHXCheckpoint(),
  115. m_ulID( 0 ),
  116. m_ulMarker( 0 )
  117.     {
  118.     }
  119. public:
  120.     UINT32  m_ulID;
  121.     UINT32 m_ulMarker;
  122. };
  123. // This class represents a way to categorize the checkpoints associated with a function or method.  It contains the list
  124. // of checkpoints for that function or method and the filename where that function or method is located.
  125. class CHXCheckpointList
  126. {
  127. public:
  128.     CHXCheckpointList(const char* pFunctionName, const char* pSourceFileName);
  129.     ~CHXCheckpointList()
  130.     {
  131.     }
  132.     void AddCheckpoint(const char* pComment, UINT32 ulLineNumber, UINT32 ulTime)
  133.     {
  134. if( m_ulCheckpointIndex < MAX_CHECKPOINTS_PER_FUNCTION )
  135. {
  136.     CHXCheckpoint* pCheckpoint = &m_CheckpointArray[m_ulCheckpointIndex];
  137.     pCheckpoint->m_ulLineNumber = ulLineNumber;
  138.     pCheckpoint->m_ulTime = ulTime;
  139.     UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
  140.     ::strncpy( pCheckpoint->m_pStaticComment, pComment, copySize ); /* Flawfinder: ignore */
  141.     pCheckpoint->m_pStaticComment[copySize] = '';
  142.     m_ulCheckpointIndex++;
  143. }
  144. else
  145. {
  146.          for( int i = 0; i < MAX_CHECKPOINTS_PER_FUNCTION; ++i )
  147.     {
  148. CHXCheckpoint* pCheckpoint = &m_CheckpointArray[i];
  149. UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
  150. ::strncpy( pCheckpoint->m_pStaticComment, "***ERROR*** - too many checkpoints in checkpoint list", copySize ); /* Flawfinder: ignore */
  151. pCheckpoint->m_pStaticComment[copySize] = '';
  152.     }
  153. }
  154.     }
  155.     void PrimeAccumulator( UINT32 id, const char* pComment, UINT32 ulLineNumber, UINT32 ulTime )
  156.     {
  157. void* pValue = NULL;
  158. if( m_accumulators.Lookup( id, pValue ) )
  159. {
  160.     CHXAccumCheckpoint* pCheckpoint = (CHXAccumCheckpoint*) pValue;
  161.     pCheckpoint->m_ulMarker = ulTime;
  162. }
  163. else if( m_ulAccumulatorIndex < MAX_ACCUMULATORS_PER_FUNCTION )
  164. {
  165.     CHXAccumCheckpoint* pCheckpoint = &m_AccumulatorArray[ m_ulAccumulatorIndex++ ];
  166.     m_accumulators.SetAt( id, pCheckpoint );
  167.     pCheckpoint->m_ulID = id;
  168.     pCheckpoint->m_ulLineNumber = ulLineNumber;
  169.     pCheckpoint->m_ulMarker = ulTime;
  170.     UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
  171.     ::strncpy( pCheckpoint->m_pStaticComment, pComment, copySize ); /* Flawfinder: ignore */
  172.     pCheckpoint->m_pStaticComment[copySize] = '';
  173. }
  174. else
  175. {
  176.     for( int i = 0; i < MAX_ACCUMULATORS_PER_FUNCTION; ++i )
  177.     {
  178. CHXAccumCheckpoint* pCheckpoint = &m_AccumulatorArray[ i ];
  179. UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
  180. ::strncpy( pCheckpoint->m_pStaticComment, "***ERROR*** - too many accumulator checkpoints in checkpoint list", copySize ); /* Flawfinder: ignore */
  181. pCheckpoint->m_pStaticComment[copySize] = '';
  182.     }
  183. }
  184.     }
  185.     void UpdateAccumulator( UINT32 id, UINT32 ulTime )
  186.     {
  187. void* pValue = NULL;
  188. if( m_accumulators.Lookup( id, pValue ) )
  189. {
  190.     CHXAccumCheckpoint* pCheckpoint = (CHXAccumCheckpoint*) pValue;
  191.     pCheckpoint->m_ulTime += ulTime - pCheckpoint->m_ulMarker;
  192.     pCheckpoint->m_ulMarker = 0;
  193. }
  194.     }
  195.     void AccumulateValue( UINT32 id, const char* pComment, UINT32 ulLineNumber, UINT32 ulValue )
  196.     {
  197. void* pValue = NULL;
  198. if( m_accumulators.Lookup( id, pValue ) )
  199. {
  200.     CHXAccumCheckpoint* pCheckpoint = (CHXAccumCheckpoint*) pValue;
  201.     pCheckpoint->m_ulTime += ulValue;
  202. }
  203. else if( m_ulAccumulatorIndex < MAX_ACCUMULATORS_PER_FUNCTION )
  204. {
  205.     CHXAccumCheckpoint* pCheckpoint = &m_AccumulatorArray[ m_ulAccumulatorIndex++ ];
  206.     m_accumulators.SetAt( id, pCheckpoint );
  207.     pCheckpoint->m_ulID = id;
  208.     pCheckpoint->m_ulLineNumber = ulLineNumber;
  209.     pCheckpoint->m_ulTime = ulValue;
  210.     UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
  211.     ::strncpy( pCheckpoint->m_pStaticComment, pComment, copySize ); /* Flawfinder: ignore */
  212.     pCheckpoint->m_pStaticComment[copySize] = '';
  213. }
  214. else
  215. {
  216.     for( int i = 0; i < MAX_ACCUMULATORS_PER_FUNCTION; ++i )
  217.     {
  218. CHXAccumCheckpoint* pCheckpoint = &m_AccumulatorArray[ i ];
  219. UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
  220. ::strncpy( pCheckpoint->m_pStaticComment, "***ERROR*** - too many accumulator checkpoints in checkpoint list", copySize ); /* Flawfinder: ignore */
  221. pCheckpoint->m_pStaticComment[copySize] = '';
  222.     }
  223. }
  224.     }
  225.     // These are public members for access speed since the checkpoint code should be as lightweight as possible.  I am
  226.     // also trying to reduce the number of lines of code since this is all inline in a header file.
  227.     const char*     m_pFunctionName;
  228.     const char*     m_pSourceFileName;
  229.     UINT32     m_ulCheckpointIndex;
  230.     CHXCheckpoint   m_CheckpointArray[MAX_CHECKPOINTS_PER_FUNCTION];
  231.     UINT32      m_ulAccumulatorIndex;
  232.     CHXAccumCheckpoint  m_AccumulatorArray[MAX_ACCUMULATORS_PER_FUNCTION];
  233.     CHXMapLongToObj m_accumulators;
  234. };
  235. // This class manages an array CHXCheckpointList objects.  It uses these to dump out timing information
  236. class CHXCheckpointManager
  237. {
  238. public:
  239.     CHXCheckpointManager(const char* pModuleName, const char* pOutputFileName ) :
  240. m_pModuleName(pModuleName),
  241. m_pOutputFileName(pOutputFileName),
  242. m_ulCheckpointListIndex(0)
  243.     {
  244.     }
  245.     ~CHXCheckpointManager()
  246.     {
  247. // Since writing to a file slows down startup time timing data is only dumped to the file when the global checkpoint
  248. // manager object associated with a dll or exe is destroyed meaning an unload or program termination occured.
  249. DumpCheckpoints();
  250.     }
  251.     void AddCheckpointList(CHXCheckpointList* pCheckpointList)
  252.     {
  253. printf( "AddCheckpointList %p to manager %pn", pCheckpointList, this );
  254. if( m_ulCheckpointListIndex < MAX_CHECKPOINTLISTS_PER_MODULE )
  255. {
  256.     m_pCheckpointListArray[m_ulCheckpointListIndex++] = pCheckpointList;
  257. }
  258. else
  259. {
  260.     for( int i = 0; i < MAX_CHECKPOINTLISTS_PER_MODULE; ++i )
  261.     {
  262. CHXCheckpointList* pCheckpointList = m_pCheckpointListArray[ i ];
  263. for( int i = 0; i < MAX_CHECKPOINTS_PER_FUNCTION; ++i )
  264. {
  265.     CHXCheckpoint* pCheckpoint = &pCheckpointList->m_CheckpointArray[i];
  266.     UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
  267.     ::strncpy( pCheckpoint->m_pStaticComment, "***ERROR*** - too many checkpoint lists in module", copySize ); /* Flawfinder: ignore */
  268.     pCheckpoint->m_pStaticComment[copySize] = '';
  269. }
  270.     }
  271. }
  272.     }
  273.     void DumpCheckpoints()
  274.     {
  275. #ifdef DUMP_CHECKPOINT_ONLY_IF_EXISTS
  276. FILE* pFile = ::fopen(m_pOutputFileName, "r+");
  277. if(pFile)
  278. {
  279. fseek(pFile, 0, SEEK_END);
  280. }
  281. #else
  282. FILE* pFile = ::fopen(m_pOutputFileName, "a+");
  283. #endif
  284. if (pFile)
  285. {
  286.     UINT32 i, j;
  287.     ::fprintf(pFile, "Format==> ElapsedTimeFromPreviousCheckpoint;ElapsedTimeFromStartOfFunction;ElapsedTimeSinceFirstModuleCheckpoint;OSTime;ModuleAndFileName;FunctionName;LineNumber;Commentn");
  288.     for (i = 0; i < m_ulCheckpointListIndex; i++)
  289.     {
  290. for (j = 0; j < m_pCheckpointListArray[i]->m_ulCheckpointIndex; j++)
  291. {
  292.     ::fprintf(pFile, "%lu;%lu;%lu;%lu;%s\%s;%s;%lu;%sn", (j ? (m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulTime - m_pCheckpointListArray[i]->m_CheckpointArray[j-1].m_ulTime) : 0),
  293. m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulTime - m_pCheckpointListArray[i]->m_CheckpointArray[0].m_ulTime,
  294. m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulTime - m_pCheckpointListArray[0]->m_CheckpointArray[0].m_ulTime,
  295. m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulTime,
  296. m_pModuleName,
  297. m_pCheckpointListArray[i]->m_pSourceFileName,
  298. m_pCheckpointListArray[i]->m_pFunctionName,
  299. m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulLineNumber,
  300. m_pCheckpointListArray[i]->m_CheckpointArray[j].m_pStaticComment);
  301. }
  302.     }
  303.     // Write out accumulators
  304.     ::fprintf( pFile, "nnAccumulators Format==> TotalTime;ModuleAndFileName;FunctionName;LineNumber;Commentn" );
  305.     for (i = 0; i < m_ulCheckpointListIndex; i++)
  306.     {
  307. for (j = 0; j < m_pCheckpointListArray[i]->m_ulAccumulatorIndex; j++)
  308. {
  309.     CHXAccumCheckpoint* pCP = (CHXAccumCheckpoint*) &m_pCheckpointListArray[i]->m_AccumulatorArray[ j ];
  310.     ::fprintf(pFile, "%lu;%s\%s;%s;%lu;%sn", pCP->m_ulTime,
  311.     m_pModuleName,
  312.     m_pCheckpointListArray[i]->m_pSourceFileName,
  313.     m_pCheckpointListArray[i]->m_pFunctionName,
  314.     pCP->m_ulLineNumber,
  315.     pCP->m_pStaticComment);
  316. }
  317.     }
  318.     ::fprintf( pFile, "nnn" );
  319.     ::fclose(pFile);
  320. }
  321.     }
  322. protected:
  323.     CHXCheckpointList*  m_pCheckpointListArray[ MAX_CHECKPOINTLISTS_PER_MODULE ];
  324.     const char* m_pModuleName;
  325.     const char* m_pOutputFileName;
  326.     UINT32 m_ulCheckpointListIndex;
  327. };
  328. extern CHXCheckpointManager g_HXCheckpointManager;
  329. inline
  330. CHXCheckpointList::CHXCheckpointList(const char* pFunctionName, const char* pSourceFileName) :
  331.     m_pFunctionName(pFunctionName),
  332.     m_pSourceFileName(pSourceFileName),
  333.     m_ulCheckpointIndex(0)
  334. {
  335.     extern CHXCheckpointManager g_HXCheckpointManager;
  336.     g_HXCheckpointManager.AddCheckpointList(this);
  337. }
  338. #define HX_ENABLE_CHECKPOINTS_FOR_MODULE(pModuleName, pOutputFileName)
  339.     CHXCheckpointManager g_HXCheckpointManager(pModuleName, pOutputFileName);
  340. #define HX_SETUP_CHECKPOINTLIST( pFunctionName )       
  341.     static CHXCheckpointList HXFunctionCheckpointList(pFunctionName, __FILE__);
  342.     
  343. #define HX_LOG_CHECKPOINT(pComment)       
  344.     HXFunctionCheckpointList.AddCheckpoint(pComment, __LINE__, HX_GET_BETTERTICKCOUNT());
  345. #define HX_PRIME_ACCUMULATOR(id, pComment)
  346.     HXFunctionCheckpointList.PrimeAccumulator( id, pComment, __LINE__, HX_GET_BETTERTICKCOUNT() );
  347. #define HX_UPDATE_ACCUMULATOR(id)
  348.     HXFunctionCheckpointList.UpdateAccumulator(id, HX_GET_BETTERTICKCOUNT() );
  349. #define HX_ACCUMULATE(id, pComment, data)        
  350.     HXFunctionCheckpointList.AccumulateValue(id, pComment,  __LINE__, data );
  351. #define HX_LOG_INITIAL_CHECKPOINT(pFunctionName)       
  352.     HX_SETUP_CHECKPOINTLIST( pFunctionName )       
  353.     HX_LOG_CHECKPOINT( "Initial Function Checkpoint" )
  354.     
  355. #define HX_LOG_SINGLESHOT_CHECKPOINT( pFunctionName, pComment)       
  356.     {       
  357. static BOOL doneCheckPoint = FALSE;       
  358. if( !doneCheckPoint )       
  359. {       
  360.     HX_SETUP_CHECKPOINTLIST( pFunctionName )       
  361.     HX_LOG_CHECKPOINT( pComment )                               
  362.     doneCheckPoint = TRUE;       
  363. }       
  364.     }
  365. #define HX_LOG_BLOCK( pBlockName )
  366.     HX_SETUP_CHECKPOINTLIST( "a" );
  367.     class CHXBlockLogger
  368.     {
  369.     public:
  370. CHXBlockLogger( CHXCheckpointList* pCheckpointList )
  371. : m_pCheckpointList( pCheckpointList )
  372. {
  373.     m_pCheckpointList->AddCheckpoint( "Enter " pBlockName, __LINE__, HX_GET_BETTERTICKCOUNT());
  374. }
  375. ~CHXBlockLogger()
  376. {
  377.     m_pCheckpointList->AddCheckpoint( "Exit " pBlockName, __LINE__, HX_GET_BETTERTICKCOUNT());
  378. }
  379.     private:
  380. CHXCheckpointList* m_pCheckpointList;
  381.     };
  382.     CHXBlockLogger blockLogger1278( &HXFunctionCheckpointList );
  383. #define HX_LOG_START_SECTION( pSectionName )       
  384.     HX_LOG_SINGLESHOT_CHECKPOINT( "", "--- Start section " pSectionName );
  385. #define HX_LOG_END_SECTION( pSectionName )       
  386.     HX_LOG_SINGLESHOT_CHECKPOINT( "", "--- End section " pSectionName );
  387. #else /* ENABLE_CHECKPOINTS && ENABLE_CHECKPOINTS2 not Defined */
  388. #define HX_ENABLE_CHECKPOINTS_FOR_MODULE(pModuleName, pOutputFileName)
  389. #define HX_SETUP_CHECKPOINTLIST( pFunctionName )
  390. #define HX_LOG_CHECKPOINT(pComment)
  391. #define HX_PRIME_ACCUMULATOR(id, pComment)
  392. #define HX_UPDATE_ACCUMULATOR(id)
  393. #define HX_ACCUMULATE(id, pComment, data)
  394. #define HX_LOG_INITIAL_CHECKPOINT(pFunctionName)
  395. #define HX_LOG_SINGLESHOT_CHECKPOINT( pFunctionName, pComment)
  396. #define HX_LOG_BLOCK( pBlockName )
  397. #define HX_LOG_START_SECTION( pSectionName )
  398. #define HX_LOG_END_SECTION( pSectionName )
  399. #endif /* ENABLE_CHECKPOINTS */
  400. #endif /* _HXCHKPT_H_ */