Source code of Windows XP (NT5)
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.

232 lines
5.1 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. tracelog.cxx
  5. Abstract:
  6. This module implements a trace log.
  7. A trace log is a fast, in-memory, thread safe activity log useful
  8. for debugging certain classes of problems. They are especially useful
  9. when debugging reference count bugs.
  10. Author:
  11. Keith Moore (keithmo) 10-Jun-1998
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #if REFERENCE_DEBUG
  16. //
  17. // Environmental stuff.
  18. //
  19. #define MY_ALLOC_MEM(cb) \
  20. (PVOID)UL_ALLOCATE_POOL( \
  21. NonPagedPool, \
  22. (ULONG)(cb), \
  23. UL_DEBUG_POOL_TAG \
  24. )
  25. #define MY_FREE_MEM(ptr) \
  26. UL_FREE_POOL( \
  27. (PVOID)(ptr), \
  28. UL_DEBUG_POOL_TAG \
  29. )
  30. #define MY_ASSERT(expr) ASSERT(expr)
  31. /***************************************************************************++
  32. Routine Description:
  33. Creates a new (empty) trace log buffer.
  34. Arguments:
  35. LogSize - Supplies the number of entries in the log.
  36. ExtraBytesInHeader - Supplies the number of extra bytes to include
  37. in the log header. This is useful for adding application-specific
  38. data to the log.
  39. EntrySize - Supplies the size (in bytes) of each entry.
  40. Return Value:
  41. PTRACE_LOG - Pointer to the newly created log if successful,
  42. NULL otherwise.
  43. --***************************************************************************/
  44. PTRACE_LOG
  45. CreateTraceLog(
  46. IN ULONG TypeSignature,
  47. IN ULONG LogSize,
  48. IN ULONG ExtraBytesInHeader,
  49. IN ULONG EntrySize
  50. )
  51. {
  52. ULONG totalSize;
  53. PTRACE_LOG pLog;
  54. //
  55. // Sanity check the parameters.
  56. //
  57. MY_ASSERT( LogSize > 0 );
  58. MY_ASSERT( EntrySize > 0 );
  59. MY_ASSERT( ( EntrySize & 3 ) == 0 );
  60. //
  61. // Allocate & initialize the log structure.
  62. //
  63. totalSize = sizeof(*pLog) + ( LogSize * EntrySize ) + ExtraBytesInHeader;
  64. MY_ASSERT( totalSize > 0 );
  65. pLog = (PTRACE_LOG)MY_ALLOC_MEM( totalSize );
  66. //
  67. // Initialize it.
  68. //
  69. if (pLog != NULL)
  70. {
  71. RtlZeroMemory( pLog, totalSize );
  72. pLog->Signature = TRACE_LOG_SIGNATURE;
  73. pLog->TypeSignature = TypeSignature;
  74. pLog->LogSize = LogSize;
  75. pLog->NextEntry = -1;
  76. pLog->EntrySize = EntrySize;
  77. pLog->pLogBuffer = (PUCHAR)( pLog + 1 ) + ExtraBytesInHeader;
  78. }
  79. return pLog;
  80. } // CreateTraceLog
  81. /***************************************************************************++
  82. Routine Description:
  83. Destroys a trace log buffer created with CreateTraceLog().
  84. Arguments:
  85. pLog - Supplies the trace log buffer to destroy.
  86. --***************************************************************************/
  87. VOID
  88. DestroyTraceLog(
  89. IN PTRACE_LOG pLog
  90. )
  91. {
  92. if (pLog != NULL)
  93. {
  94. MY_ASSERT( pLog->Signature == TRACE_LOG_SIGNATURE );
  95. pLog->Signature = TRACE_LOG_SIGNATURE_X;
  96. MY_FREE_MEM( pLog );
  97. }
  98. } // DestroyTraceLog
  99. /***************************************************************************++
  100. Routine Description:
  101. Writes a new entry to the specified trace log.
  102. Arguments:
  103. pLog - Supplies the log to write to.
  104. pEntry - Supplies a pointer to the data to write. This buffer is
  105. assumed to be pLog->EntrySize bytes long.
  106. Return Value:
  107. LONGLONG - Index of the newly written entry within the tracelog
  108. (used by the OwnerRef tracelog).
  109. --***************************************************************************/
  110. LONGLONG
  111. WriteTraceLog(
  112. IN PTRACE_LOG pLog,
  113. IN PVOID pEntry
  114. )
  115. {
  116. PUCHAR pTarget;
  117. ULONGLONG index = -1;
  118. if (pLog != NULL)
  119. {
  120. MY_ASSERT( pLog->Signature == TRACE_LOG_SIGNATURE );
  121. MY_ASSERT( pEntry != NULL );
  122. //
  123. // Find the next slot, copy the entry to the slot.
  124. //
  125. index = (ULONGLONG) UlInterlockedIncrement64( &pLog->NextEntry );
  126. pTarget = ( (index % pLog->LogSize) * pLog->EntrySize )
  127. + pLog->pLogBuffer;
  128. RtlCopyMemory( pTarget, pEntry, pLog->EntrySize );
  129. }
  130. return index;
  131. } // WriteTraceLog
  132. /***************************************************************************++
  133. Routine Description:
  134. Resets the specified trace log such that the next entry written
  135. will be placed at the beginning of the log.
  136. Arguments:
  137. pLog - Supplies the trace log to reset.
  138. --***************************************************************************/
  139. VOID
  140. ResetTraceLog(
  141. IN PTRACE_LOG pLog
  142. )
  143. {
  144. if (pLog != NULL)
  145. {
  146. MY_ASSERT( pLog->Signature == TRACE_LOG_SIGNATURE );
  147. RtlZeroMemory(
  148. ( pLog + 1 ),
  149. pLog->LogSize * pLog->EntrySize
  150. );
  151. pLog->NextEntry = -1;
  152. }
  153. } // ResetTraceLog
  154. #endif // REFERENCE_DEBUG