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.
7 #include "eventpipeconfiguration.h"
8 #include "eventpipeeventinstance.h"
9 #include "eventpipeprovider.h"
11 #ifdef FEATURE_PERFTRACING
13 // {5291C09C-2660-4D6A-83A3-C383FD020DEC}
14 const GUID EventPipeConfiguration::s_configurationProviderID =
15 { 0x5291c09c, 0x2660, 0x4d6a, { 0x83, 0xa3, 0xc3, 0x83, 0xfd, 0x2, 0xd, 0xec } };
17 EventPipeConfiguration::EventPipeConfiguration()
21 m_pProviderList = new SList<SListElem<EventPipeProvider*>>();
24 EventPipeConfiguration::~EventPipeConfiguration()
34 if(m_pProviderList != NULL)
36 delete(m_pProviderList);
37 m_pProviderList = NULL;
41 void EventPipeConfiguration::Initialize()
51 // Create the configuration provider.
52 m_pConfigProvider = new EventPipeProvider(s_configurationProviderID);
54 // Create the metadata event.
55 m_pMetadataEvent = m_pConfigProvider->AddEvent(
59 EventPipeEventLevel::Critical,
60 false); /* needStack */
63 bool EventPipeConfiguration::RegisterProvider(EventPipeProvider &provider)
73 // Take the lock before manipulating the provider list.
74 CrstHolder _crst(EventPipe::GetLock());
76 // See if we've already registered this provider.
77 EventPipeProvider *pExistingProvider = GetProviderNoLock(provider.GetProviderID());
78 if(pExistingProvider != NULL)
83 // The provider has not been registered, so register it.
84 m_pProviderList->InsertTail(new SListElem<EventPipeProvider*>(&provider));
86 // TODO: Set the provider configuration and enable it if we know
87 // anything about the provider before it is registered.
88 provider.SetConfiguration(true /* providerEnabled */, 0xFFFFFFFFFFFFFFFF /* keywords */, EventPipeEventLevel::Verbose /* level */);
93 bool EventPipeConfiguration::UnregisterProvider(EventPipeProvider &provider)
103 // Take the lock before manipulating the provider list.
104 CrstHolder _crst(EventPipe::GetLock());
106 // Find the provider.
107 SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead();
110 if(pElem->GetValue() == &provider)
115 pElem = m_pProviderList->GetNext(pElem);
118 // If we found the provider, remove it.
121 if(m_pProviderList->FindAndRemove(pElem) != NULL)
130 EventPipeProvider* EventPipeConfiguration::GetProvider(const GUID &providerID)
140 // Take the lock before touching the provider list to ensure no one tries to
142 CrstHolder _crst(EventPipe::GetLock());
144 return GetProviderNoLock(providerID);
147 EventPipeProvider* EventPipeConfiguration::GetProviderNoLock(const GUID &providerID)
154 PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
158 SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead();
161 EventPipeProvider *pProvider = pElem->GetValue();
162 if(pProvider->GetProviderID() == providerID)
167 pElem = m_pProviderList->GetNext(pElem);
173 void EventPipeConfiguration::Enable()
180 // Lock must be held by EventPipe::Enable.
181 PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
185 SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead();
188 // TODO: Only enable the providers that have been explicitly enabled with specified keywords/level.
189 EventPipeProvider *pProvider = pElem->GetValue();
190 pProvider->SetConfiguration(true /* providerEnabled */, 0xFFFFFFFFFFFFFFFF /* keywords */, EventPipeEventLevel::Verbose /* level */);
192 pElem = m_pProviderList->GetNext(pElem);
197 void EventPipeConfiguration::Disable()
204 // Lock must be held by EventPipe::Disable.
205 PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
209 SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead();
212 EventPipeProvider *pProvider = pElem->GetValue();
213 pProvider->SetConfiguration(false /* providerEnabled */, 0 /* keywords */, EventPipeEventLevel::Critical /* level */);
215 pElem = m_pProviderList->GetNext(pElem);
219 EventPipeEventInstance* EventPipeConfiguration::BuildEventMetadataEvent(EventPipeEvent &sourceEvent, BYTE *pPayloadData, unsigned int payloadLength)
229 // The payload of the event should contain:
230 // - GUID ProviderID.
231 // - unsigned int EventID.
232 // - unsigned int EventVersion.
233 // - Optional event description payload.
235 // Calculate the size of the event.
236 const GUID &providerID = sourceEvent.GetProvider()->GetProviderID();
237 unsigned int eventID = sourceEvent.GetEventID();
238 unsigned int eventVersion = sourceEvent.GetEventVersion();
239 unsigned int instancePayloadSize = sizeof(providerID) + sizeof(eventID) + sizeof(eventVersion) + payloadLength;
241 // Allocate the payload.
242 BYTE *pInstancePayload = new BYTE[instancePayloadSize];
244 // Fill the buffer with the payload.
245 BYTE *currentPtr = pInstancePayload;
247 // Write the provider ID.
248 memcpy(currentPtr, (BYTE*)&providerID, sizeof(providerID));
249 currentPtr += sizeof(providerID);
251 // Write the event ID.
252 memcpy(currentPtr, &eventID, sizeof(eventID));
253 currentPtr += sizeof(eventID);
255 // Write the event version.
256 memcpy(currentPtr, &eventVersion, sizeof(eventVersion));
257 currentPtr += sizeof(eventVersion);
259 // Write the incoming payload data.
260 memcpy(currentPtr, pPayloadData, payloadLength);
262 // Construct the event instance.
263 EventPipeEventInstance *pInstance = new EventPipeEventInstance(
265 GetCurrentThreadId(),
267 instancePayloadSize);
272 #endif // FEATURE_PERFTRACING