Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

768 lines
21 KiB

  1. #ifndef _TRACER_H_
  2. #define _TRACER_H_
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <windows.h>
  6. #include <stdarg.h>
  7. //
  8. // global defines.
  9. //
  10. #define MAX_FLAG_NAME 32
  11. #define MAX_TAG_NAME 64
  12. #define DEVICE_FLAG 0
  13. #define ERROR_LEVEL_FLAG 1
  14. #define ASSERT_LEVEL_FLAG 2
  15. #define PRINT_LOCATION 3
  16. #define PRINT_PROGRAM_NAME 4
  17. #define PRINT_TIME 5
  18. #define PRINT_THREAD_ID 6
  19. #define PRINT_ERROR_LEVEL 7
  20. #define PRINT_TAG_ID 8
  21. #define PRINT_TAG_NAME 9
  22. #define PRINT_PROCESS_ID 10
  23. #define LAST_FLAG 11
  24. #define TRACER_DEVICE_FLAG_FILE 0x00000001L
  25. #define TRACER_DEVICE_FLAG_DEBUGOUT 0x00000002L
  26. #define TRACER_DEVICE_FLAG_STDOUT 0x00000004L
  27. #define TRACER_DEVICE_FLAG_STDERR 0x00000008L
  28. //
  29. // basic classes
  30. //
  31. typedef enum _ERROR_LEVEL
  32. {
  33. elFirst = 0,
  34. elCrash,
  35. elError,
  36. elWarning,
  37. elInfo,
  38. elVerbose,
  39. elLast
  40. } ERROR_LEVEL;
  41. typedef ULONG TAG;
  42. ///////////////////////////////////////////////////////////////////////////////
  43. // CTracerTagEntry
  44. ///////////////////////////////////////////////////////////////////////////////
  45. class CTracerTagEntry
  46. {
  47. public:
  48. CTracerTagEntry() :
  49. m_TagErrLevel(elFirst)
  50. {
  51. m_pszTagName[0] = '\0';
  52. }
  53. public:
  54. ERROR_LEVEL m_TagErrLevel;
  55. char m_pszTagName[MAX_TAG_NAME];
  56. };
  57. ///////////////////////////////////////////////////////////////////////////////
  58. // CTracerFlagEntry
  59. ///////////////////////////////////////////////////////////////////////////////
  60. class CTracerFlagEntry
  61. {
  62. public:
  63. CTracerFlagEntry() :
  64. m_ulFlagValue(0)
  65. {
  66. m_pszName[0] = '\0';
  67. }
  68. public:
  69. ULONG m_ulFlagValue;
  70. char m_pszName[MAX_FLAG_NAME];
  71. };
  72. ///////////////////////////////////////////////////////////////////////////////
  73. // CTracer
  74. ///////////////////////////////////////////////////////////////////////////////
  75. typedef enum {
  76. logUseLogName,
  77. logUseAppName
  78. } LogState;
  79. class CTracer
  80. {
  81. public:
  82. // The virtual distructor is here to allow derived classes to
  83. // define distructors
  84. virtual ~CTracer();
  85. // This function deallocates the tracer! it calls the Function pointer
  86. // passed in the constructor or if not given - the default
  87. // delete operator for the dll.
  88. virtual void Free();
  89. // The TraceSZ function output is defined by the tags and error level mode.
  90. // The control of this mode is via the registry.
  91. // (Default LOCAL_MACHINE\SOFTWARE\Microsoft\Tracer)
  92. // TraceSZ gets the mode by calling IsEnabled.
  93. //-------------------------------------------------------------------------
  94. // accepts printf format for traces
  95. virtual void
  96. TraceSZ(DWORD, LPCSTR, int, ERROR_LEVEL, TAG, LPCSTR, ...);
  97. virtual void
  98. TraceSZ(DWORD, LPCSTR, int, ERROR_LEVEL, TAG, PCWSTR, ...);
  99. // Prints the implements the TraceSZ function.
  100. virtual void
  101. VaTraceSZ(DWORD, LPCSTR, int, ERROR_LEVEL, TAG, LPCSTR, va_list);
  102. virtual void
  103. VaTraceSZ(DWORD, LPCSTR, int, ERROR_LEVEL, TAG, PCWSTR, va_list);
  104. // Raw output functions
  105. virtual void
  106. RawVaTraceSZ(LPCSTR, va_list);
  107. virtual void
  108. RawVaTraceSZ(PCWSTR, va_list);
  109. // Create or open a new tag for tracing
  110. virtual HRESULT RegisterTagSZ(LPCSTR, TAG&);
  111. // Two Assert functions one allows attaching a string.
  112. //-------------------------------------------------------------------------
  113. // assert, different implementations possible - gui or text
  114. virtual void TraceAssertSZ(LPCSTR, LPCSTR, LPCSTR, int);
  115. // assert, different implementations possible - gui or text
  116. virtual void TraceAssert(LPCSTR, LPCSTR, int);
  117. // The following function are used to check return values and validity of
  118. // pointers and handles. If the item checked is bad the function will
  119. // return TRUE and a trace will be made for that.
  120. //-------------------------------------------------------------------------
  121. // Verify a boolean function return code
  122. virtual BOOL IsFailure(BOOL, LPCSTR, int);
  123. // verify allocation
  124. virtual BOOL IsBadAlloc(void*, LPCSTR, int);
  125. // Verify a Handle
  126. virtual BOOL IsBadHandle(HANDLE, LPCSTR, int);
  127. // Verify an OLE hresult function
  128. virtual BOOL IsBadResult(HRESULT, LPCSTR, int);
  129. public:
  130. TAG* m_ptagNextTagId;
  131. // A array of tags.
  132. CTracerTagEntry* m_aTags;
  133. // Contains the flags that control wich output devices are used.
  134. ULONG* m_pulNumOfFlagEntries;
  135. CTracerFlagEntry* m_aFlags;
  136. // log file
  137. LogState m_LogState;
  138. char* m_pszLogName;
  139. };
  140. extern "C" CTracer* g_pTracer;
  141. class CSetLogFile
  142. {
  143. public:
  144. CSetLogFile()
  145. {
  146. g_pTracer->m_LogState = logUseAppName;
  147. }
  148. CSetLogFile(char* pszName)
  149. {
  150. g_pTracer->m_LogState = logUseLogName;
  151. g_pTracer->m_pszLogName = pszName;
  152. }
  153. };
  154. ///////////////////////////////////////////////////////////////////////////////
  155. // CTempTrace
  156. ///////////////////////////////////////////////////////////////////////////////
  157. class CTempTrace
  158. {
  159. public:
  160. CTempTrace(LPCSTR pszFile, int iLine);
  161. void TraceSZ(ERROR_LEVEL, ULONG, LPCSTR, ...);
  162. void TraceSZ(ERROR_LEVEL, ULONG, DWORD dwError, LPCSTR, ...);
  163. void TraceSZ(ERROR_LEVEL, ULONG, PCWSTR, ...);
  164. void TraceSZ(ERROR_LEVEL, ULONG, DWORD dwError, PCWSTR, ...);
  165. private:
  166. LPCSTR m_pszFile;
  167. int m_iLine;
  168. };
  169. ///////////////////////////////////////////////////////////////////////////////
  170. // CTempTrace1
  171. ///////////////////////////////////////////////////////////////////////////////
  172. class CTempTrace1
  173. {
  174. public:
  175. CTempTrace1(LPCSTR pszFile, int iLine, TAG tag, ERROR_LEVEL el);
  176. void TraceSZ(LPCSTR, ...);
  177. void TraceSZ(DWORD dwError, LPCSTR, ...);
  178. void TraceSZ(PCWSTR, ...);
  179. void TraceSZ(DWORD dwError, PCWSTR, ...);
  180. private:
  181. LPCSTR m_pszFile;
  182. int m_iLine;
  183. TAG m_ulTag;
  184. ERROR_LEVEL m_el;
  185. };
  186. ///////////////////////////////////////////////////////////////////////////////
  187. // CLongTrace
  188. ///////////////////////////////////////////////////////////////////////////////
  189. class CLongTrace
  190. {
  191. public:
  192. CLongTrace(LPCSTR pszFile, int iLine);
  193. ~CLongTrace();
  194. BOOL Init(ERROR_LEVEL, TAG);
  195. private:
  196. BOOL m_fRelease;
  197. LPCSTR m_pszFile;
  198. int m_iLine;
  199. };
  200. ///////////////////////////////////////////////////////////////////////////////
  201. // CLongTraceOutput
  202. ///////////////////////////////////////////////////////////////////////////////
  203. class CLongTraceOutput
  204. {
  205. public:
  206. CLongTraceOutput(LPCSTR pszFile, int iLine);
  207. void TraceSZ(LPCSTR, ...);
  208. void TraceSZ(PCWSTR, ...);
  209. private:
  210. LPCSTR m_pszFile;
  211. int m_iLine;
  212. };
  213. ///////////////////////////////////////////////////////////////////////////////
  214. // CTracerTag
  215. ///////////////////////////////////////////////////////////////////////////////
  216. class CTracerTag
  217. {
  218. #if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
  219. public:
  220. CTracerTag(PSZ pszTagName)
  221. {
  222. HRESULT hrTagRegistrationResult;
  223. hrTagRegistrationResult = g_pTracer->RegisterTagSZ(pszTagName, m_ulTag);
  224. if(FAILED(hrTagRegistrationResult))
  225. throw "Tag could not be registered";
  226. }
  227. operator TAG()
  228. {
  229. return m_ulTag;
  230. }
  231. public:
  232. TAG m_ulTag;
  233. #else /* DEBUG */
  234. public:
  235. CTracerTag(PSZ){}
  236. #endif /* DEBUG */
  237. };
  238. extern CTracerTag tagError;
  239. extern CTracerTag tagWarning;
  240. extern CTracerTag tagInformation;
  241. extern CTracerTag tagVerbose;
  242. extern CTracerTag tagGeneral;
  243. //
  244. // global defines
  245. //
  246. #define BAD_POINTER(ptr) (NULL == (ptr))
  247. #define BAD_HANDLE(h) ((0 == ((HANDLE)h))|| \
  248. (INVALID_HANDLE_VALUE == ((HANDLE)h)))
  249. #define BAD_RESULT(hr) (FAILED(hr))
  250. #if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
  251. #ifdef __cplusplus
  252. #define CheckTraceRestrictions(el, tag) \
  253. ((g_pTracer->m_aTags[tag].m_TagErrLevel >= el) && \
  254. (g_pTracer->m_aFlags[ERROR_LEVEL_FLAG].m_ulFlagValue >= (ULONG)el) && \
  255. g_pTracer->m_aFlags[DEVICE_FLAG].m_ulFlagValue)
  256. #define Trace(x) \
  257. {CTempTrace tmp(__FILE__, __LINE__);tmp.TraceSZ x;}
  258. #define Trace1(el, tag, x) \
  259. { \
  260. if (CheckTraceRestrictions(el, tag.m_ulTag)) \
  261. { \
  262. CTempTrace1 tmp(__FILE__, __LINE__, tag.m_ulTag, el); \
  263. tmp.TraceSZ x; \
  264. } \
  265. }
  266. #define BeginLongTrace(x) {CLongTrace tmp(__FILE__, __LINE__);if (tmp.Init x) {
  267. #define LongTrace(x) {CLongTraceOutput tmp(__FILE__, __LINE__);tmp.TraceSZ x;}
  268. #define EndLongTrace }}
  269. #define RegisterTag(psz, tag) g_pTracer->RegisterTagSZ((psz), tag)
  270. #define IS_FAILURE(x) g_pTracer->IsFailure((x), __FILE__, __LINE__)
  271. #define IS_BAD_ALLOC(x) g_pTracer->IsBadAlloc((void*)(x), __FILE__, __LINE__)
  272. #define IS_BAD_HANDLE(x) g_pTracer->IsBadHandle((HANDLE)(x), __FILE__, __LINE__)
  273. #define IS_BAD_RESULT(x) g_pTracer->IsBadResult((x), __FILE__, __LINE__)
  274. #define Assert(x) {if (!(x)) {g_pTracer->TraceAssert(#x, __FILE__, __LINE__);}}
  275. #define AssertSZ(x, psz) {if (!(x)) {g_pTracer->TraceAssertSZ(#x, (PSZ)(psz),__FILE__, __LINE__);}}
  276. #define SET_TRACER(x) SetTracer(x)
  277. #define SET_TRACER_LOGGING_TO_FILE_OFF g_pTracer->m_aFlags[DEVICE_FLAG].m_ulFlagValue &= ~TRACER_DEVICE_FLAG_FILE;
  278. #define USE_COMMON_LOG_FILE(name) CSetLogFile SetLogFile(name);
  279. #else /* __cplusplus */
  280. #define IS_FAILURE(x) IsFailure((x), __FILE__, __LINE__)
  281. #define IS_BAD_ALLOC(x) IsBadAlloc((void*)(x), __FILE__, __LINE__)
  282. #define IS_BAD_HANDLE(x) IsBadHandle((HANDLE)(x), __FILE__, __LINE__)
  283. #define IS_BAD_RESULT(x) IsBadResult((x), __FILE__, __LINE__)
  284. #define Assert(x) {if (!(x)) {TraceAssert(#x,__FILE__, __LINE__);}}
  285. #ifdef UNICODE
  286. #define AssertSZ(x, psz) {if (!(x)) {TraceAssertWSZ(#x, (pwsz), __FILE__, __LINE__);}}
  287. #define Trace(x) TraceWSZ x
  288. #else
  289. #define AssertSZ(x, psz) {if (!(x)) {TraceAssertSZ(#x, (psz),__FILE__, __LINE__);}}
  290. #define Trace(x) TraceSZ x
  291. #endif
  292. #define RegisterTag(psz, tag) RegisterTagSZ((psz), &(tag))
  293. #endif /* __cplusplus */
  294. #define GIS_FAILURE(x) IsFailure((x), __FILE__, __LINE__)
  295. #define GIS_BAD_ALLOC(x) IsBadAlloc((void*)(x), __FILE__, __LINE__)
  296. #define GIS_BAD_HANDLE(x) IsBadHandle((HANDLE)(x), __FILE__, __LINE__)
  297. #define GIS_BAD_RESULT(x) IsBadResult((x), __FILE__, __LINE__)
  298. #define GAssert(x) {if (!(x)) {TraceAssert(#x, __FILE__, __LINE__);}}
  299. #define GAssertSZ(x, psz) {if (!(x)) {TraceAssertSZ(#x, (PSZ)(psz), __FILE__, __LINE__);}}
  300. #define GTrace(x) TraceSZ x
  301. #define DECLARE_TAG(name, psz) static CTracerTag name(psz);
  302. #define DECLARE_GLOBAL_TAG(name, psz) CTracerTag name(psz);
  303. #define USES_TAG(name) extern CTracerTag name;
  304. #else // DEBUG
  305. #define IS_FAILURE(x) (!(x))
  306. #define IS_BAD_ALLOC(x) BAD_POINTER((void*)(x))
  307. #define IS_BAD_HANDLE(x) BAD_HANDLE((HANDLE)(x))
  308. #define IS_BAD_RESULT(x) BAD_RESULT(x)
  309. #define Assert(x)
  310. #define AssertSZ(x, psz)
  311. #define Trace(x)
  312. #define Trace1(el,tag,x)
  313. #define BeginLongTrace(x) {if (0) {
  314. #define LongTrace(x) ;
  315. #define EndLongTrace }}
  316. #define RegisterTag(psz, tag)
  317. #define SET_TRACER(x)
  318. #define SET_TRACER_LOGGING_TO_FILE_OFF
  319. #define USE_COMMON_LOG_FILE(name)
  320. #define GIS_FAILURE(x) IS_FAILURE(x)
  321. #define GIS_BAD_ALLOC(x) IS_BAD_ALLOC(x)
  322. #define GIS_BAD_HANDLE(x) IS_BAD_HANDLE(x)
  323. #define GIS_BAD_RESULT(x) IS_BAD_RESULT(x)
  324. #define GAssert(x) Assert(x)
  325. #define GAssertSZ(x, psz) AssertSZ(x, psz)
  326. #define GTrace(x)
  327. #define DECLARE_TAG(name, psz)
  328. #define DECLARE_GLOBAL_TAG(name, psz)
  329. #define USES_TAG(name)
  330. #endif // DEBUG
  331. //
  332. // Turn off Asserts for retail, even if USE_TRACER is specified
  333. //
  334. #if (!defined(DEBUG))
  335. #ifdef Assert
  336. #undef Assert
  337. #define Assert(x)
  338. #endif // Assert
  339. #ifdef AssertSZ
  340. #undef AssertSZ
  341. #define AssertSZ(x, psz)
  342. #endif // AssertSZ
  343. #ifdef GAssert
  344. #undef GAssert
  345. #define GAssert(x)
  346. #endif // GAssert
  347. #ifdef GAssertSZ
  348. #undef GAssertSZ
  349. #define GAssertSZ(x, psz)
  350. #endif // GAssertSZ
  351. #endif // DEBUG
  352. #ifndef PQS_CODE
  353. #undef _ASSERTE
  354. #if (defined (DEBUG) && !defined(_NO_TRACER))
  355. #define _ASSERTE(x) Assert(x)
  356. #else
  357. #define _ASSERTE(x) 0
  358. #endif
  359. #endif // PQS_CODE
  360. ////////////////////////////////////////////////////////////////////////////////
  361. //
  362. // Define this to export the classes
  363. //
  364. ////////////////////////////////////////////////////////////////////////////////
  365. #ifdef TRACER_EXPORT
  366. #define TracerExported __declspec( dllexport )
  367. #else
  368. #define TracerExported
  369. #endif
  370. ////////////////////////////////////////////////////////////////////////////////
  371. //
  372. // class CTraced definition + implementation
  373. //
  374. // pupose : A base class for every class who wants to use a special.
  375. //
  376. //
  377. ////////////////////////////////////////////////////////////////////////////////
  378. #if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
  379. void __cdecl ShutdownTracer();
  380. class TracerExported CTraced {
  381. public:
  382. // A Constructor - sets a default Tracer. replace it by calling SetTracer
  383. // in the derived class constructor.
  384. CTraced()
  385. {
  386. m_pTracer = NULL;
  387. }
  388. // The destructor deletes the existing tracer.
  389. ~CTraced()
  390. {
  391. if (m_pTracer)
  392. m_pTracer->Free();
  393. }
  394. // replace the current tracer while erasing it.
  395. BOOL SetTracer(CTracer* pTracer)
  396. {
  397. CTracer* pTempTracer = m_pTracer;
  398. m_pTracer = pTracer;
  399. if (pTempTracer)
  400. pTempTracer->Free();
  401. return TRUE;
  402. }
  403. // Return a pointer to the tracer this function is called by the macro's so
  404. // if one wants to supply a different mechanism he can override it.
  405. virtual CTracer* GetTracer()
  406. {
  407. if(m_pTracer)
  408. return m_pTracer;
  409. else
  410. return g_pTracer;
  411. }
  412. protected:
  413. // A pointer to the tracer.
  414. CTracer *m_pTracer;
  415. };
  416. #else /* DEBUG */
  417. class TracerExported CTraced {};
  418. #endif /* DEBUG */
  419. ////////////////////////////////////////////////////////////////////////////////
  420. //
  421. // The C interface prototypes. The macros calls them.
  422. //
  423. ////////////////////////////////////////////////////////////////////////////////
  424. #ifdef __cplusplus
  425. extern "C"
  426. {
  427. #endif /* __cplusplus */
  428. void TraceAssert( PSZ, PSZ, int);
  429. void TraceAssertSZ( PSZ, PSZ, PSZ, int);
  430. void TraceAssertWSZ(PSZ, PWSTR, PSZ, int);
  431. BOOL IsFailure (BOOL , PSZ, int);
  432. BOOL IsBadAlloc (void* , PSZ, int);
  433. BOOL IsBadHandle(HANDLE , PSZ, int);
  434. BOOL IsBadResult(HRESULT, PSZ, int);
  435. void TraceSZ(ERROR_LEVEL, TAG, PSZ, ...);
  436. void TraceWSZ(ERROR_LEVEL, TAG, PWSTR, ...);
  437. HRESULT RegisterTagSZ(PSZ, TAG*);
  438. #ifdef __cplusplus
  439. }
  440. #endif /* __cplusplus */
  441. #ifdef __cplusplus
  442. ////////////////////////////////////////////////////////////////////////////////
  443. //
  444. // Some extra classes.
  445. //
  446. ////////////////////////////////////////////////////////////////////////////////
  447. ////////////////////////////////////////////////////////////////////////////////
  448. //
  449. // An accumulating timer. Use it to define accuulator.
  450. // (See cpptest.cpp in the Sample)
  451. //
  452. // It is be used to compute average times of function etc.
  453. //
  454. // timer - the vaiable name
  455. // tag - the tag to trace to
  456. // string - a prefix
  457. //
  458. ////////////////////////////////////////////////////////////////////////////////
  459. #if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
  460. #define AccumulatingTimer(timer, tag, string, actimer) \
  461. CTracerAccumulatingTimer timer(tag, string, actimer)
  462. #else
  463. #define AccumulatingTimer(timer, tag, string, actimer)
  464. #endif
  465. #if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
  466. class CTracerAccumulatingTimer
  467. {
  468. public:
  469. CTracerAccumulatingTimer(
  470. TAG tag,
  471. PSZ pszSomeText = NULL,
  472. CTracerAccumulatingTimer *pTimer = NULL)
  473. :m_ulAccumulatedTimeInMiliseconds(0)
  474. ,m_ulEventNumber(0)
  475. ,m_tagTheTagToTraceTo(tag)
  476. ,m_pAccumulator(pTimer)
  477. {
  478. if (pszSomeText)
  479. strncpy(m_rchText, pszSomeText, MAX_PATH);
  480. else
  481. m_rchText[0] = '\0';
  482. }
  483. operator TAG(){return m_tagTheTagToTraceTo;}
  484. void AddEvent(ULONG ulEventDurationInMiliseconds, PSZ pszSomeText)
  485. {
  486. m_ulAccumulatedTimeInMiliseconds += ulEventDurationInMiliseconds;
  487. m_ulEventNumber++;
  488. Trace((
  489. elInfo,
  490. m_tagTheTagToTraceTo,
  491. "%s%s took %d miliseconds,"
  492. " average is %d miliseconds,"
  493. " accumulated %d miliseconds,"
  494. " op# %d",
  495. m_rchText,
  496. pszSomeText,
  497. ulEventDurationInMiliseconds,
  498. m_ulAccumulatedTimeInMiliseconds/m_ulEventNumber,
  499. m_ulAccumulatedTimeInMiliseconds,
  500. m_ulEventNumber));
  501. if(m_pAccumulator)
  502. m_pAccumulator->AddEvent(
  503. ulEventDurationInMiliseconds,
  504. m_rchText);
  505. }
  506. protected:
  507. // The time
  508. ULONG m_ulAccumulatedTimeInMiliseconds;
  509. // The event counter
  510. ULONG m_ulEventNumber;
  511. // The tag the trace will use.
  512. TAG m_tagTheTagToTraceTo;
  513. // some text to specify which scope or code block is it
  514. char m_rchText[MAX_PATH + 1];
  515. // pointer to accumulating time
  516. CTracerAccumulatingTimer *m_pAccumulator;
  517. };
  518. #endif
  519. ////////////////////////////////////////////////////////////////////////////////
  520. //
  521. // A scope timer. It will trace the time that passed from the instanciation
  522. // to the end of the scope.
  523. // (See cpptest.cpp in the Sample)
  524. //
  525. // It is be used to compute times of function etc.
  526. //
  527. // tag - the tag to trace to
  528. // string - a prefix
  529. //
  530. ////////////////////////////////////////////////////////////////////////////////
  531. #if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
  532. #define ScopeTimer(tag, string) CTracerScopeTimer __scopetimer(tag, string)
  533. #else
  534. #define ScopeTimer(tag, string)
  535. #endif
  536. ////////////////////////////////////////////////////////////////////////////////
  537. //
  538. // A scope timer that uses and updates an accumulator timer.
  539. // It will trace the time that passed from the instanciation
  540. // to the end of the scope and tell this time to the accumulator as well.
  541. // (See cpptest.cpp in the Sample)
  542. //
  543. // tag - the tag to trace to
  544. // string - a prefix
  545. // actimer - an AccumulatingTimer object.
  546. //
  547. // comment - if both the scope timer and the accumulating timer has the
  548. // same tags - the scope timer will not trace.
  549. //
  550. ////////////////////////////////////////////////////////////////////////////////
  551. #if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
  552. #define ScopeAccumulatingTimer(tag, string, actimer) \
  553. CTracerScopeTimer __scopetimer(tag, string, actimer)
  554. #else
  555. #define ScopeAccumulatingTimer(tag, string, actimer)
  556. #endif
  557. #if (defined (DEBUG) && !defined(_NO_TRACER)) || defined(USE_TRACER)
  558. class CTracerScopeTimer
  559. {
  560. public:
  561. CTracerScopeTimer(
  562. TAG tag,
  563. PSZ pszSomeText = NULL,
  564. CTracerAccumulatingTimer *pTimer = NULL)
  565. :m_ulStartTimeInMiliseconds(GetTickCount())
  566. ,m_tagTheTagToTraceTo(tag)
  567. ,m_pAccumulator(pTimer)
  568. {
  569. if (pszSomeText)
  570. strncpy(m_rchText, pszSomeText, MAX_PATH);
  571. else
  572. m_rchText[0] = '\0';
  573. }
  574. ~CTracerScopeTimer()
  575. {
  576. ULONG ulFinishTimeInMiliseconds = GetTickCount();
  577. ULONG ulStartToFinishTimeInMiliseconds;
  578. if (ulFinishTimeInMiliseconds >
  579. m_ulStartTimeInMiliseconds)
  580. ulStartToFinishTimeInMiliseconds =
  581. ulFinishTimeInMiliseconds - m_ulStartTimeInMiliseconds;
  582. else
  583. ulStartToFinishTimeInMiliseconds =
  584. ulFinishTimeInMiliseconds + 1 +
  585. (0xffffffff - m_ulStartTimeInMiliseconds);
  586. if(!m_pAccumulator ||
  587. (m_tagTheTagToTraceTo != (ULONG)(*m_pAccumulator)))
  588. Trace((
  589. elInfo,
  590. m_tagTheTagToTraceTo,
  591. "%s took %d miliseconds",
  592. m_rchText,
  593. ulStartToFinishTimeInMiliseconds));
  594. if(m_pAccumulator)
  595. m_pAccumulator->AddEvent(
  596. ulStartToFinishTimeInMiliseconds,
  597. m_rchText);
  598. }
  599. protected:
  600. // The counter
  601. ULONG m_ulStartTimeInMiliseconds;
  602. // The tag the trace will use.
  603. TAG m_tagTheTagToTraceTo;
  604. // some text to specify which scope or code block is it
  605. char m_rchText[MAX_PATH + 1];
  606. // pointer to accumulating time
  607. CTracerAccumulatingTimer *m_pAccumulator;
  608. };
  609. #endif
  610. #endif /* __cplusplus */
  611. #endif // _TRACER_H_