summaryrefslogtreecommitdiff
path: root/src/vm/eventpipesession.h
blob: 839ede5b394dade2733ede333d62b4b8edbff197 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
// 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.

#ifndef __EVENTPIPE_SESSION_H__
#define __EVENTPIPE_SESSION_H__

#ifdef FEATURE_PERFTRACING

#include "common.h"
#include "hosting.h"
#include "threadsuspend.h"

class EventPipeBufferManager;
class EventPipeEventInstance;
class EventPipeFile;
class EventPipeSessionProvider;
class EventPipeSessionProviderList;
class EventPipeThread;

// TODO: Revisit the need of this enum and its usage.
enum class EventPipeSessionType
{
    File,
    Listener,
    IpcStream
};

enum class EventPipeSerializationFormat
{
    // Default format used in .Net Core 2.0-3.0 Preview 6
    // TBD - it may remain the default format .Net Core 3.0 when
    // used with private EventPipe managed API via reflection.
    // This format had limited official exposure in documented
    // end-user RTM scenarios, but it is supported by PerfView,
    // TraceEvent, and was used by AI profiler
    NetPerfV3,

    // Default format we plan to use in .Net Core 3 Preview7+
    // for most if not all scenarios
    NetTraceV4,

    Count
};

//! Encapsulates an EventPipe session information and memory management.
class EventPipeSession
{
private:
    const uint32_t m_index;

    // The set of configurations for each provider in the session.
    EventPipeSessionProviderList *const m_pProviderList;

    // Session buffer manager.
    EventPipeBufferManager * m_pBufferManager;

    // True if rundown is enabled.
    Volatile<bool> m_rundownEnabled;

    // The type of the session.
    // This determines behavior within the system (e.g. policies around which events to drop, etc.)
    const EventPipeSessionType m_SessionType;

    // For file/IPC sessions this controls the format emitted. For in-proc EventListener it is
    // irrelevant.
    EventPipeSerializationFormat m_format;

    // For determininig if a particular session needs rundown events
    const bool m_rundownRequested;

    // Start date and time in UTC.
    FILETIME m_sessionStartTime;

    // Start timestamp.
    LARGE_INTEGER m_sessionStartTimeStamp;

    // Object used to flush event data (File, IPC stream, etc.).
    EventPipeFile *m_pFile;

    // Data members used when an IPC streaming thread is used.
    Volatile<BOOL> m_ipcStreamingEnabled = false;

    // When the session is of IPC type, this becomes a handle to the streaming thread.
    Thread *m_pIpcStreamingThread = nullptr;

    // Event object used to signal Disable that the IPC streaming thread is done.
    CLREvent m_threadShutdownEvent;

    void CreateIpcStreamingThread();

    static DWORD WINAPI ThreadProc(void *args);

    void SetThreadShutdownEvent();

    void DisableIpcStreamingThread();

public:
    EventPipeSession(
        uint32_t index,
        LPCWSTR strOutputPath,
        IpcStream *const pStream,
        EventPipeSessionType sessionType,
        EventPipeSerializationFormat format,
        bool rundownRequested,
        uint32_t circularBufferSizeInMB,
        const EventPipeProviderConfiguration *pProviders,
        uint32_t numProviders,
        bool rundownEnabled = false);
    ~EventPipeSession();
    void Close();

    uint64_t GetMask() const
    {
        LIMITED_METHOD_CONTRACT;
        return ((uint64_t)1 << m_index);
    }

    uint32_t GetIndex() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_index;
    }

    // Get the session type.
    EventPipeSessionType GetSessionType() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_SessionType;
    }

    // Get the format version used by the file/IPC serializer
    EventPipeSerializationFormat GetSerializationFormat() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_format;
    }

    // Get whether rundown was requested by the client.
    bool RundownRequested() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_rundownRequested;
    }

    // Determine if rundown is enabled.
    bool RundownEnabled() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_rundownEnabled;
    }

    // Get the session start time in UTC.
    FILETIME GetStartTime() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_sessionStartTime;
    }

    // Get the session start timestamp.
    LARGE_INTEGER GetStartTimeStamp() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_sessionStartTimeStamp;
    }

    bool IsIpcStreamingEnabled() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_ipcStreamingEnabled;
    }

#ifdef DEBUG
    EventPipeBufferManager* GetBufferManager() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_pBufferManager;
    }
#endif

    Thread *GetIpcStreamingThread() const
    {
        LIMITED_METHOD_CONTRACT;
        return m_pIpcStreamingThread;
    }

    // Add a new provider to the session.
    void AddSessionProvider(EventPipeSessionProvider *pProvider);

    // Get the session provider for the specified provider if present.
    EventPipeSessionProvider* GetSessionProvider(const EventPipeProvider *pProvider) const;

    bool WriteAllBuffersToFile(bool *pEventsWritten);

    bool WriteEventBuffered(
        Thread *pThread,
        EventPipeEvent &event,
        EventPipeEventPayload &payload,
        LPCGUID pActivityId,
        LPCGUID pRelatedActivityId,
        Thread *pEventThread = nullptr,
        StackContents *pStack = nullptr);

    // Write a sequence point into the output stream synchronously
    void WriteSequencePointUnbuffered();

    EventPipeEventInstance *GetNextEvent();

    CLREvent *GetWaitEvent();

    // Enable a session in the event pipe.
    void Enable();

    // Disable a session in the event pipe.
    // side-effects: writes all buffers to stream/file
    void Disable();

    // Force all in-progress writes to either finish or cancel
    // This is required to ensure we can safely flush and delete the buffers
    void SuspendWriteEvent();

    void EnableRundown();
    void ExecuteRundown();

    // Determine if the session is valid or not.  Invalid sessions can be detected before they are enabled.
    bool IsValid() const;

    bool HasIpcStreamingStarted() /* This is not const because CrtsHolder does not take a const* */;
};

#endif // FEATURE_PERFTRACING

#endif // __EVENTPIPE_SESSION_H__