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.
92 bool EventPipeConfiguration::UnregisterProvider(EventPipeProvider &provider)
102 // Take the lock before manipulating the provider list.
103 CrstHolder _crst(EventPipe::GetLock());
105 // Find the provider.
106 SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead();
109 if(pElem->GetValue() == &provider)
114 pElem = m_pProviderList->GetNext(pElem);
117 // If we found the provider, remove it.
120 if(m_pProviderList->FindAndRemove(pElem) != NULL)
129 EventPipeProvider* EventPipeConfiguration::GetProvider(const GUID &providerID)
139 // Take the lock before touching the provider list to ensure no one tries to
141 CrstHolder _crst(EventPipe::GetLock());
143 return GetProviderNoLock(providerID);
146 EventPipeProvider* EventPipeConfiguration::GetProviderNoLock(const GUID &providerID)
153 PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
157 SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead();
160 EventPipeProvider *pProvider = pElem->GetValue();
161 if(pProvider->GetProviderID() == providerID)
166 pElem = m_pProviderList->GetNext(pElem);
172 void EventPipeConfiguration::Enable()
179 // Lock must be held by EventPipe::Enable.
180 PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
184 SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead();
187 // TODO: Only enable the providers that have been explicitly enabled with specified keywords/level.
188 EventPipeProvider *pProvider = pElem->GetValue();
189 pProvider->SetConfiguration(true /* providerEnabled */, 0xFFFFFFFFFFFFFFFF /* keywords */, EventPipeEventLevel::Verbose /* level */);
191 pElem = m_pProviderList->GetNext(pElem);
196 void EventPipeConfiguration::Disable()
203 // Lock must be held by EventPipe::Disable.
204 PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
208 SListElem<EventPipeProvider*> *pElem = m_pProviderList->GetHead();
211 EventPipeProvider *pProvider = pElem->GetValue();
212 pProvider->SetConfiguration(false /* providerEnabled */, 0 /* keywords */, EventPipeEventLevel::Critical /* level */);
214 pElem = m_pProviderList->GetNext(pElem);
218 EventPipeEventInstance* EventPipeConfiguration::BuildEventMetadataEvent(EventPipeEvent &sourceEvent, BYTE *pPayloadData, unsigned int payloadLength)
228 // The payload of the event should contain:
229 // - GUID ProviderID.
230 // - unsigned int EventID.
231 // - unsigned int EventVersion.
232 // - Optional event description payload.
234 // Calculate the size of the event.
235 const GUID &providerID = sourceEvent.GetProvider()->GetProviderID();
236 unsigned int eventID = sourceEvent.GetEventID();
237 unsigned int eventVersion = sourceEvent.GetEventVersion();
238 unsigned int instancePayloadSize = sizeof(providerID) + sizeof(eventID) + sizeof(eventVersion) + payloadLength;
240 // Allocate the payload.
241 BYTE *pInstancePayload = new BYTE[instancePayloadSize];
243 // Fill the buffer with the payload.
244 BYTE *currentPtr = pInstancePayload;
246 // Write the provider ID.
247 memcpy(currentPtr, (BYTE*)&providerID, sizeof(providerID));
248 currentPtr += sizeof(providerID);
250 // Write the event ID.
251 memcpy(currentPtr, &eventID, sizeof(eventID));
252 currentPtr += sizeof(eventID);
254 // Write the event version.
255 memcpy(currentPtr, &eventVersion, sizeof(eventVersion));
256 currentPtr += sizeof(eventVersion);
258 // Write the incoming payload data.
259 memcpy(currentPtr, pPayloadData, payloadLength);
261 // Construct the event instance.
262 EventPipeEventInstance *pInstance = new EventPipeEventInstance(
264 GetCurrentThreadId(),
266 instancePayloadSize);
271 #endif // FEATURE_PERFTRACING