769 lines
20 KiB
C++
769 lines
20 KiB
C++
#ifndef _TRACER_H_
|
|
#define _TRACER_H_
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <stdarg.h>
|
|
|
|
//
|
|
// global defines.
|
|
//
|
|
|
|
#define MAX_FLAG_NAME 32
|
|
#define MAX_TAG_NAME 64
|
|
|
|
#define DEVICE_FLAG 0
|
|
#define ERROR_LEVEL_FLAG 1
|
|
#define ASSERT_LEVEL_FLAG 2
|
|
#define PRINT_LOCATION 3
|
|
#define PRINT_PROGRAM_NAME 4
|
|
#define PRINT_TIME 5
|
|
#define PRINT_THREAD_ID 6
|
|
#define PRINT_ERROR_LEVEL 7
|
|
#define PRINT_TAG_ID 8
|
|
#define PRINT_TAG_NAME 9
|
|
#define PRINT_PROCESS_ID 10
|
|
#define LAST_FLAG 11
|
|
|
|
#define TRACER_DEVICE_FLAG_FILE 0x00000001L
|
|
#define TRACER_DEVICE_FLAG_DEBUGOUT 0x00000002L
|
|
#define TRACER_DEVICE_FLAG_STDOUT 0x00000004L
|
|
#define TRACER_DEVICE_FLAG_STDERR 0x00000008L
|
|
|
|
//
|
|
// basic classes
|
|
//
|
|
|
|
typedef enum _ERROR_LEVEL
|
|
{
|
|
elFirst = 0,
|
|
elCrash,
|
|
elError,
|
|
elWarning,
|
|
elInfo,
|
|
elVerbose,
|
|
elLast
|
|
} ERROR_LEVEL;
|
|
|
|
typedef ULONG TAG;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CTracerTagEntry
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
class CTracerTagEntry
|
|
{
|
|
public:
|
|
CTracerTagEntry() :
|
|
m_TagErrLevel(elFirst)
|
|
{
|
|
m_pszTagName[0] = '\0';
|
|
}
|
|
|
|
public:
|
|
ERROR_LEVEL m_TagErrLevel;
|
|
char m_pszTagName[MAX_TAG_NAME];
|
|
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CTracerFlagEntry
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CTracerFlagEntry
|
|
{
|
|
public:
|
|
CTracerFlagEntry() :
|
|
m_ulFlagValue(0)
|
|
{
|
|
m_pszName[0] = '\0';
|
|
}
|
|
|
|
public:
|
|
ULONG m_ulFlagValue;
|
|
char m_pszName[MAX_FLAG_NAME];
|
|
};
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CTracer
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
typedef enum {
|
|
logUseLogName,
|
|
logUseAppName
|
|
} LogState;
|
|
|
|
class CTracer
|
|
{
|
|
public:
|
|
|
|
// The virtual distructor is here to allow derived classes to
|
|
// define distructors
|
|
virtual ~CTracer();
|
|
|
|
// This function deallocates the tracer! it calls the Function pointer
|
|
// passed in the constructor or if not given - the default
|
|
// delete operator for the dll.
|
|
virtual void Free();
|
|
|
|
|
|
// The TraceSZ function output is defined by the tags and error level mode.
|
|
// The control of this mode is via the registry.
|
|
// (Default LOCAL_MACHINE\SOFTWARE\Microsoft\Tracer)
|
|
// TraceSZ gets the mode by calling IsEnabled.
|
|
//-------------------------------------------------------------------------
|
|
// accepts printf format for traces
|
|
virtual void
|
|
TraceSZ(DWORD, LPCSTR, int, ERROR_LEVEL, TAG, LPCSTR, ...);
|
|
virtual void
|
|
TraceSZ(DWORD, LPCSTR, int, ERROR_LEVEL, TAG, PCWSTR, ...);
|
|
|
|
// Prints the implements the TraceSZ function.
|
|
virtual void
|
|
VaTraceSZ(DWORD, LPCSTR, int, ERROR_LEVEL, TAG, LPCSTR, va_list);
|
|
virtual void
|
|
VaTraceSZ(DWORD, LPCSTR, int, ERROR_LEVEL, TAG, PCWSTR, va_list);
|
|
|
|
// Raw output functions
|
|
virtual void
|
|
RawVaTraceSZ(LPCSTR, va_list);
|
|
virtual void
|
|
RawVaTraceSZ(PCWSTR, va_list);
|
|
|
|
// Create or open a new tag for tracing
|
|
virtual HRESULT RegisterTagSZ(LPCSTR, TAG&);
|
|
|
|
// Two Assert functions one allows attaching a string.
|
|
//-------------------------------------------------------------------------
|
|
// assert, different implementations possible - gui or text
|
|
virtual void TraceAssertSZ(LPCSTR, LPCSTR, LPCSTR, int);
|
|
|
|
// assert, different implementations possible - gui or text
|
|
virtual void TraceAssert(LPCSTR, LPCSTR, int);
|
|
|
|
// The following function are used to check return values and validity of
|
|
// pointers and handles. If the item checked is bad the function will
|
|
// return TRUE and a trace will be made for that.
|
|
//-------------------------------------------------------------------------
|
|
// Verify a boolean function return code
|
|
virtual BOOL IsFailure(BOOL, LPCSTR, int);
|
|
|
|
// verify allocation
|
|
virtual BOOL IsBadAlloc(void*, LPCSTR, int);
|
|
|
|
// Verify a Handle
|
|
virtual BOOL IsBadHandle(HANDLE, LPCSTR, int);
|
|
|
|
// Verify an OLE hresult function
|
|
virtual BOOL IsBadResult(HRESULT, LPCSTR, int);
|
|
|
|
public:
|
|
|
|
TAG* m_ptagNextTagId;
|
|
// A array of tags.
|
|
CTracerTagEntry* m_aTags;
|
|
|
|
// Contains the flags that control wich output devices are used.
|
|
|
|
ULONG* m_pulNumOfFlagEntries;
|
|
CTracerFlagEntry* m_aFlags;
|
|
|
|
// log file
|
|
|
|
LogState m_LogState;
|
|
char* m_pszLogName;
|
|
};
|
|
|
|
extern "C" CTracer* g_pTracer;
|
|
|
|
class CSetLogFile
|
|
{
|
|
public:
|
|
CSetLogFile()
|
|
{
|
|
g_pTracer->m_LogState = logUseAppName;
|
|
}
|
|
|
|
CSetLogFile(char* pszName)
|
|
{
|
|
g_pTracer->m_LogState = logUseLogName;
|
|
g_pTracer->m_pszLogName = pszName;
|
|
}
|
|
|
|
};
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CTempTrace
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CTempTrace
|
|
{
|
|
public:
|
|
CTempTrace(LPCSTR pszFile, int iLine);
|
|
|
|
void TraceSZ(ERROR_LEVEL, ULONG, LPCSTR, ...);
|
|
void TraceSZ(ERROR_LEVEL, ULONG, DWORD dwError, LPCSTR, ...);
|
|
|
|
void TraceSZ(ERROR_LEVEL, ULONG, PCWSTR, ...);
|
|
void TraceSZ(ERROR_LEVEL, ULONG, DWORD dwError, PCWSTR, ...);
|
|
|
|
private:
|
|
|
|
LPCSTR m_pszFile;
|
|
int m_iLine;
|
|
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CTempTrace1
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CTempTrace1
|
|
{
|
|
public:
|
|
CTempTrace1(LPCSTR pszFile, int iLine, TAG tag, ERROR_LEVEL el);
|
|
|
|
void TraceSZ(LPCSTR, ...);
|
|
void TraceSZ(DWORD dwError, LPCSTR, ...);
|
|
|
|
void TraceSZ(PCWSTR, ...);
|
|
void TraceSZ(DWORD dwError, PCWSTR, ...);
|
|
|
|
private:
|
|
|
|
LPCSTR m_pszFile;
|
|
int m_iLine;
|
|
TAG m_ulTag;
|
|
ERROR_LEVEL m_el;
|
|
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CLongTrace
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CLongTrace
|
|
{
|
|
public:
|
|
CLongTrace(LPCSTR pszFile, int iLine);
|
|
~CLongTrace();
|
|
BOOL Init(ERROR_LEVEL, TAG);
|
|
|
|
private:
|
|
BOOL m_fRelease;
|
|
LPCSTR m_pszFile;
|
|
int m_iLine;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CLongTraceOutput
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CLongTraceOutput
|
|
{
|
|
public:
|
|
CLongTraceOutput(LPCSTR pszFile, int iLine);
|
|
|
|
void TraceSZ(LPCSTR, ...);
|
|
void TraceSZ(PCWSTR, ...);
|
|
|
|
private:
|
|
LPCSTR m_pszFile;
|
|
int m_iLine;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// CTracerTag
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
class CTracerTag
|
|
{
|
|
#if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
|
|
public:
|
|
|
|
CTracerTag(PSZ pszTagName)
|
|
{
|
|
HRESULT hrTagRegistrationResult;
|
|
|
|
hrTagRegistrationResult = g_pTracer->RegisterTagSZ(pszTagName, m_ulTag);
|
|
|
|
if(FAILED(hrTagRegistrationResult))
|
|
throw "Tag could not be registered";
|
|
|
|
}
|
|
|
|
operator TAG()
|
|
{
|
|
return m_ulTag;
|
|
}
|
|
|
|
public:
|
|
TAG m_ulTag;
|
|
#else /* DEBUG */
|
|
public:
|
|
CTracerTag(PSZ){}
|
|
#endif /* DEBUG */
|
|
};
|
|
|
|
|
|
extern CTracerTag tagError;
|
|
extern CTracerTag tagWarning;
|
|
extern CTracerTag tagInformation;
|
|
extern CTracerTag tagVerbose;
|
|
extern CTracerTag tagGeneral;
|
|
//
|
|
// global defines
|
|
//
|
|
|
|
#define BAD_POINTER(ptr) (NULL == (ptr))
|
|
#define BAD_HANDLE(h) ((0 == ((HANDLE)h))|| \
|
|
(INVALID_HANDLE_VALUE == ((HANDLE)h)))
|
|
#define BAD_RESULT(hr) (FAILED(hr))
|
|
|
|
#if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
|
|
|
|
#ifdef __cplusplus
|
|
|
|
#define CheckTraceRestrictions(el, tag) \
|
|
((g_pTracer->m_aTags[tag].m_TagErrLevel >= el) && \
|
|
(g_pTracer->m_aFlags[ERROR_LEVEL_FLAG].m_ulFlagValue >= (ULONG)el) && \
|
|
g_pTracer->m_aFlags[DEVICE_FLAG].m_ulFlagValue)
|
|
|
|
#define Trace(x) \
|
|
{CTempTrace tmp(__FILE__, __LINE__);tmp.TraceSZ x;}
|
|
|
|
#define Trace1(el, tag, x) \
|
|
{ \
|
|
if (CheckTraceRestrictions(el, tag.m_ulTag)) \
|
|
{ \
|
|
CTempTrace1 tmp(__FILE__, __LINE__, tag.m_ulTag, el); \
|
|
tmp.TraceSZ x; \
|
|
} \
|
|
}
|
|
|
|
#define BeginLongTrace(x) {CLongTrace tmp(__FILE__, __LINE__);if (tmp.Init x) {
|
|
#define LongTrace(x) {CLongTraceOutput tmp(__FILE__, __LINE__);tmp.TraceSZ x;}
|
|
#define EndLongTrace }}
|
|
|
|
#define RegisterTag(psz, tag) g_pTracer->RegisterTagSZ((psz), tag)
|
|
|
|
#define IS_FAILURE(x) g_pTracer->IsFailure((x), __FILE__, __LINE__)
|
|
#define IS_BAD_ALLOC(x) g_pTracer->IsBadAlloc((void*)(x), __FILE__, __LINE__)
|
|
#define IS_BAD_HANDLE(x) g_pTracer->IsBadHandle((HANDLE)(x), __FILE__, __LINE__)
|
|
#define IS_BAD_RESULT(x) g_pTracer->IsBadResult((x), __FILE__, __LINE__)
|
|
|
|
#define Assert(x) {if (!(x)) {g_pTracer->TraceAssert(#x, __FILE__, __LINE__);}}
|
|
#define AssertSZ(x, psz) {if (!(x)) {g_pTracer->TraceAssertSZ(#x, (PSZ)(psz),__FILE__, __LINE__);}}
|
|
|
|
#define SET_TRACER(x) SetTracer(x)
|
|
|
|
#define SET_TRACER_LOGGING_TO_FILE_OFF g_pTracer->m_aFlags[DEVICE_FLAG].m_ulFlagValue &= ~TRACER_DEVICE_FLAG_FILE;
|
|
#define USE_COMMON_LOG_FILE(name) CSetLogFile SetLogFile(name);
|
|
|
|
#else /* __cplusplus */
|
|
|
|
#define IS_FAILURE(x) IsFailure((x), __FILE__, __LINE__)
|
|
#define IS_BAD_ALLOC(x) IsBadAlloc((void*)(x), __FILE__, __LINE__)
|
|
#define IS_BAD_HANDLE(x) IsBadHandle((HANDLE)(x), __FILE__, __LINE__)
|
|
#define IS_BAD_RESULT(x) IsBadResult((x), __FILE__, __LINE__)
|
|
|
|
#define Assert(x) {if (!(x)) {TraceAssert(#x,__FILE__, __LINE__);}}
|
|
|
|
#ifdef UNICODE
|
|
#define AssertSZ(x, psz) {if (!(x)) {TraceAssertWSZ(#x, (pwsz), __FILE__, __LINE__);}}
|
|
#define Trace(x) TraceWSZ x
|
|
#else
|
|
#define AssertSZ(x, psz) {if (!(x)) {TraceAssertSZ(#x, (psz),__FILE__, __LINE__);}}
|
|
#define Trace(x) TraceSZ x
|
|
#endif
|
|
|
|
#define RegisterTag(psz, tag) RegisterTagSZ((psz), &(tag))
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
#define GIS_FAILURE(x) IsFailure((x), __FILE__, __LINE__)
|
|
#define GIS_BAD_ALLOC(x) IsBadAlloc((void*)(x), __FILE__, __LINE__)
|
|
#define GIS_BAD_HANDLE(x) IsBadHandle((HANDLE)(x), __FILE__, __LINE__)
|
|
#define GIS_BAD_RESULT(x) IsBadResult((x), __FILE__, __LINE__)
|
|
|
|
#define GAssert(x) {if (!(x)) {TraceAssert(#x, __FILE__, __LINE__);}}
|
|
#define GAssertSZ(x, psz) {if (!(x)) {TraceAssertSZ(#x, (PSZ)(psz), __FILE__, __LINE__);}}
|
|
|
|
#define GTrace(x) TraceSZ x
|
|
|
|
#define DECLARE_TAG(name, psz) static CTracerTag name(psz);
|
|
#define DECLARE_GLOBAL_TAG(name, psz) CTracerTag name(psz);
|
|
#define USES_TAG(name) extern CTracerTag name;
|
|
|
|
#else // DEBUG
|
|
|
|
#define IS_FAILURE(x) (!(x))
|
|
#define IS_BAD_ALLOC(x) BAD_POINTER((void*)(x))
|
|
#define IS_BAD_HANDLE(x) BAD_HANDLE((HANDLE)(x))
|
|
#define IS_BAD_RESULT(x) BAD_RESULT(x)
|
|
|
|
#define Assert(x)
|
|
#define AssertSZ(x, psz)
|
|
|
|
#define Trace(x)
|
|
#define Trace1(el,tag,x)
|
|
|
|
#define BeginLongTrace(x) {if (0) {
|
|
#define LongTrace(x) ;
|
|
#define EndLongTrace }}
|
|
|
|
#define RegisterTag(psz, tag)
|
|
|
|
#define SET_TRACER(x)
|
|
#define SET_TRACER_LOGGING_TO_FILE_OFF
|
|
#define USE_COMMON_LOG_FILE(name)
|
|
|
|
#define GIS_FAILURE(x) IS_FAILURE(x)
|
|
#define GIS_BAD_ALLOC(x) IS_BAD_ALLOC(x)
|
|
#define GIS_BAD_HANDLE(x) IS_BAD_HANDLE(x)
|
|
#define GIS_BAD_RESULT(x) IS_BAD_RESULT(x)
|
|
|
|
#define GAssert(x) Assert(x)
|
|
#define GAssertSZ(x, psz) AssertSZ(x, psz)
|
|
|
|
#define GTrace(x)
|
|
|
|
#define DECLARE_TAG(name, psz)
|
|
#define DECLARE_GLOBAL_TAG(name, psz)
|
|
#define USES_TAG(name)
|
|
|
|
#endif // DEBUG
|
|
|
|
//
|
|
// Turn off Asserts for retail, even if USE_TRACER is specified
|
|
//
|
|
#if (!defined(DEBUG))
|
|
|
|
#ifdef Assert
|
|
#undef Assert
|
|
#define Assert(x)
|
|
#endif // Assert
|
|
|
|
#ifdef AssertSZ
|
|
#undef AssertSZ
|
|
#define AssertSZ(x, psz)
|
|
#endif // AssertSZ
|
|
|
|
#ifdef GAssert
|
|
#undef GAssert
|
|
#define GAssert(x)
|
|
#endif // GAssert
|
|
|
|
#ifdef GAssertSZ
|
|
#undef GAssertSZ
|
|
#define GAssertSZ(x, psz)
|
|
#endif // GAssertSZ
|
|
|
|
#endif // DEBUG
|
|
|
|
#ifndef PQS_CODE
|
|
#undef _ASSERTE
|
|
|
|
#if (defined (DEBUG) && !defined(_NO_TRACER))
|
|
#define _ASSERTE(x) Assert(x)
|
|
#else
|
|
#define _ASSERTE(x) 0
|
|
#endif
|
|
|
|
#endif // PQS_CODE
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Define this to export the classes
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#ifdef TRACER_EXPORT
|
|
#define TracerExported __declspec( dllexport )
|
|
#else
|
|
#define TracerExported
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// class CTraced definition + implementation
|
|
//
|
|
// pupose : A base class for every class who wants to use a special.
|
|
//
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
|
|
|
|
void __cdecl ShutdownTracer();
|
|
|
|
class TracerExported CTraced {
|
|
public:
|
|
// A Constructor - sets a default Tracer. replace it by calling SetTracer
|
|
// in the derived class constructor.
|
|
CTraced()
|
|
{
|
|
m_pTracer = NULL;
|
|
}
|
|
|
|
// The destructor deletes the existing tracer.
|
|
~CTraced()
|
|
{
|
|
if (m_pTracer)
|
|
m_pTracer->Free();
|
|
}
|
|
|
|
// replace the current tracer while erasing it.
|
|
BOOL SetTracer(CTracer* pTracer)
|
|
{
|
|
CTracer* pTempTracer = m_pTracer;
|
|
m_pTracer = pTracer;
|
|
|
|
if (pTempTracer)
|
|
pTempTracer->Free();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
// Return a pointer to the tracer this function is called by the macro's so
|
|
// if one wants to supply a different mechanism he can override it.
|
|
virtual CTracer* GetTracer()
|
|
{
|
|
if(m_pTracer)
|
|
return m_pTracer;
|
|
else
|
|
return g_pTracer;
|
|
}
|
|
|
|
protected:
|
|
// A pointer to the tracer.
|
|
CTracer *m_pTracer;
|
|
};
|
|
|
|
#else /* DEBUG */
|
|
class TracerExported CTraced {};
|
|
#endif /* DEBUG */
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// The C interface prototypes. The macros calls them.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif /* __cplusplus */
|
|
|
|
void TraceAssert( PSZ, PSZ, int);
|
|
void TraceAssertSZ( PSZ, PSZ, PSZ, int);
|
|
void TraceAssertWSZ(PSZ, PWSTR, PSZ, int);
|
|
|
|
BOOL IsFailure (BOOL , PSZ, int);
|
|
BOOL IsBadAlloc (void* , PSZ, int);
|
|
BOOL IsBadHandle(HANDLE , PSZ, int);
|
|
BOOL IsBadResult(HRESULT, PSZ, int);
|
|
|
|
void TraceSZ(ERROR_LEVEL, TAG, PSZ, ...);
|
|
void TraceWSZ(ERROR_LEVEL, TAG, PWSTR, ...);
|
|
|
|
HRESULT RegisterTagSZ(PSZ, TAG*);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
|
|
#ifdef __cplusplus
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Some extra classes.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// An accumulating timer. Use it to define accuulator.
|
|
// (See cpptest.cpp in the Sample)
|
|
//
|
|
// It is be used to compute average times of function etc.
|
|
//
|
|
// timer - the vaiable name
|
|
// tag - the tag to trace to
|
|
// string - a prefix
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
|
|
#define AccumulatingTimer(timer, tag, string, actimer) \
|
|
CTracerAccumulatingTimer timer(tag, string, actimer)
|
|
#else
|
|
#define AccumulatingTimer(timer, tag, string, actimer)
|
|
#endif
|
|
|
|
#if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
|
|
class CTracerAccumulatingTimer
|
|
{
|
|
public:
|
|
CTracerAccumulatingTimer(
|
|
TAG tag,
|
|
PSZ pszSomeText = NULL,
|
|
CTracerAccumulatingTimer *pTimer = NULL)
|
|
:m_ulAccumulatedTimeInMiliseconds(0)
|
|
,m_ulEventNumber(0)
|
|
,m_tagTheTagToTraceTo(tag)
|
|
,m_pAccumulator(pTimer)
|
|
{
|
|
if (pszSomeText)
|
|
strncpy(m_rchText, pszSomeText, MAX_PATH);
|
|
else
|
|
m_rchText[0] = '\0';
|
|
}
|
|
|
|
operator TAG(){return m_tagTheTagToTraceTo;}
|
|
|
|
void AddEvent(ULONG ulEventDurationInMiliseconds, PSZ pszSomeText)
|
|
{
|
|
m_ulAccumulatedTimeInMiliseconds += ulEventDurationInMiliseconds;
|
|
m_ulEventNumber++;
|
|
|
|
Trace((
|
|
elInfo,
|
|
m_tagTheTagToTraceTo,
|
|
"%s%s took %d miliseconds,"
|
|
" average is %d miliseconds,"
|
|
" accumulated %d miliseconds,"
|
|
" op# %d",
|
|
m_rchText,
|
|
pszSomeText,
|
|
ulEventDurationInMiliseconds,
|
|
m_ulAccumulatedTimeInMiliseconds/m_ulEventNumber,
|
|
m_ulAccumulatedTimeInMiliseconds,
|
|
m_ulEventNumber));
|
|
|
|
if(m_pAccumulator)
|
|
m_pAccumulator->AddEvent(
|
|
ulEventDurationInMiliseconds,
|
|
m_rchText);
|
|
}
|
|
|
|
protected:
|
|
// The time
|
|
ULONG m_ulAccumulatedTimeInMiliseconds;
|
|
|
|
// The event counter
|
|
ULONG m_ulEventNumber;
|
|
|
|
// The tag the trace will use.
|
|
TAG m_tagTheTagToTraceTo;
|
|
|
|
// some text to specify which scope or code block is it
|
|
char m_rchText[MAX_PATH + 1];
|
|
|
|
// pointer to accumulating time
|
|
CTracerAccumulatingTimer *m_pAccumulator;
|
|
};
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// A scope timer. It will trace the time that passed from the instanciation
|
|
// to the end of the scope.
|
|
// (See cpptest.cpp in the Sample)
|
|
//
|
|
// It is be used to compute times of function etc.
|
|
//
|
|
// tag - the tag to trace to
|
|
// string - a prefix
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
|
|
#define ScopeTimer(tag, string) CTracerScopeTimer __scopetimer(tag, string)
|
|
#else
|
|
#define ScopeTimer(tag, string)
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// A scope timer that uses and updates an accumulator timer.
|
|
// It will trace the time that passed from the instanciation
|
|
// to the end of the scope and tell this time to the accumulator as well.
|
|
// (See cpptest.cpp in the Sample)
|
|
//
|
|
// tag - the tag to trace to
|
|
// string - a prefix
|
|
// actimer - an AccumulatingTimer object.
|
|
//
|
|
// comment - if both the scope timer and the accumulating timer has the
|
|
// same tags - the scope timer will not trace.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
|
|
#define ScopeAccumulatingTimer(tag, string, actimer) \
|
|
CTracerScopeTimer __scopetimer(tag, string, actimer)
|
|
#else
|
|
#define ScopeAccumulatingTimer(tag, string, actimer)
|
|
#endif
|
|
|
|
#if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
|
|
class CTracerScopeTimer
|
|
{
|
|
public:
|
|
CTracerScopeTimer(
|
|
TAG tag,
|
|
PSZ pszSomeText = NULL,
|
|
CTracerAccumulatingTimer *pTimer = NULL)
|
|
:m_ulStartTimeInMiliseconds(GetTickCount())
|
|
,m_tagTheTagToTraceTo(tag)
|
|
,m_pAccumulator(pTimer)
|
|
{
|
|
if (pszSomeText)
|
|
strncpy(m_rchText, pszSomeText, MAX_PATH);
|
|
else
|
|
m_rchText[0] = '\0';
|
|
}
|
|
|
|
|
|
~CTracerScopeTimer()
|
|
{
|
|
ULONG ulFinishTimeInMiliseconds = GetTickCount();
|
|
ULONG ulStartToFinishTimeInMiliseconds;
|
|
|
|
if (ulFinishTimeInMiliseconds >
|
|
m_ulStartTimeInMiliseconds)
|
|
ulStartToFinishTimeInMiliseconds =
|
|
ulFinishTimeInMiliseconds - m_ulStartTimeInMiliseconds;
|
|
else
|
|
ulStartToFinishTimeInMiliseconds =
|
|
ulFinishTimeInMiliseconds + 1 +
|
|
(0xffffffff - m_ulStartTimeInMiliseconds);
|
|
|
|
if(!m_pAccumulator ||
|
|
(m_tagTheTagToTraceTo != (ULONG)(*m_pAccumulator)))
|
|
Trace((
|
|
elInfo,
|
|
m_tagTheTagToTraceTo,
|
|
"%s took %d miliseconds",
|
|
m_rchText,
|
|
ulStartToFinishTimeInMiliseconds));
|
|
|
|
if(m_pAccumulator)
|
|
m_pAccumulator->AddEvent(
|
|
ulStartToFinishTimeInMiliseconds,
|
|
m_rchText);
|
|
}
|
|
|
|
protected:
|
|
// The counter
|
|
ULONG m_ulStartTimeInMiliseconds;
|
|
|
|
// The tag the trace will use.
|
|
TAG m_tagTheTagToTraceTo;
|
|
|
|
// some text to specify which scope or code block is it
|
|
char m_rchText[MAX_PATH + 1];
|
|
|
|
// pointer to accumulating time
|
|
CTracerAccumulatingTimer *m_pAccumulator;
|
|
};
|
|
#endif
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
|
|
#endif // _TRACER_H_
|