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.

391 lines
9.6 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. schedt.c
  5. Abstract:
  6. Psched Tracing support
  7. Author:
  8. Rajesh Sundaram (rajeshsu) 01-Aug-1998.
  9. Environment:
  10. Kernel Mode
  11. Revision History:
  12. --*/
  13. #include "psched.h"
  14. #pragma hdrstop
  15. //
  16. // Globals
  17. //
  18. NDIS_SPIN_LOCK GlobalLoggingLock;
  19. ULONG SchedTraceIndex;
  20. ULONG SchedBufferSize;
  21. ULONG SchedTraced;
  22. UCHAR *SchedTraceBuffer;
  23. ULONG SchedBufferStart;
  24. ULONG SchedTraceBytesUnread;
  25. ULONG SchedTraceThreshold;
  26. PVOID SchedTraceThreshContext;
  27. SCHEDTRACE_THRESH_PROC SchedTraceThreshProc;
  28. BOOLEAN TraceBufferAllocated;
  29. VOID
  30. SchedInitialize(
  31. ULONG BufferSize)
  32. {
  33. SchedBufferSize = BufferSize;
  34. TraceBufferAllocated = FALSE;
  35. PsAllocatePool(SchedTraceBuffer, SchedBufferSize, PsMiscTag);
  36. if(SchedTraceBuffer){
  37. TraceBufferAllocated = TRUE;
  38. NdisAllocateSpinLock(&GlobalLoggingLock);
  39. }
  40. else {
  41. TraceBufferAllocated = FALSE;
  42. }
  43. }
  44. VOID
  45. SchedDeInitialize(
  46. )
  47. {
  48. if(TraceBufferAllocated)
  49. {
  50. PsFreePool(SchedTraceBuffer);
  51. TraceBufferAllocated = FALSE;
  52. }
  53. NdisFreeSpinLock(&GlobalLoggingLock);
  54. }
  55. VOID
  56. DbugTraceSetThreshold(
  57. ULONG Threshold,
  58. PVOID Context,
  59. SCHEDTRACE_THRESH_PROC ThreshProc)
  60. {
  61. ULONG bytesToCopyAtEnd;
  62. ULONG bytesToCopyAtStart;
  63. NdisAcquireSpinLock(&GlobalLoggingLock);
  64. SchedTraceThreshProc = ThreshProc;
  65. SchedTraceThreshold = (Threshold <= SchedBufferSize) ? Threshold : SchedBufferSize;
  66. SchedTraceThreshContext = Context;
  67. if ((SchedTraceThreshContext != NULL) && (SchedTraceBytesUnread >= SchedTraceThreshold)) {
  68. SchedTraceThreshContext = NULL;
  69. NdisReleaseSpinLock(&GlobalLoggingLock);
  70. (*ThreshProc)(Context);
  71. }
  72. else {
  73. NdisReleaseSpinLock(&GlobalLoggingLock);
  74. }
  75. }
  76. VOID
  77. DbugReadTraceBuffer(
  78. PUCHAR Buffer,
  79. ULONG BytesToRead,
  80. PULONG BytesRead
  81. )
  82. {
  83. ULONG bytesToCopyAtEnd;
  84. ULONG bytesToCopyAtStart;
  85. ULONG bytesToCopy;
  86. ULONG startIndex;
  87. // Copy the most recently added bytes to the user buffer. If BytesToRead is less than
  88. // the number of unread bytes in the trace buffer, the older bytes are lost. This
  89. // ensures that the last record in the user buffer is complete (as long as the user
  90. // buffer is big enough to accommodate at least that one record).
  91. NdisAcquireSpinLock(&GlobalLoggingLock);
  92. bytesToCopy = (SchedTraceBytesUnread <= BytesToRead) ? SchedTraceBytesUnread : BytesToRead;
  93. startIndex = (bytesToCopy > SchedTraceIndex) ?
  94. SchedTraceIndex + SchedBufferSize - bytesToCopy :
  95. SchedTraceIndex - bytesToCopy;
  96. if ((startIndex + bytesToCopy) > SchedBufferSize) {
  97. bytesToCopyAtEnd = SchedBufferSize - startIndex;
  98. bytesToCopyAtStart = bytesToCopy - bytesToCopyAtEnd;
  99. RtlCopyMemory(Buffer, &SchedTraceBuffer[startIndex], bytesToCopyAtEnd);
  100. RtlCopyMemory(Buffer + bytesToCopyAtEnd, &SchedTraceBuffer[0], bytesToCopyAtStart);
  101. }
  102. else {
  103. bytesToCopyAtEnd = bytesToCopy;
  104. RtlCopyMemory(Buffer, &SchedTraceBuffer[startIndex], bytesToCopy);
  105. }
  106. SchedTraceBytesUnread = 0;
  107. *BytesRead = bytesToCopy;
  108. NdisReleaseSpinLock(&GlobalLoggingLock);
  109. }
  110. NTSTATUS
  111. WriteRecord(
  112. UCHAR * Record,
  113. ULONG Bytes
  114. )
  115. {
  116. ULONG bytesToCopyAtEnd;
  117. ULONG bytesToCopyAtStart;
  118. SCHEDTRACE_THRESH_PROC ThreshProc;
  119. PVOID Context;
  120. if(!TraceBufferAllocated){
  121. return(STATUS_UNSUCCESSFUL);
  122. }
  123. NdisAcquireSpinLock(&GlobalLoggingLock);
  124. if((SchedTraceIndex + Bytes) > SchedBufferSize){
  125. bytesToCopyAtEnd = SchedBufferSize - SchedTraceIndex;
  126. bytesToCopyAtStart = Bytes - bytesToCopyAtEnd;
  127. RtlCopyMemory(&SchedTraceBuffer[SchedTraceIndex], Record, bytesToCopyAtEnd);
  128. RtlCopyMemory(&SchedTraceBuffer[0], (UCHAR *)Record + bytesToCopyAtEnd, bytesToCopyAtStart);
  129. SchedTraceIndex = bytesToCopyAtStart;
  130. SchedTraced += Bytes;
  131. }
  132. else{
  133. bytesToCopyAtEnd = Bytes;
  134. RtlCopyMemory(&SchedTraceBuffer[SchedTraceIndex], Record, Bytes);
  135. SchedTraceIndex += Bytes;
  136. SchedTraced += Bytes;
  137. }
  138. SchedTraceBytesUnread += Bytes;
  139. if (SchedTraceBytesUnread > SchedBufferSize) {
  140. SchedTraceBytesUnread = SchedBufferSize;
  141. }
  142. if ((SchedTraceThreshContext != NULL) && (SchedTraceBytesUnread >= SchedTraceThreshold)) {
  143. ThreshProc = SchedTraceThreshProc;
  144. Context = SchedTraceThreshContext;
  145. SchedTraceThreshContext = NULL;
  146. NdisReleaseSpinLock(&GlobalLoggingLock);
  147. (*ThreshProc)(Context);
  148. }
  149. else {
  150. NdisReleaseSpinLock(&GlobalLoggingLock);
  151. }
  152. return(STATUS_SUCCESS);
  153. }
  154. #define ClearRecord(x, y) \
  155. RtlFillMemory(x, y, 0)
  156. VOID
  157. DbugSchedString(char *format, ...)
  158. {
  159. TRACE_RECORD_STRING record;
  160. CHAR buffer[TRACE_STRING_LENGTH];
  161. va_list va;
  162. va_start(va, format);
  163. _vsnprintf(buffer, TRACE_STRING_LENGTH-1, format, va);
  164. va_end(va);
  165. ClearRecord(&record, sizeof(TRACE_RECORD_STRING));
  166. record.Preamble = TRACE_PREAMBLE;
  167. record.RecordType = RECORD_TSTRING;
  168. PsGetCurrentTime(&record.Now);
  169. strncpy(record.StringStart, buffer, TRACE_STRING_LENGTH);
  170. WriteRecord((UCHAR *)&record, sizeof(TRACE_RECORD_STRING));
  171. return;
  172. }
  173. VOID
  174. DbugRecv(
  175. ULONG Event,
  176. ULONG Action,
  177. PVOID Adapter,
  178. PNDIS_PACKET Packet1,
  179. PNDIS_PACKET Packet2
  180. )
  181. {
  182. TRACE_RECORD_RECV record;
  183. ClearRecord(&record, sizeof(TRACE_RECORD_RECV));
  184. record.Preamble = TRACE_PREAMBLE;
  185. record.RecordType = RECORD_RECV;
  186. PsGetCurrentTime(&record.Now);
  187. record.Event = Event;
  188. record.Action = Action;
  189. record.Adapter = Adapter;
  190. record.Packet1 = Packet1;
  191. record.Packet2 = Packet2;
  192. WriteRecord((UCHAR *)&record, sizeof(TRACE_RECORD_RECV));
  193. }
  194. VOID
  195. DbugSend(
  196. ULONG Event,
  197. ULONG Action,
  198. PVOID Adapter,
  199. PVOID Vc,
  200. PNDIS_PACKET Packet1,
  201. PNDIS_PACKET Packet2
  202. )
  203. {
  204. TRACE_RECORD_SEND record;
  205. ClearRecord(&record, sizeof(TRACE_RECORD_SEND));
  206. record.Preamble = TRACE_PREAMBLE;
  207. record.RecordType = RECORD_SEND;
  208. PsGetCurrentTime(&record.Now);
  209. record.Event = Event;
  210. record.Action = Action;
  211. record.Adapter = Adapter;
  212. record.Vc = Vc;
  213. record.Packet1 = Packet1;
  214. record.Packet2 = Packet2;
  215. WriteRecord((UCHAR *)&record, sizeof(TRACE_RECORD_SEND));
  216. }
  217. VOID DbugOid(
  218. ULONG Action,
  219. ULONG Local,
  220. ULONG PTState,
  221. ULONG MPState,
  222. PVOID Adapter,
  223. ULONG Oid,
  224. ULONG Status
  225. )
  226. {
  227. TRACE_RECORD_OID record;
  228. ClearRecord(&record, sizeof(TRACE_RECORD_OID));
  229. record.Preamble = TRACE_PREAMBLE;
  230. record.RecordType = RECORD_OID;
  231. PsGetCurrentTime(&record.Now);
  232. record.Action = Action;
  233. record.Local = Local;
  234. record.Oid = Oid;
  235. record.PTState = PTState;
  236. record.MPState = MPState;
  237. record.Adapter = Adapter;
  238. record.Status = Status;
  239. WriteRecord((UCHAR *)&record, sizeof(TRACE_RECORD_OID));
  240. }
  241. VOID
  242. DbugSchedPkts(
  243. ULONG CallingFunction,
  244. PVOID VC,
  245. PNDIS_PACKET Packet,
  246. ULONG Action,
  247. ULONG PacketLength)
  248. {
  249. TRACE_RECORD_PKT record;
  250. ClearRecord(&record, sizeof(TRACE_RECORD_PKT));
  251. record.Preamble = TRACE_PREAMBLE;
  252. record.RecordType = RECORD_PKT;
  253. record.CallingFunction = CallingFunction;
  254. PsGetCurrentTime(&record.Now);
  255. record.VC = VC;
  256. record.Packet = Packet;
  257. record.Action = Action;
  258. record.PacketLength = PacketLength;
  259. WriteRecord((UCHAR *)&record, sizeof(TRACE_RECORD_PKT));
  260. }
  261. VOID
  262. DbugSched(
  263. ULONG SchedulerComponent,
  264. ULONG Action,
  265. PVOID VC,
  266. PNDIS_PACKET Packet,
  267. ULONG PacketLength,
  268. ULONG Priority,
  269. LONGLONG ArrivalTime,
  270. LONGLONG ConformanceTime,
  271. ULONG PacketsInComponent,
  272. ULONG BytesInComponent
  273. )
  274. {
  275. TRACE_RECORD_SCHED record;
  276. ClearRecord(&record, sizeof(TRACE_RECORD_SCHED));
  277. record.Preamble = TRACE_PREAMBLE;
  278. record.RecordType = RECORD_SCHED;
  279. record.SchedulerComponent = SchedulerComponent;
  280. PsGetCurrentTime(&record.Now);
  281. record.Action = Action;
  282. record.VC = VC;
  283. record.Packet = Packet;
  284. record.PacketLength = PacketLength;
  285. record.Priority = Priority;
  286. record.ArrivalTime = ArrivalTime,
  287. record.ConformanceTime = ConformanceTime;
  288. record.PacketsInComponent = PacketsInComponent;
  289. record.BytesInComponent = BytesInComponent;
  290. WriteRecord((UCHAR *)&record, sizeof(TRACE_RECORD_SCHED));
  291. }
  292. VOID
  293. DbugComponentSpecificRec(
  294. ULONG Component,
  295. PVOID Data,
  296. ULONG Length)
  297. {
  298. TRACE_RECORD_COMPONENT_SPECIFIC record;
  299. ClearRecord(&record, sizeof(TRACE_RECORD_COMPONENT_SPECIFIC));
  300. record.Preamble = TRACE_PREAMBLE;
  301. record.RecordType = RECORD_COMPONENT_SPECIFIC;
  302. record.SchedulerComponent = Component;
  303. PsGetCurrentTime(&record.Now);
  304. record.Length = (Length > MAX_RECORD_DATA) ? MAX_RECORD_DATA : Length;
  305. RtlCopyMemory(record.Data, Data, record.Length);
  306. WriteRecord((UCHAR *)&record, record.Length + FIELD_OFFSET(TRACE_RECORD_COMPONENT_SPECIFIC, Data));
  307. }
  308. ULONG
  309. SchedtGetBufferSize()
  310. {
  311. return SchedBufferSize;
  312. }
  313. ULONG
  314. SchedtGetBytesUnread()
  315. {
  316. return SchedTraceBytesUnread;
  317. }