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
|
// 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_BUFFER_H__
#define __EVENTPIPE_BUFFER_H__
#ifdef FEATURE_PERFTRACING
#include "eventpipe.h"
#include "eventpipeevent.h"
#include "eventpipeeventinstance.h"
class EventPipeBuffer
{
friend class EventPipeBufferList;
friend class EventPipeBufferManager;
private:
// A pointer to the actual buffer.
BYTE *m_pBuffer;
// The current write pointer.
BYTE *m_pCurrent;
// The max write pointer (end of the buffer).
BYTE *m_pLimit;
// The timestamp of the most recent event in the buffer.
LARGE_INTEGER m_mostRecentTimeStamp;
// Used by PopNext as input to GetNext.
// If NULL, no events have been popped.
// The event will still remain in the buffer after it is popped, but PopNext will not return it again.
EventPipeEventInstance *m_pLastPoppedEvent;
// Each buffer will become part of a per-thread linked list of buffers.
// The linked list is invasive, thus we declare the pointers here.
EventPipeBuffer *m_pPrevBuffer;
EventPipeBuffer *m_pNextBuffer;
unsigned int GetSize() const
{
LIMITED_METHOD_CONTRACT;
return (unsigned int)(m_pLimit - m_pBuffer);
}
EventPipeBuffer* GetPrevious() const
{
LIMITED_METHOD_CONTRACT;
return m_pPrevBuffer;
}
EventPipeBuffer* GetNext() const
{
LIMITED_METHOD_CONTRACT;
return m_pNextBuffer;
}
void SetPrevious(EventPipeBuffer *pBuffer)
{
LIMITED_METHOD_CONTRACT;
m_pPrevBuffer = pBuffer;
}
void SetNext(EventPipeBuffer *pBuffer)
{
LIMITED_METHOD_CONTRACT;
m_pNextBuffer = pBuffer;
}
public:
EventPipeBuffer(unsigned int bufferSize);
~EventPipeBuffer();
// Write an event to the buffer.
// An optional stack trace can be provided for sample profiler events.
// Otherwise, if a stack trace is needed, one will be automatically collected.
// Returns:
// - true: The write succeeded.
// - false: The write failed. In this case, the buffer should be considered full.
bool WriteEvent(Thread *pThread, EventPipeEvent &event, EventPipeEventPayload &payload, LPCGUID pActivityId, LPCGUID pRelatedActivityId, StackContents *pStack = NULL);
// Get the timestamp of the most recent event in the buffer.
LARGE_INTEGER GetMostRecentTimeStamp() const;
// Clear the buffer.
void Clear();
// Get the next event from the buffer as long as it is before the specified timestamp.
// Input of NULL gets the first event.
EventPipeEventInstance* GetNext(EventPipeEventInstance *pEvent, LARGE_INTEGER beforeTimeStamp);
// Get the next event from the buffer, but don't mark it read.
EventPipeEventInstance* PeekNext(LARGE_INTEGER beforeTimeStamp);
// Get the next event from the buffer and mark it as read.
EventPipeEventInstance* PopNext(LARGE_INTEGER beforeTimeStamp);
#ifdef _DEBUG
bool EnsureConsistency();
#endif // _DEBUG
};
#endif // FEATURE_PERFTRACING
#endif // __EVENTPIPE_BUFFER_H__
|