📄 hxchkpt.h
字号:
UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
::strncpy( pCheckpoint->m_pStaticComment, pComment, copySize ); /* Flawfinder: ignore */
pCheckpoint->m_pStaticComment[copySize] = '\0';
}
else
{
for( int i = 0; i < MAX_ACCUMULATORS_PER_FUNCTION; ++i )
{
CHXAccumCheckpoint* pCheckpoint = &m_AccumulatorArray[ i ];
UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
::strncpy( pCheckpoint->m_pStaticComment, "***ERROR*** - too many accumulator checkpoints in checkpoint list", copySize ); /* Flawfinder: ignore */
pCheckpoint->m_pStaticComment[copySize] = '\0';
}
}
}
// These are public members for access speed since the checkpoint code should be as lightweight as possible. I am
// also trying to reduce the number of lines of code since this is all inline in a header file.
const char* m_pFunctionName;
const char* m_pSourceFileName;
UINT32 m_ulCheckpointIndex;
CHXCheckpoint m_CheckpointArray[MAX_CHECKPOINTS_PER_FUNCTION];
UINT32 m_ulAccumulatorIndex;
CHXAccumCheckpoint m_AccumulatorArray[MAX_ACCUMULATORS_PER_FUNCTION];
CHXMapLongToObj m_accumulators;
};
// This class manages an array CHXCheckpointList objects. It uses these to dump out timing information
class CHXCheckpointManager
{
public:
CHXCheckpointManager(const char* pModuleName, const char* pOutputFileName ) :
m_pModuleName(pModuleName),
m_pOutputFileName(pOutputFileName),
m_ulCheckpointListIndex(0)
{
}
~CHXCheckpointManager()
{
// Since writing to a file slows down startup time timing data is only dumped to the file when the global checkpoint
// manager object associated with a dll or exe is destroyed meaning an unload or program termination occured.
DumpCheckpoints();
}
void AddCheckpointList(CHXCheckpointList* pCheckpointList)
{
printf( "AddCheckpointList %p to manager %p\n", pCheckpointList, this );
if( m_ulCheckpointListIndex < MAX_CHECKPOINTLISTS_PER_MODULE )
{
m_pCheckpointListArray[m_ulCheckpointListIndex++] = pCheckpointList;
}
else
{
for( int i = 0; i < MAX_CHECKPOINTLISTS_PER_MODULE; ++i )
{
CHXCheckpointList* pCheckpointList = m_pCheckpointListArray[ i ];
for( int i = 0; i < MAX_CHECKPOINTS_PER_FUNCTION; ++i )
{
CHXCheckpoint* pCheckpoint = &pCheckpointList->m_CheckpointArray[i];
UINT32 copySize = sizeof(pCheckpoint->m_pStaticComment) - 1;
::strncpy( pCheckpoint->m_pStaticComment, "***ERROR*** - too many checkpoint lists in module", copySize ); /* Flawfinder: ignore */
pCheckpoint->m_pStaticComment[copySize] = '\0';
}
}
}
}
void DumpCheckpoints()
{
#ifdef DUMP_CHECKPOINT_ONLY_IF_EXISTS
FILE* pFile = ::fopen(m_pOutputFileName, "r+");
if(pFile)
{
fseek(pFile, 0, SEEK_END);
}
#else
FILE* pFile = ::fopen(m_pOutputFileName, "a+");
#endif
if (pFile)
{
UINT32 i, j;
::fprintf(pFile, "Format==> ElapsedTimeFromPreviousCheckpoint;ElapsedTimeFromStartOfFunction;ElapsedTimeSinceFirstModuleCheckpoint;OSTime;ModuleAndFileName;FunctionName;LineNumber;Comment\n");
for (i = 0; i < m_ulCheckpointListIndex; i++)
{
for (j = 0; j < m_pCheckpointListArray[i]->m_ulCheckpointIndex; j++)
{
::fprintf(pFile, "%lu;%lu;%lu;%lu;%s\\%s;%s;%lu;%s\n", (j ? (m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulTime - m_pCheckpointListArray[i]->m_CheckpointArray[j-1].m_ulTime) : 0),
m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulTime - m_pCheckpointListArray[i]->m_CheckpointArray[0].m_ulTime,
m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulTime - m_pCheckpointListArray[0]->m_CheckpointArray[0].m_ulTime,
m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulTime,
m_pModuleName,
m_pCheckpointListArray[i]->m_pSourceFileName,
m_pCheckpointListArray[i]->m_pFunctionName,
m_pCheckpointListArray[i]->m_CheckpointArray[j].m_ulLineNumber,
m_pCheckpointListArray[i]->m_CheckpointArray[j].m_pStaticComment);
}
}
// Write out accumulators
::fprintf( pFile, "\n\nAccumulators Format==> TotalTime;ModuleAndFileName;FunctionName;LineNumber;Comment\n" );
for (i = 0; i < m_ulCheckpointListIndex; i++)
{
for (j = 0; j < m_pCheckpointListArray[i]->m_ulAccumulatorIndex; j++)
{
CHXAccumCheckpoint* pCP = (CHXAccumCheckpoint*) &m_pCheckpointListArray[i]->m_AccumulatorArray[ j ];
::fprintf(pFile, "%lu;%s\\%s;%s;%lu;%s\n", pCP->m_ulTime,
m_pModuleName,
m_pCheckpointListArray[i]->m_pSourceFileName,
m_pCheckpointListArray[i]->m_pFunctionName,
pCP->m_ulLineNumber,
pCP->m_pStaticComment);
}
}
::fprintf( pFile, "\n\n\n" );
::fclose(pFile);
}
}
protected:
CHXCheckpointList* m_pCheckpointListArray[ MAX_CHECKPOINTLISTS_PER_MODULE ];
const char* m_pModuleName;
const char* m_pOutputFileName;
UINT32 m_ulCheckpointListIndex;
};
extern CHXCheckpointManager g_HXCheckpointManager;
inline
CHXCheckpointList::CHXCheckpointList(const char* pFunctionName, const char* pSourceFileName) :
m_pFunctionName(pFunctionName),
m_pSourceFileName(pSourceFileName),
m_ulCheckpointIndex(0)
{
extern CHXCheckpointManager g_HXCheckpointManager;
g_HXCheckpointManager.AddCheckpointList(this);
}
#define HX_ENABLE_CHECKPOINTS_FOR_MODULE(pModuleName, pOutputFileName) \
CHXCheckpointManager g_HXCheckpointManager(pModuleName, pOutputFileName);
#define HX_SETUP_CHECKPOINTLIST( pFunctionName ) \
static CHXCheckpointList HXFunctionCheckpointList(pFunctionName, __FILE__);
#define HX_LOG_CHECKPOINT(pComment) \
HXFunctionCheckpointList.AddCheckpoint(pComment, __LINE__, HX_GET_BETTERTICKCOUNT());
#define HX_PRIME_ACCUMULATOR(id, pComment) \
HXFunctionCheckpointList.PrimeAccumulator( id, pComment, __LINE__, HX_GET_BETTERTICKCOUNT() );
#define HX_UPDATE_ACCUMULATOR(id) \
HXFunctionCheckpointList.UpdateAccumulator(id, HX_GET_BETTERTICKCOUNT() );
#define HX_ACCUMULATE(id, pComment, data) \
HXFunctionCheckpointList.AccumulateValue(id, pComment, __LINE__, data );
#define HX_LOG_INITIAL_CHECKPOINT(pFunctionName) \
HX_SETUP_CHECKPOINTLIST( pFunctionName ) \
HX_LOG_CHECKPOINT( "Initial Function Checkpoint" )
#define HX_LOG_SINGLESHOT_CHECKPOINT( pFunctionName, pComment) \
{ \
static BOOL doneCheckPoint = FALSE; \
if( !doneCheckPoint ) \
{ \
HX_SETUP_CHECKPOINTLIST( pFunctionName ) \
HX_LOG_CHECKPOINT( pComment ) \
doneCheckPoint = TRUE; \
} \
}
#define HX_LOG_BLOCK( pBlockName ) \
HX_SETUP_CHECKPOINTLIST( "a" ); \
class CHXBlockLogger \
{ \
public: \
CHXBlockLogger( CHXCheckpointList* pCheckpointList ) \
: m_pCheckpointList( pCheckpointList ) \
{ \
m_pCheckpointList->AddCheckpoint( "Enter " pBlockName, __LINE__, HX_GET_BETTERTICKCOUNT()); \
} \
~CHXBlockLogger() \
{ \
m_pCheckpointList->AddCheckpoint( "Exit " pBlockName, __LINE__, HX_GET_BETTERTICKCOUNT()); \
} \
private: \
CHXCheckpointList* m_pCheckpointList; \
}; \
CHXBlockLogger blockLogger1278( &HXFunctionCheckpointList );
#define HX_LOG_START_SECTION( pSectionName ) \
HX_LOG_SINGLESHOT_CHECKPOINT( "", "--- Start section " pSectionName );
#define HX_LOG_END_SECTION( pSectionName ) \
HX_LOG_SINGLESHOT_CHECKPOINT( "", "--- End section " pSectionName );
#else /* ENABLE_CHECKPOINTS && ENABLE_CHECKPOINTS2 not Defined */
#define HX_ENABLE_CHECKPOINTS_FOR_MODULE(pModuleName, pOutputFileName)
#define HX_SETUP_CHECKPOINTLIST( pFunctionName )
#define HX_LOG_CHECKPOINT(pComment)
#define HX_PRIME_ACCUMULATOR(id, pComment)
#define HX_UPDATE_ACCUMULATOR(id)
#define HX_ACCUMULATE(id, pComment, data)
#define HX_LOG_INITIAL_CHECKPOINT(pFunctionName)
#define HX_LOG_SINGLESHOT_CHECKPOINT( pFunctionName, pComment)
#define HX_LOG_BLOCK( pBlockName )
#define HX_LOG_START_SECTION( pSectionName )
#define HX_LOG_END_SECTION( pSectionName )
#endif /* ENABLE_CHECKPOINTS */
#endif /* _HXCHKPT_H_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -