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.

248 lines
5.8 KiB

  1. /*++
  2. Copyright (c) 1998-2002 Microsoft Corporation
  3. Module Name:
  4. tracelog.c
  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. static int g_TraceLogDummyDeclarationToKeepW4WarningsQuiet;
  17. #else // REFERENCE_DEBUG
  18. //
  19. // Environmental stuff.
  20. //
  21. #define MY_ASSERT(expr) ASSERT(expr)
  22. /***************************************************************************++
  23. Routine Description:
  24. Creates a new (empty) trace log buffer.
  25. Arguments:
  26. TypeSignature - Signature used by debugger extensions to match
  27. specialized tracelogs
  28. LogSize - Supplies the number of entries in the log.
  29. ExtraBytesInHeader - Supplies the number of extra bytes to include
  30. in the log header. This is useful for adding application-specific
  31. data to the log.
  32. EntrySize - Supplies the size (in bytes) of each entry.
  33. AllocationPriority - (currently ignored) If memory consumption is
  34. high, use AllocationPriority to determine if allocation succeeds
  35. PoolTag - Helps !poolused attribute different kinds of tracelogs
  36. Return Value:
  37. PTRACE_LOG - Pointer to the newly created log if successful,
  38. NULL otherwise.
  39. --***************************************************************************/
  40. PTRACE_LOG
  41. CreateTraceLog(
  42. IN ULONG TypeSignature,
  43. IN ULONG LogSize,
  44. IN ULONG ExtraBytesInHeader,
  45. IN ULONG EntrySize,
  46. IN TRACELOG_PRIORITY AllocationPriority,
  47. IN ULONG PoolTag
  48. )
  49. {
  50. ULONG totalSize;
  51. ULONG ExtraHeaderSize;
  52. PTRACE_LOG pLog;
  53. //
  54. // Sanity check the parameters.
  55. //
  56. MY_ASSERT( LogSize > 0 );
  57. MY_ASSERT( EntrySize > 0 );
  58. MY_ASSERT( ( EntrySize & 3 ) == 0 );
  59. //
  60. // Round up to platform allocation size to ensure that pLogBuffer
  61. // is correctly aligned
  62. //
  63. ExtraHeaderSize = (ExtraBytesInHeader + (MEMORY_ALLOCATION_ALIGNMENT-1))
  64. & ~(MEMORY_ALLOCATION_ALIGNMENT-1);
  65. //
  66. // Allocate & initialize the log structure.
  67. //
  68. totalSize = sizeof(*pLog) + ( LogSize * EntrySize ) + ExtraHeaderSize;
  69. MY_ASSERT( totalSize > 0 );
  70. //
  71. // CODEWORK: check AllocationPriority and memory consumption.
  72. // Fail allocation if memory too low and priority not high enough
  73. //
  74. pLog = (PTRACE_LOG) ExAllocatePoolWithTag(
  75. NonPagedPool,
  76. totalSize,
  77. PoolTag
  78. );
  79. //
  80. // Initialize it.
  81. //
  82. if (pLog != NULL)
  83. {
  84. RtlZeroMemory( pLog, totalSize );
  85. pLog->Signature = TRACE_LOG_SIGNATURE;
  86. pLog->TypeSignature = TypeSignature;
  87. pLog->LogSize = LogSize;
  88. pLog->NextEntry = -1;
  89. pLog->EntrySize = EntrySize;
  90. pLog->AllocationPriority = AllocationPriority;
  91. pLog->pLogBuffer = (PUCHAR)( pLog + 1 ) + ExtraBytesInHeader;
  92. }
  93. return pLog;
  94. } // CreateTraceLog
  95. /***************************************************************************++
  96. Routine Description:
  97. Destroys a trace log buffer created with CreateTraceLog().
  98. Arguments:
  99. pLog - Supplies the trace log buffer to destroy.
  100. --***************************************************************************/
  101. VOID
  102. DestroyTraceLog(
  103. IN PTRACE_LOG pLog,
  104. IN ULONG PoolTag
  105. )
  106. {
  107. if (pLog != NULL)
  108. {
  109. MY_ASSERT( pLog->Signature == TRACE_LOG_SIGNATURE );
  110. pLog->Signature = TRACE_LOG_SIGNATURE_X;
  111. ExFreePoolWithTag( pLog, PoolTag );
  112. }
  113. } // DestroyTraceLog
  114. /***************************************************************************++
  115. Routine Description:
  116. Writes a new entry to the specified trace log.
  117. Arguments:
  118. pLog - Supplies the log to write to.
  119. pEntry - Supplies a pointer to the data to write. This buffer is
  120. assumed to be pLog->EntrySize bytes long.
  121. Return Value:
  122. LONGLONG - Index of the newly written entry within the tracelog.
  123. --***************************************************************************/
  124. LONGLONG
  125. WriteTraceLog(
  126. IN PTRACE_LOG pLog,
  127. IN PVOID pEntry
  128. )
  129. {
  130. PUCHAR pTarget;
  131. ULONGLONG index = (ULONGLONG) -1;
  132. if (pLog != NULL)
  133. {
  134. MY_ASSERT( pLog->Signature == TRACE_LOG_SIGNATURE );
  135. MY_ASSERT( pEntry != NULL );
  136. //
  137. // Find the next slot, copy the entry to the slot.
  138. //
  139. index = (ULONGLONG) UlInterlockedIncrement64( &pLog->NextEntry );
  140. pTarget = ( (index % pLog->LogSize) * pLog->EntrySize )
  141. + pLog->pLogBuffer;
  142. RtlCopyMemory( pTarget, pEntry, pLog->EntrySize );
  143. }
  144. return index;
  145. } // WriteTraceLog
  146. /***************************************************************************++
  147. Routine Description:
  148. Resets the specified trace log such that the next entry written
  149. will be placed at the beginning of the log.
  150. Arguments:
  151. pLog - Supplies the trace log to reset.
  152. --***************************************************************************/
  153. VOID
  154. ResetTraceLog(
  155. IN PTRACE_LOG pLog
  156. )
  157. {
  158. if (pLog != NULL)
  159. {
  160. MY_ASSERT( pLog->Signature == TRACE_LOG_SIGNATURE );
  161. RtlZeroMemory(pLog->pLogBuffer, pLog->LogSize * pLog->EntrySize);
  162. pLog->NextEntry = -1;
  163. }
  164. } // ResetTraceLog
  165. #endif // REFERENCE_DEBUG