1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
6 // ResourcesEtwProvider.cs
9 // Managed event source for things that can version with MSCORLIB.
13 using System.Collections.Generic;
14 using System.Globalization;
15 using System.Reflection;
17 using System.Runtime.CompilerServices;
19 namespace System.Diagnostics.Tracing
21 // To use the framework provider
23 // \\clrmain\tools\Perfmonitor /nokernel /noclr /provider:8E9F5090-2D75-4d03-8A81-E5AFBF85DAF1 start
25 // \\clrmain\tools\Perfmonitor stop
26 // \\clrmain\tools\Perfmonitor print
28 // This will produce an XML file, where each event is pretty-printed with all its arguments nicely parsed.
30 // [FriendAccessAllowed]
31 [EventSource(Guid = "8E9F5090-2D75-4d03-8A81-E5AFBF85DAF1", Name = "System.Diagnostics.Eventing.FrameworkEventSource")]
32 sealed internal class FrameworkEventSource : EventSource
34 // Defines the singleton instance for the Resources ETW provider
35 public static readonly FrameworkEventSource Log = new FrameworkEventSource();
37 // Keyword definitions. These represent logical groups of events that can be turned on and off independently
38 // Often each task has a keyword, but where tasks are determined by subsystem, keywords are determined by
39 // usefulness to end users to filter. Generally users don't mind extra events if they are not high volume
40 // so grouping low volume events together in a single keywords is OK (users can post-filter by task if desired)
41 public static class Keywords
43 public const EventKeywords Loader = (EventKeywords)0x0001; // This is bit 0
44 public const EventKeywords ThreadPool = (EventKeywords)0x0002;
45 public const EventKeywords NetClient = (EventKeywords)0x0004;
47 // This is a private event we do not want to expose to customers. It is to be used for profiling
48 // uses of dynamic type loading by ProjectN applications running on the desktop CLR
50 public const EventKeywords DynamicTypeUsage = (EventKeywords)0x0008;
51 public const EventKeywords ThreadTransfer = (EventKeywords)0x0010;
54 /// <summary>ETW tasks that have start/stop events.</summary>
55 public static class Tasks // this name is important for EventSource
57 /// <summary>Begin / End - GetResponse.</summary>
58 public const EventTask GetResponse = (EventTask)1;
59 /// <summary>Begin / End - GetRequestStream</summary>
60 public const EventTask GetRequestStream = (EventTask)2;
61 /// <summary>Send / Receive - begin transfer/end transfer</summary>
62 public const EventTask ThreadTransfer = (EventTask)3;
65 public static class Opcodes
67 public const EventOpcode ReceiveHandled = (EventOpcode)11;
70 // This predicate is used by consumers of this class to deteremine if the class has actually been initialized,
71 // and therefore if the public statics are available for use. This is typically not a problem... if the static
72 // class constructor fails, then attempts to access the statics (or even this property) will result in a
73 // TypeInitializationException. However, that is not the case while the class loader is actually trying to construct
74 // the TypeInitializationException instance to represent that failure, and some consumers of this class are on
75 // that code path, specifically the resource manager.
76 public static bool IsInitialized
84 // The FrameworkEventSource GUID is {8E9F5090-2D75-4d03-8A81-E5AFBF85DAF1}
85 private FrameworkEventSource() : base(new Guid(0x8e9f5090, 0x2d75, 0x4d03, 0x8a, 0x81, 0xe5, 0xaf, 0xbf, 0x85, 0xda, 0xf1), "System.Diagnostics.Eventing.FrameworkEventSource") { }
87 // WriteEvent overloads (to avoid the "params" EventSource.WriteEvent
89 // optimized for common signatures (used by the ThreadTransferSend/Receive events)
92 [System.Security.SecuritySafeCritical]
94 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
95 private unsafe void WriteEvent(int eventId, long arg1, int arg2, string arg3, bool arg4)
99 if (arg3 == null) arg3 = "";
100 fixed (char* string3Bytes = arg3)
102 EventSource.EventData* descrs = stackalloc EventSource.EventData[4];
103 descrs[0].DataPointer = (IntPtr)(&arg1);
105 descrs[1].DataPointer = (IntPtr)(&arg2);
107 descrs[2].DataPointer = (IntPtr)string3Bytes;
108 descrs[2].Size = ((arg3.Length + 1) * 2);
109 descrs[3].DataPointer = (IntPtr)(&arg4);
111 WriteEventCore(eventId, 4, descrs);
116 // optimized for common signatures (used by the ThreadTransferSend/Receive events)
119 [System.Security.SecuritySafeCritical]
121 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
122 private unsafe void WriteEvent(int eventId, long arg1, int arg2, string arg3)
126 if (arg3 == null) arg3 = "";
127 fixed (char* string3Bytes = arg3)
129 EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
130 descrs[0].DataPointer = (IntPtr)(&arg1);
132 descrs[1].DataPointer = (IntPtr)(&arg2);
134 descrs[2].DataPointer = (IntPtr)string3Bytes;
135 descrs[2].Size = ((arg3.Length + 1) * 2);
136 WriteEventCore(eventId, 3, descrs);
141 // optimized for common signatures (used by the BeginGetResponse/BeginGetRequestStream events)
144 [System.Security.SecuritySafeCritical]
146 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
147 private unsafe void WriteEvent(int eventId, long arg1, string arg2, bool arg3, bool arg4)
151 if (arg2 == null) arg2 = "";
152 fixed (char* string2Bytes = arg2)
154 EventSource.EventData* descrs = stackalloc EventSource.EventData[4];
155 descrs[0].DataPointer = (IntPtr)(&arg1);
157 descrs[1].DataPointer = (IntPtr)string2Bytes;
158 descrs[1].Size = ((arg2.Length + 1) * 2);
159 descrs[2].DataPointer = (IntPtr)(&arg3);
161 descrs[3].DataPointer = (IntPtr)(&arg4);
163 WriteEventCore(eventId, 4, descrs);
168 // optimized for common signatures (used by the EndGetRequestStream event)
171 [System.Security.SecuritySafeCritical]
173 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
174 private unsafe void WriteEvent(int eventId, long arg1, bool arg2, bool arg3)
178 EventSource.EventData* descrs = stackalloc EventSource.EventData[3];
179 descrs[0].DataPointer = (IntPtr)(&arg1);
181 descrs[1].DataPointer = (IntPtr)(&arg2);
183 descrs[2].DataPointer = (IntPtr)(&arg3);
185 WriteEventCore(eventId, 3, descrs);
189 // optimized for common signatures (used by the EndGetResponse event)
192 [System.Security.SecuritySafeCritical]
194 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Concurrency", "CA8001", Justification = "This does not need to be correct when racing with other threads")]
195 private unsafe void WriteEvent(int eventId, long arg1, bool arg2, bool arg3, int arg4)
199 EventSource.EventData* descrs = stackalloc EventSource.EventData[4];
200 descrs[0].DataPointer = (IntPtr)(&arg1);
202 descrs[1].DataPointer = (IntPtr)(&arg2);
204 descrs[2].DataPointer = (IntPtr)(&arg3);
206 descrs[3].DataPointer = (IntPtr)(&arg4);
208 WriteEventCore(eventId, 4, descrs);
212 // ResourceManager Event Definitions
214 [Event(1, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
215 public void ResourceManagerLookupStarted(String baseName, String mainAssemblyName, String cultureName)
217 WriteEvent(1, baseName, mainAssemblyName, cultureName);
220 [Event(2, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
221 public void ResourceManagerLookingForResourceSet(String baseName, String mainAssemblyName, String cultureName)
224 WriteEvent(2, baseName, mainAssemblyName, cultureName);
227 [Event(3, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
228 public void ResourceManagerFoundResourceSetInCache(String baseName, String mainAssemblyName, String cultureName)
231 WriteEvent(3, baseName, mainAssemblyName, cultureName);
234 // After loading a satellite assembly, we already have the ResourceSet for this culture in
235 // the cache. This can happen if you have an assembly load callback that called into this
236 // instance of the ResourceManager.
237 [Event(4, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
238 public void ResourceManagerFoundResourceSetInCacheUnexpected(String baseName, String mainAssemblyName, String cultureName)
241 WriteEvent(4, baseName, mainAssemblyName, cultureName);
244 // manifest resource stream lookup succeeded
245 [Event(5, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
246 public void ResourceManagerStreamFound(String baseName, String mainAssemblyName, String cultureName, String loadedAssemblyName, String resourceFileName)
249 WriteEvent(5, baseName, mainAssemblyName, cultureName, loadedAssemblyName, resourceFileName);
252 // manifest resource stream lookup failed
253 [Event(6, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
254 public void ResourceManagerStreamNotFound(String baseName, String mainAssemblyName, String cultureName, String loadedAssemblyName, String resourceFileName)
257 WriteEvent(6, baseName, mainAssemblyName, cultureName, loadedAssemblyName, resourceFileName);
260 [Event(7, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
261 public void ResourceManagerGetSatelliteAssemblySucceeded(String baseName, String mainAssemblyName, String cultureName, String assemblyName)
264 WriteEvent(7, baseName, mainAssemblyName, cultureName, assemblyName);
267 [Event(8, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
268 public void ResourceManagerGetSatelliteAssemblyFailed(String baseName, String mainAssemblyName, String cultureName, String assemblyName)
271 WriteEvent(8, baseName, mainAssemblyName, cultureName, assemblyName);
274 [Event(9, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
275 public void ResourceManagerCaseInsensitiveResourceStreamLookupSucceeded(String baseName, String mainAssemblyName, String assemblyName, String resourceFileName)
278 WriteEvent(9, baseName, mainAssemblyName, assemblyName, resourceFileName);
281 [Event(10, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
282 public void ResourceManagerCaseInsensitiveResourceStreamLookupFailed(String baseName, String mainAssemblyName, String assemblyName, String resourceFileName)
285 WriteEvent(10, baseName, mainAssemblyName, assemblyName, resourceFileName);
288 // Could not access the manifest resource the assembly
289 [Event(11, Level = EventLevel.Error, Keywords = Keywords.Loader)]
290 public void ResourceManagerManifestResourceAccessDenied(String baseName, String mainAssemblyName, String assemblyName, String canonicalName)
293 WriteEvent(11, baseName, mainAssemblyName, assemblyName, canonicalName);
296 // Neutral resources are sufficient for this culture. Skipping satellites
297 [Event(12, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
298 public void ResourceManagerNeutralResourcesSufficient(String baseName, String mainAssemblyName, String cultureName)
301 WriteEvent(12, baseName, mainAssemblyName, cultureName);
304 [Event(13, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
305 public void ResourceManagerNeutralResourceAttributeMissing(String mainAssemblyName)
308 WriteEvent(13, mainAssemblyName);
311 [Event(14, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
312 public void ResourceManagerCreatingResourceSet(String baseName, String mainAssemblyName, String cultureName, String fileName)
315 WriteEvent(14, baseName, mainAssemblyName, cultureName, fileName);
318 [Event(15, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
319 public void ResourceManagerNotCreatingResourceSet(String baseName, String mainAssemblyName, String cultureName)
322 WriteEvent(15, baseName, mainAssemblyName, cultureName);
325 [Event(16, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
326 public void ResourceManagerLookupFailed(String baseName, String mainAssemblyName, String cultureName)
329 WriteEvent(16, baseName, mainAssemblyName, cultureName);
332 [Event(17, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
333 public void ResourceManagerReleasingResources(String baseName, String mainAssemblyName)
336 WriteEvent(17, baseName, mainAssemblyName);
339 [Event(18, Level = EventLevel.Warning, Keywords = Keywords.Loader)]
340 public void ResourceManagerNeutralResourcesNotFound(String baseName, String mainAssemblyName, String resName)
343 WriteEvent(18, baseName, mainAssemblyName, resName);
346 [Event(19, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
347 public void ResourceManagerNeutralResourcesFound(String baseName, String mainAssemblyName, String resName)
350 WriteEvent(19, baseName, mainAssemblyName, resName);
353 [Event(20, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
354 public void ResourceManagerAddingCultureFromConfigFile(String baseName, String mainAssemblyName, String cultureName)
357 WriteEvent(20, baseName, mainAssemblyName, cultureName);
360 [Event(21, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
361 public void ResourceManagerCultureNotFoundInConfigFile(String baseName, String mainAssemblyName, String cultureName)
364 WriteEvent(21, baseName, mainAssemblyName, cultureName);
367 [Event(22, Level = EventLevel.Informational, Keywords = Keywords.Loader)]
368 public void ResourceManagerCultureFoundInConfigFile(String baseName, String mainAssemblyName, String cultureName)
371 WriteEvent(22, baseName, mainAssemblyName, cultureName);
375 // ResourceManager Event Wrappers
378 public void ResourceManagerLookupStarted(String baseName, Assembly mainAssembly, String cultureName)
381 ResourceManagerLookupStarted(baseName, GetName(mainAssembly), cultureName);
385 public void ResourceManagerLookingForResourceSet(String baseName, Assembly mainAssembly, String cultureName)
388 ResourceManagerLookingForResourceSet(baseName, GetName(mainAssembly), cultureName);
392 public void ResourceManagerFoundResourceSetInCache(String baseName, Assembly mainAssembly, String cultureName)
395 ResourceManagerFoundResourceSetInCache(baseName, GetName(mainAssembly), cultureName);
399 public void ResourceManagerFoundResourceSetInCacheUnexpected(String baseName, Assembly mainAssembly, String cultureName)
402 ResourceManagerFoundResourceSetInCacheUnexpected(baseName, GetName(mainAssembly), cultureName);
406 public void ResourceManagerStreamFound(String baseName, Assembly mainAssembly, String cultureName, Assembly loadedAssembly, String resourceFileName)
409 ResourceManagerStreamFound(baseName, GetName(mainAssembly), cultureName, GetName(loadedAssembly), resourceFileName);
413 public void ResourceManagerStreamNotFound(String baseName, Assembly mainAssembly, String cultureName, Assembly loadedAssembly, String resourceFileName)
416 ResourceManagerStreamNotFound(baseName, GetName(mainAssembly), cultureName, GetName(loadedAssembly), resourceFileName);
420 public void ResourceManagerGetSatelliteAssemblySucceeded(String baseName, Assembly mainAssembly, String cultureName, String assemblyName)
423 ResourceManagerGetSatelliteAssemblySucceeded(baseName, GetName(mainAssembly), cultureName, assemblyName);
427 public void ResourceManagerGetSatelliteAssemblyFailed(String baseName, Assembly mainAssembly, String cultureName, String assemblyName)
430 ResourceManagerGetSatelliteAssemblyFailed(baseName, GetName(mainAssembly), cultureName, assemblyName);
434 public void ResourceManagerCaseInsensitiveResourceStreamLookupSucceeded(String baseName, Assembly mainAssembly, String assemblyName, String resourceFileName)
437 ResourceManagerCaseInsensitiveResourceStreamLookupSucceeded(baseName, GetName(mainAssembly), assemblyName, resourceFileName);
441 public void ResourceManagerCaseInsensitiveResourceStreamLookupFailed(String baseName, Assembly mainAssembly, String assemblyName, String resourceFileName)
444 ResourceManagerCaseInsensitiveResourceStreamLookupFailed(baseName, GetName(mainAssembly), assemblyName, resourceFileName);
448 public void ResourceManagerManifestResourceAccessDenied(String baseName, Assembly mainAssembly, String assemblyName, String canonicalName)
451 ResourceManagerManifestResourceAccessDenied(baseName, GetName(mainAssembly), assemblyName, canonicalName);
455 public void ResourceManagerNeutralResourcesSufficient(String baseName, Assembly mainAssembly, String cultureName)
458 ResourceManagerNeutralResourcesSufficient(baseName, GetName(mainAssembly), cultureName);
462 public void ResourceManagerNeutralResourceAttributeMissing(Assembly mainAssembly)
465 ResourceManagerNeutralResourceAttributeMissing(GetName(mainAssembly));
469 public void ResourceManagerCreatingResourceSet(String baseName, Assembly mainAssembly, String cultureName, String fileName)
472 ResourceManagerCreatingResourceSet(baseName, GetName(mainAssembly), cultureName, fileName);
476 public void ResourceManagerNotCreatingResourceSet(String baseName, Assembly mainAssembly, String cultureName)
479 ResourceManagerNotCreatingResourceSet(baseName, GetName(mainAssembly), cultureName);
483 public void ResourceManagerLookupFailed(String baseName, Assembly mainAssembly, String cultureName)
486 ResourceManagerLookupFailed(baseName, GetName(mainAssembly), cultureName);
490 public void ResourceManagerReleasingResources(String baseName, Assembly mainAssembly)
493 ResourceManagerReleasingResources(baseName, GetName(mainAssembly));
497 public void ResourceManagerNeutralResourcesNotFound(String baseName, Assembly mainAssembly, String resName)
500 ResourceManagerNeutralResourcesNotFound(baseName, GetName(mainAssembly), resName);
504 public void ResourceManagerNeutralResourcesFound(String baseName, Assembly mainAssembly, String resName)
507 ResourceManagerNeutralResourcesFound(baseName, GetName(mainAssembly), resName);
511 public void ResourceManagerAddingCultureFromConfigFile(String baseName, Assembly mainAssembly, String cultureName)
514 ResourceManagerAddingCultureFromConfigFile(baseName, GetName(mainAssembly), cultureName);
518 public void ResourceManagerCultureNotFoundInConfigFile(String baseName, Assembly mainAssembly, String cultureName)
521 ResourceManagerCultureNotFoundInConfigFile(baseName, GetName(mainAssembly), cultureName);
525 public void ResourceManagerCultureFoundInConfigFile(String baseName, Assembly mainAssembly, String cultureName)
528 ResourceManagerCultureFoundInConfigFile(baseName, GetName(mainAssembly), cultureName);
531 private static string GetName(Assembly assembly)
533 if (assembly == null)
536 return assembly.FullName;
539 [Event(30, Level = EventLevel.Verbose, Keywords = Keywords.ThreadPool | Keywords.ThreadTransfer)]
540 public void ThreadPoolEnqueueWork(long workID)
542 WriteEvent(30, workID);
546 [System.Security.SecuritySafeCritical]
548 public unsafe void ThreadPoolEnqueueWorkObject(object workID)
550 // convert the Object Id to a long
551 ThreadPoolEnqueueWork((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref workID)));
554 [Event(31, Level = EventLevel.Verbose, Keywords = Keywords.ThreadPool | Keywords.ThreadTransfer)]
555 public void ThreadPoolDequeueWork(long workID)
557 WriteEvent(31, workID);
562 [System.Security.SecuritySafeCritical]
564 public unsafe void ThreadPoolDequeueWorkObject(object workID)
566 // convert the Object Id to a long
567 ThreadPoolDequeueWork((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref workID)));
570 // In the desktop runtime they don't use Tasks for the point at which the response happens, which means that the
571 // Activity ID created by start using implicit activity IDs does not match. Thus disable implicit activities (until we fix that)
572 [Event(140, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions = EventActivityOptions.Disable,
573 Task = Tasks.GetResponse, Opcode = EventOpcode.Start, Version = 1)]
574 private void GetResponseStart(long id, string uri, bool success, bool synchronous)
576 WriteEvent(140, id, uri, success, synchronous);
579 [Event(141, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions = EventActivityOptions.Disable,
580 Task = Tasks.GetResponse, Opcode = EventOpcode.Stop, Version = 1)]
581 private void GetResponseStop(long id, bool success, bool synchronous, int statusCode)
583 WriteEvent(141, id, success, synchronous, statusCode);
586 // In the desktop runtime they don't use Tasks for the point at which the response happens, which means that the
587 // Activity ID created by start using implicit activity IDs does not match. Thus disable implicit activities (until we fix that)
588 [Event(142, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions = EventActivityOptions.Disable,
589 Task = Tasks.GetRequestStream, Opcode = EventOpcode.Start, Version = 1)]
590 private void GetRequestStreamStart(long id, string uri, bool success, bool synchronous)
592 WriteEvent(142, id, uri, success, synchronous);
595 [Event(143, Level = EventLevel.Informational, Keywords = Keywords.NetClient, ActivityOptions = EventActivityOptions.Disable,
596 Task = Tasks.GetRequestStream, Opcode = EventOpcode.Stop, Version = 1)]
597 private void GetRequestStreamStop(long id, bool success, bool synchronous)
599 WriteEvent(143, id, success, synchronous);
604 [System.Security.SecuritySafeCritical]
606 public unsafe void BeginGetResponse(object id, string uri, bool success, bool synchronous)
609 GetResponseStart(IdForObject(id), uri, success, synchronous);
614 [System.Security.SecuritySafeCritical]
616 public unsafe void EndGetResponse(object id, bool success, bool synchronous, int statusCode)
619 GetResponseStop(IdForObject(id), success, synchronous, statusCode);
624 [System.Security.SecuritySafeCritical]
626 public unsafe void BeginGetRequestStream(object id, string uri, bool success, bool synchronous)
629 GetRequestStreamStart(IdForObject(id), uri, success, synchronous);
634 [System.Security.SecuritySafeCritical]
636 public unsafe void EndGetRequestStream(object id, bool success, bool synchronous)
639 GetRequestStreamStop(IdForObject(id), success, synchronous);
642 // id - represents a correlation ID that allows correlation of two activities, one stamped by
643 // ThreadTransferSend, the other by ThreadTransferReceive
644 // kind - identifies the transfer: values below 64 are reserved for the runtime. Currently used values:
645 // 1 - managed Timers ("roaming" ID)
646 // 2 - managed async IO operations (FileStream, PipeStream, a.o.)
647 // 3 - WinRT dispatch operations
648 // info - any additional information user code might consider interesting
649 [Event(150, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = EventOpcode.Send)]
650 public void ThreadTransferSend(long id, int kind, string info, bool multiDequeues)
653 WriteEvent(150, id, kind, info, multiDequeues);
655 // id - is a managed object. it gets translated to the object's address. ETW listeners must
656 // keep track of GC movements in order to correlate the value passed to XyzSend with the
657 // (possibly changed) value passed to XyzReceive
660 [System.Security.SecuritySafeCritical]
662 public unsafe void ThreadTransferSendObj(object id, int kind, string info, bool multiDequeues)
664 ThreadTransferSend((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref id)), kind, info, multiDequeues);
667 // id - represents a correlation ID that allows correlation of two activities, one stamped by
668 // ThreadTransferSend, the other by ThreadTransferReceive
669 // kind - identifies the transfer: values below 64 are reserved for the runtime. Currently used values:
670 // 1 - managed Timers ("roaming" ID)
671 // 2 - managed async IO operations (FileStream, PipeStream, a.o.)
672 // 3 - WinRT dispatch operations
673 // info - any additional information user code might consider interesting
674 [Event(151, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = EventOpcode.Receive)]
675 public void ThreadTransferReceive(long id, int kind, string info)
678 WriteEvent(151, id, kind, info);
680 // id - is a managed object. it gets translated to the object's address. ETW listeners must
681 // keep track of GC movements in order to correlate the value passed to XyzSend with the
682 // (possibly changed) value passed to XyzReceive
685 [System.Security.SecuritySafeCritical]
687 public unsafe void ThreadTransferReceiveObj(object id, int kind, string info)
689 ThreadTransferReceive((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref id)), kind, info);
692 // id - represents a correlation ID that allows correlation of two activities, one stamped by
693 // ThreadTransferSend, the other by ThreadTransferReceive
694 // kind - identifies the transfer: values below 64 are reserved for the runtime. Currently used values:
695 // 1 - managed Timers ("roaming" ID)
696 // 2 - managed async IO operations (FileStream, PipeStream, a.o.)
697 // 3 - WinRT dispatch operations
698 // info - any additional information user code might consider interesting
699 [Event(152, Level = EventLevel.Informational, Keywords = Keywords.ThreadTransfer, Task = Tasks.ThreadTransfer, Opcode = Opcodes.ReceiveHandled)]
700 public void ThreadTransferReceiveHandled(long id, int kind, string info)
703 WriteEvent(152, id, kind, info);
705 // id - is a managed object. it gets translated to the object's address. ETW listeners must
706 // keep track of GC movements in order to correlate the value passed to XyzSend with the
707 // (possibly changed) value passed to XyzReceive
710 [System.Security.SecuritySafeCritical]
712 public unsafe void ThreadTransferReceiveHandledObj(object id, int kind, string info)
714 ThreadTransferReceive((long)*((void**)JitHelpers.UnsafeCastToStackPointer(ref id)), kind, info);
717 // return a stable ID for a an object. We use the hash code which is not truely unique but is
718 // close enough for now at least. we add to it 0x7FFFFFFF00000000 to make it distinguishable
719 // from the style of ID that simply casts the object reference to a long (since old versions of the
720 // runtime will emit IDs of that form).
721 private static long IdForObject(object obj)
723 return obj.GetHashCode() + 0x7FFFFFFF00000000;