summaryrefslogtreecommitdiff
path: root/src/vm/eventpipeprovider.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/eventpipeprovider.cpp')
-rw-r--r--src/vm/eventpipeprovider.cpp244
1 files changed, 244 insertions, 0 deletions
diff --git a/src/vm/eventpipeprovider.cpp b/src/vm/eventpipeprovider.cpp
new file mode 100644
index 0000000000..896f9b2650
--- /dev/null
+++ b/src/vm/eventpipeprovider.cpp
@@ -0,0 +1,244 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include "common.h"
+#include "eventpipe.h"
+#include "eventpipeconfiguration.h"
+#include "eventpipeevent.h"
+#include "eventpipeprovider.h"
+
+#ifdef FEATURE_PERFTRACING
+
+EventPipeProvider::EventPipeProvider(const GUID &providerID, EventPipeCallback pCallbackFunction, void *pCallbackData)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ m_providerID = providerID;
+ m_enabled = false;
+ m_keywords = 0;
+ m_providerLevel = EventPipeEventLevel::Critical;
+ m_pEventList = new SList<SListElem<EventPipeEvent*>>();
+ m_pCallbackFunction = pCallbackFunction;
+ m_pCallbackData = pCallbackData;
+ m_pConfig = EventPipe::GetConfiguration();
+ _ASSERTE(m_pConfig != NULL);
+
+ // Register the provider.
+ m_pConfig->RegisterProvider(*this);
+}
+
+EventPipeProvider::~EventPipeProvider()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ // Unregister the provider.
+ // This call is re-entrant.
+ // NOTE: We don't use the cached event pipe configuration pointer
+ // in case this runs during shutdown and the configuration has already
+ // been freed.
+ EventPipeConfiguration* pConfig = EventPipe::GetConfiguration();
+ _ASSERTE(pConfig != NULL);
+ pConfig->UnregisterProvider(*this);
+
+ // Free all of the events.
+ if(m_pEventList != NULL)
+ {
+ // Take the lock before manipulating the list.
+ CrstHolder _crst(EventPipe::GetLock());
+
+ SListElem<EventPipeEvent*> *pElem = m_pEventList->GetHead();
+ while(pElem != NULL)
+ {
+ EventPipeEvent *pEvent = pElem->GetValue();
+ delete pEvent;
+
+ pElem = m_pEventList->GetNext(pElem);
+ }
+
+ delete m_pEventList;
+ m_pEventList = NULL;
+ }
+}
+
+const GUID& EventPipeProvider::GetProviderID() const
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return m_providerID;
+}
+
+bool EventPipeProvider::Enabled() const
+{
+ LIMITED_METHOD_CONTRACT;
+
+ return (m_pConfig->Enabled() && m_enabled);
+}
+
+bool EventPipeProvider::EventEnabled(INT64 keywords) const
+{
+ LIMITED_METHOD_CONTRACT;
+
+ // The event is enabled if:
+ // - The provider is enabled.
+ // - The event keywords are unspecified in the manifest (== 0) or when masked with the enabled config are != 0.
+ return (Enabled() && ((keywords == 0) || ((m_keywords & keywords) != 0)));
+}
+
+bool EventPipeProvider::EventEnabled(INT64 keywords, EventPipeEventLevel eventLevel) const
+{
+ LIMITED_METHOD_CONTRACT;
+
+ // The event is enabled if:
+ // - The provider is enabled.
+ // - The event keywords are unspecified in the manifest (== 0) or when masked with the enabled config are != 0.
+ // - The event level is LogAlways or the provider's verbosity level is set to greater than the event's verbosity level in the manifest.
+ return (EventEnabled(keywords) &&
+ ((eventLevel == EventPipeEventLevel::LogAlways) || (m_providerLevel >= eventLevel)));
+}
+
+void EventPipeProvider::SetConfiguration(bool providerEnabled, INT64 keywords, EventPipeEventLevel providerLevel)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
+ }
+ CONTRACTL_END;
+
+ m_enabled = providerEnabled;
+ m_keywords = keywords;
+ m_providerLevel = providerLevel;
+
+ RefreshAllEvents();
+ InvokeCallback();
+}
+
+EventPipeEvent* EventPipeProvider::AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, BYTE *pMetadata, unsigned int metadataLength)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ return AddEvent(eventID, keywords, eventVersion, level, true /* needStack */, pMetadata, metadataLength);
+}
+
+EventPipeEvent* EventPipeProvider::AddEvent(unsigned int eventID, INT64 keywords, unsigned int eventVersion, EventPipeEventLevel level, bool needStack, BYTE *pMetadata, unsigned int metadataLength)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ // Create the event.
+ EventPipeEvent *pEvent = new EventPipeEvent(
+ *this,
+ keywords,
+ eventID,
+ eventVersion,
+ level,
+ needStack,
+ pMetadata,
+ metadataLength);
+
+ // Add it to the list of events.
+ AddEvent(*pEvent);
+ return pEvent;
+}
+
+void EventPipeProvider::AddEvent(EventPipeEvent &event)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACTL_END;
+
+ // Take the config lock before inserting a new event.
+ CrstHolder _crst(EventPipe::GetLock());
+
+ m_pEventList->InsertTail(new SListElem<EventPipeEvent*>(&event));
+ event.RefreshState();
+}
+
+void EventPipeProvider::InvokeCallback()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
+ }
+ CONTRACTL_END;
+
+ if(m_pCallbackFunction != NULL && !g_fEEShutDown)
+ {
+ (*m_pCallbackFunction)(
+ &m_providerID,
+ m_enabled,
+ (UCHAR) m_providerLevel,
+ m_keywords,
+ 0 /* matchAllKeywords */,
+ NULL /* FilterData */,
+ m_pCallbackData /* CallbackContext */);
+ }
+}
+
+bool EventPipeProvider::GetDeleteDeferred() const
+{
+ LIMITED_METHOD_CONTRACT;
+ return m_deleteDeferred;
+}
+
+void EventPipeProvider::SetDeleteDeferred()
+{
+ LIMITED_METHOD_CONTRACT;
+ m_deleteDeferred = true;
+}
+
+void EventPipeProvider::RefreshAllEvents()
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ PRECONDITION(EventPipe::GetLock()->OwnedByCurrentThread());
+ }
+ CONTRACTL_END;
+
+ SListElem<EventPipeEvent*> *pElem = m_pEventList->GetHead();
+ while(pElem != NULL)
+ {
+ EventPipeEvent *pEvent = pElem->GetValue();
+ pEvent->RefreshState();
+
+ pElem = m_pEventList->GetNext(pElem);
+ }
+}
+
+#endif // FEATURE_PERFTRACING