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.
4
5#include "common.h"
6#include "eventpipeconfiguration.h"
7#include "eventpipeeventinstance.h"
8#include "eventpipejsonfile.h"
9#include "fastserializer.h"
10#include "sampleprofiler.h"
11
12#ifdef FEATURE_PERFTRACING
13
14EventPipeEventInstance::EventPipeEventInstance(
15 EventPipeSession &session,
16 EventPipeEvent &event,
17 DWORD threadID,
18 BYTE *pData,
19 unsigned int length,
20 LPCGUID pActivityId,
21 LPCGUID pRelatedActivityId)
22{
23 CONTRACTL
24 {
25 NOTHROW;
26 GC_NOTRIGGER;
27 MODE_ANY;
28 }
29 CONTRACTL_END;
30
31#ifdef _DEBUG
32 m_debugEventStart = 0xDEADBEEF;
33 m_debugEventEnd = 0xCAFEBABE;
34#endif // _DEBUG
35 m_pEvent = &event;
36 m_threadID = threadID;
37 if(pActivityId != NULL)
38 {
39 m_activityId = *pActivityId;
40 }
41 else
42 {
43 m_activityId = {0};
44 }
45 if(pRelatedActivityId != NULL)
46 {
47 m_relatedActivityId = *pRelatedActivityId;
48 }
49 else
50 {
51 m_relatedActivityId = {0};
52 }
53
54 m_pData = pData;
55 m_dataLength = length;
56 QueryPerformanceCounter(&m_timeStamp);
57 _ASSERTE(m_timeStamp.QuadPart > 0);
58
59 if(event.NeedStack() && !session.RundownEnabled())
60 {
61 EventPipe::WalkManagedStackForCurrentThread(m_stackContents);
62 }
63
64#ifdef _DEBUG
65 EnsureConsistency();
66#endif // _DEBUG
67}
68
69unsigned int EventPipeEventInstance::GetAlignedTotalSize() const
70{
71 CONTRACT(unsigned int)
72 {
73 NOTHROW;
74 GC_NOTRIGGER;
75 MODE_ANY;
76 POSTCONDITION(RETVAL % ALIGNMENT_SIZE == 0);
77 }
78 CONTRACT_END;
79
80 // Calculate the size of the total payload so that it can be written to the file.
81 unsigned int payloadLength =
82 sizeof(m_metadataId) + // Metadata ID
83 sizeof(m_threadID) + // Thread ID
84 sizeof(m_timeStamp) + // TimeStamp
85 sizeof(m_activityId) + // Activity ID
86 sizeof(m_relatedActivityId) + // Related Activity ID
87 sizeof(m_dataLength) + // Data payload length
88 m_dataLength + // Event payload data
89 sizeof(unsigned int) + // Prepended stack payload size in bytes
90 m_stackContents.GetSize(); // Stack payload size
91
92 // round up to ALIGNMENT_SIZE bytes
93 if (payloadLength % ALIGNMENT_SIZE != 0)
94 {
95 payloadLength += ALIGNMENT_SIZE - (payloadLength % ALIGNMENT_SIZE);
96 }
97
98 RETURN payloadLength;
99}
100
101#ifdef _DEBUG
102void EventPipeEventInstance::SerializeToJsonFile(EventPipeJsonFile *pFile)
103{
104 CONTRACTL
105 {
106 NOTHROW;
107 GC_NOTRIGGER;
108 MODE_ANY;
109 }
110 CONTRACTL_END;
111
112 if(pFile == NULL)
113 {
114 return;
115 }
116
117 EX_TRY
118 {
119 StackScratchBuffer scratch;
120 SString providerName = m_pEvent->GetProvider()->GetProviderName();
121
122 SString message;
123 message.Printf("Provider=%s/EventID=%d/Version=%d", providerName.GetANSI(scratch), m_pEvent->GetEventID(), m_pEvent->GetEventVersion());
124 pFile->WriteEvent(m_timeStamp, m_threadID, message, m_stackContents);
125 }
126 EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);
127}
128#endif
129
130void EventPipeEventInstance::SetTimeStamp(LARGE_INTEGER timeStamp)
131{
132 LIMITED_METHOD_CONTRACT;
133
134 m_timeStamp = timeStamp;
135}
136
137#ifdef _DEBUG
138bool EventPipeEventInstance::EnsureConsistency()
139{
140 CONTRACTL
141 {
142 NOTHROW;
143 GC_NOTRIGGER;
144 MODE_ANY;
145 }
146 CONTRACTL_END;
147
148 // Validate event start.
149 _ASSERTE(m_debugEventStart == 0xDEADBEEF);
150
151 // Validate event end.
152 _ASSERTE(m_debugEventEnd == 0xCAFEBABE);
153
154 return true;
155}
156#endif // _DEBUG
157
158SampleProfilerEventInstance::SampleProfilerEventInstance(EventPipeSession &session, EventPipeEvent &event, Thread *pThread, BYTE *pData, unsigned int length)
159 :EventPipeEventInstance(session, event, pThread->GetOSThreadId(), pData, length, NULL /* pActivityId */, NULL /* pRelatedActivityId */)
160{
161 LIMITED_METHOD_CONTRACT;
162}
163
164#endif // FEATURE_PERFTRACING
165