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 "eventpipeblock.h" |
7 | #include "eventpipeeventinstance.h" |
8 | #include "fastserializableobject.h" |
9 | #include "fastserializer.h" |
10 | |
11 | #ifdef FEATURE_PERFTRACING |
12 | |
13 | EventPipeBlock::EventPipeBlock(unsigned int maxBlockSize) |
14 | { |
15 | CONTRACTL |
16 | { |
17 | NOTHROW; |
18 | GC_NOTRIGGER; |
19 | MODE_ANY; |
20 | } |
21 | CONTRACTL_END; |
22 | |
23 | m_pBlock = new (nothrow) BYTE[maxBlockSize]; |
24 | if (m_pBlock == NULL) |
25 | { |
26 | return; |
27 | } |
28 | |
29 | memset(m_pBlock, 0, maxBlockSize); |
30 | m_pWritePointer = m_pBlock; |
31 | m_pEndOfTheBuffer = m_pBlock + maxBlockSize; |
32 | } |
33 | |
34 | EventPipeBlock::~EventPipeBlock() |
35 | { |
36 | CONTRACTL |
37 | { |
38 | NOTHROW; |
39 | GC_NOTRIGGER; |
40 | MODE_ANY; |
41 | } |
42 | CONTRACTL_END; |
43 | |
44 | if(m_pBlock != NULL) |
45 | { |
46 | m_pEndOfTheBuffer = NULL; |
47 | m_pWritePointer = NULL; |
48 | delete[] m_pBlock; |
49 | m_pBlock = NULL; |
50 | } |
51 | } |
52 | |
53 | bool EventPipeBlock::WriteEvent(EventPipeEventInstance &instance) |
54 | { |
55 | CONTRACTL |
56 | { |
57 | NOTHROW; |
58 | GC_NOTRIGGER; |
59 | MODE_ANY; |
60 | } |
61 | CONTRACTL_END; |
62 | |
63 | if (m_pBlock == NULL) |
64 | { |
65 | return false; |
66 | } |
67 | |
68 | unsigned int totalSize = instance.GetAlignedTotalSize(); |
69 | if (m_pWritePointer + totalSize >= m_pEndOfTheBuffer) |
70 | { |
71 | return false; |
72 | } |
73 | |
74 | BYTE* alignedEnd = m_pWritePointer + totalSize + sizeof(totalSize); |
75 | |
76 | memcpy(m_pWritePointer, &totalSize, sizeof(totalSize)); |
77 | m_pWritePointer += sizeof(totalSize); |
78 | |
79 | unsigned int metadataId = instance.GetMetadataId(); |
80 | memcpy(m_pWritePointer, &metadataId, sizeof(metadataId)); |
81 | m_pWritePointer += sizeof(metadataId); |
82 | |
83 | DWORD threadId = instance.GetThreadId(); |
84 | memcpy(m_pWritePointer, &threadId, sizeof(threadId)); |
85 | m_pWritePointer += sizeof(threadId); |
86 | |
87 | const LARGE_INTEGER* timeStamp = instance.GetTimeStamp(); |
88 | memcpy(m_pWritePointer, timeStamp, sizeof(*timeStamp)); |
89 | m_pWritePointer += sizeof(*timeStamp); |
90 | |
91 | const GUID* activityId = instance.GetActivityId(); |
92 | memcpy(m_pWritePointer, activityId, sizeof(*activityId)); |
93 | m_pWritePointer += sizeof(*activityId); |
94 | |
95 | const GUID* relatedActivityId = instance.GetRelatedActivityId(); |
96 | memcpy(m_pWritePointer, relatedActivityId, sizeof(*relatedActivityId)); |
97 | m_pWritePointer += sizeof(*relatedActivityId); |
98 | |
99 | unsigned int dataLength = instance.GetDataLength(); |
100 | memcpy(m_pWritePointer, &dataLength, sizeof(dataLength)); |
101 | m_pWritePointer += sizeof(dataLength); |
102 | |
103 | if (dataLength > 0) |
104 | { |
105 | memcpy(m_pWritePointer, instance.GetData(), dataLength); |
106 | m_pWritePointer += dataLength; |
107 | } |
108 | |
109 | unsigned int stackSize = instance.GetStackSize(); |
110 | memcpy(m_pWritePointer, &stackSize, sizeof(stackSize)); |
111 | m_pWritePointer += sizeof(stackSize); |
112 | |
113 | if (stackSize > 0) |
114 | { |
115 | memcpy(m_pWritePointer, instance.GetStack(), stackSize); |
116 | m_pWritePointer += stackSize; |
117 | } |
118 | |
119 | while (m_pWritePointer < alignedEnd) |
120 | { |
121 | *m_pWritePointer++ = (BYTE)0; // put padding at the end to get 4 bytes alignment of the payload |
122 | } |
123 | |
124 | return true; |
125 | } |
126 | |
127 | void EventPipeBlock::Clear() |
128 | { |
129 | CONTRACTL |
130 | { |
131 | NOTHROW; |
132 | GC_NOTRIGGER; |
133 | MODE_ANY; |
134 | } |
135 | CONTRACTL_END; |
136 | |
137 | if (m_pBlock == NULL) |
138 | { |
139 | return; |
140 | } |
141 | |
142 | memset(m_pBlock, 0, GetSize()); |
143 | m_pWritePointer = m_pBlock; |
144 | } |
145 | |
146 | #endif // FEATURE_PERFTRACING |
147 | |