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
13EventPipeBlock::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
34EventPipeBlock::~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
53bool 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
127void 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