hxchkpt.h
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:18k
源码类别:

Symbian

开发平台:

Visual C++

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