Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
52c1d0b9
R
runtime
项目概览
dotNET Platform
/
runtime
12 个月 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
runtime
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
52c1d0b9
编写于
4月 28, 2021
作者:
M
Miha Zupan
提交者:
GitHub
4月 28, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Reduce EventListener overheads (#51822)
* Reduce EventListener overheads * Update comment around byte[] handling
上级
f372f6b5
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
78 addition
and
102 deletion
+78
-102
src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs
...ate.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs
+78
-102
未找到文件。
src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs
浏览文件 @
52c1d0b9
...
...
@@ -1303,22 +1303,23 @@ protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* rel
Debug
.
Assert
(
m_eventData
!=
null
);
// You must have initialized this if you enabled the source.
try
{
EventOpcode
opcode
=
(
EventOpcode
)
m_eventData
[
eventId
].
Descriptor
.
Opcode
;
EventActivityOptions
activityOptions
=
m_eventData
[
eventId
].
ActivityOptions
;
ref
EventMetadata
metadata
=
ref
m_eventData
[
eventId
];
EventOpcode
opcode
=
(
EventOpcode
)
metadata
.
Descriptor
.
Opcode
;
Guid
*
pActivityId
=
null
;
Guid
activityId
=
Guid
.
Empty
;
Guid
relActivityId
=
Guid
.
Empty
;
if
(
opcode
!=
EventOpcode
.
Info
&&
relatedActivityId
==
null
&&
((
a
ctivityOptions
&
EventActivityOptions
.
Disable
)
==
0
))
((
metadata
.
A
ctivityOptions
&
EventActivityOptions
.
Disable
)
==
0
))
{
if
(
opcode
==
EventOpcode
.
Start
)
{
m_activityTracker
.
OnStart
(
m_name
,
m
_eventData
[
eventId
].
Name
,
m_eventData
[
eventId
].
Descriptor
.
Task
,
ref
activityId
,
ref
relActivityId
,
m_eventData
[
eventId
]
.
ActivityOptions
);
m_activityTracker
.
OnStart
(
m_name
,
m
etadata
.
Name
,
metadata
.
Descriptor
.
Task
,
ref
activityId
,
ref
relActivityId
,
metadata
.
ActivityOptions
);
}
else
if
(
opcode
==
EventOpcode
.
Stop
)
{
m_activityTracker
.
OnStop
(
m_name
,
m
_eventData
[
eventId
].
Name
,
m_eventData
[
eventId
]
.
Descriptor
.
Task
,
ref
activityId
);
m_activityTracker
.
OnStop
(
m_name
,
m
etadata
.
Name
,
metadata
.
Descriptor
.
Task
,
ref
activityId
);
}
if
(
activityId
!=
Guid
.
Empty
)
...
...
@@ -1330,39 +1331,37 @@ protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, Guid* rel
#if FEATURE_MANAGED_ETW
if
(!
SelfDescribingEvents
)
{
if
(
m
_eventData
[
eventId
].
EnabledForETW
&&
!
m_etwProvider
.
WriteEvent
(
ref
m_eventData
[
eventId
].
Descriptor
,
m_eventData
[
eventId
]
.
EventHandle
,
pActivityId
,
relatedActivityId
,
eventDataCount
,
(
IntPtr
)
data
))
ThrowEventSourceException
(
m
_eventData
[
eventId
]
.
Name
);
if
(
m
etadata
.
EnabledForETW
&&
!
m_etwProvider
.
WriteEvent
(
ref
metadata
.
Descriptor
,
metadata
.
EventHandle
,
pActivityId
,
relatedActivityId
,
eventDataCount
,
(
IntPtr
)
data
))
ThrowEventSourceException
(
m
etadata
.
Name
);
#if FEATURE_PERFTRACING
if
(
m
_eventData
[
eventId
].
EnabledForEventPipe
&&
!
m_eventPipeProvider
.
WriteEvent
(
ref
m_eventData
[
eventId
].
Descriptor
,
m_eventData
[
eventId
]
.
EventHandle
,
pActivityId
,
relatedActivityId
,
eventDataCount
,
(
IntPtr
)
data
))
ThrowEventSourceException
(
m
_eventData
[
eventId
]
.
Name
);
if
(
m
etadata
.
EnabledForEventPipe
&&
!
m_eventPipeProvider
.
WriteEvent
(
ref
metadata
.
Descriptor
,
metadata
.
EventHandle
,
pActivityId
,
relatedActivityId
,
eventDataCount
,
(
IntPtr
)
data
))
ThrowEventSourceException
(
m
etadata
.
Name
);
#endif // FEATURE_PERFTRACING
}
else
if
(
m
_eventData
[
eventId
]
.
EnabledForETW
else
if
(
m
etadata
.
EnabledForETW
#if FEATURE_PERFTRACING
||
m
_eventData
[
eventId
]
.
EnabledForEventPipe
||
m
etadata
.
EnabledForEventPipe
#endif // FEATURE_PERFTRACING
)
{
TraceLoggingEventTypes
?
tlet
=
m
_eventData
[
eventId
]
.
TraceLoggingEventTypes
;
TraceLoggingEventTypes
?
tlet
=
m
etadata
.
TraceLoggingEventTypes
;
if
(
tlet
==
null
)
{
tlet
=
new
TraceLoggingEventTypes
(
m_eventData
[
eventId
].
Name
,
m_eventData
[
eventId
].
Tags
,
m_eventData
[
eventId
].
Parameters
);
Interlocked
.
CompareExchange
(
ref
m_eventData
[
eventId
].
TraceLoggingEventTypes
,
tlet
,
null
);
tlet
=
new
TraceLoggingEventTypes
(
metadata
.
Name
,
metadata
.
Tags
,
metadata
.
Parameters
);
Interlocked
.
CompareExchange
(
ref
metadata
.
TraceLoggingEventTypes
,
tlet
,
null
);
}
EventSourceOptions
opt
=
new
EventSourceOptions
{
Keywords
=
(
EventKeywords
)
m
_eventData
[
eventId
]
.
Descriptor
.
Keywords
,
Level
=
(
EventLevel
)
m
_eventData
[
eventId
]
.
Descriptor
.
Level
,
Opcode
=
(
EventOpcode
)
m
_eventData
[
eventId
]
.
Descriptor
.
Opcode
Keywords
=
(
EventKeywords
)
m
etadata
.
Descriptor
.
Keywords
,
Level
=
(
EventLevel
)
m
etadata
.
Descriptor
.
Level
,
Opcode
=
(
EventOpcode
)
m
etadata
.
Descriptor
.
Opcode
};
WriteMultiMerge
(
m
_eventData
[
eventId
]
.
Name
,
ref
opt
,
tlet
,
pActivityId
,
relatedActivityId
,
data
);
WriteMultiMerge
(
m
etadata
.
Name
,
ref
opt
,
tlet
,
pActivityId
,
relatedActivityId
,
data
);
}
#endif // FEATURE_MANAGED_ETW
if
(
m_Dispatchers
!=
null
&&
m
_eventData
[
eventId
]
.
EnabledForAnyListener
)
if
(
m_Dispatchers
!=
null
&&
m
etadata
.
EnabledForAnyListener
)
{
#if MONO && !TARGET_BROWSER
// On Mono, managed events from NativeRuntimeEventSource are written using WriteEventCore which can be
...
...
@@ -1693,7 +1692,7 @@ private static Guid GenerateGuidFromName(string name)
return
new
Guid
(
bytes
);
}
private
unsafe
object
?
DecodeObject
(
int
eventId
,
int
parameterId
,
ref
EventSource
.
EventData
*
data
)
private
static
unsafe
object
?
DecodeObject
(
Type
dataType
,
ref
EventSource
.
EventData
*
data
)
{
// TODO FIX : We use reflection which in turn uses EventSource, right now we carefully avoid
// the recursion, but can we do this in a robust way?
...
...
@@ -1702,9 +1701,6 @@ private static Guid GenerateGuidFromName(string name)
// advance to next EventData in array
++
data
;
Debug
.
Assert
(
m_eventData
!=
null
);
Type
dataType
=
GetDataType
(
m_eventData
[
eventId
],
parameterId
);
Again
:
if
(
dataType
==
typeof
(
IntPtr
))
{
...
...
@@ -1790,46 +1786,32 @@ private static Guid GenerateGuidFromName(string name)
}
else
{
if
(
m_EventSourcePreventRecursion
&&
m_EventSourceInDecodeObject
)
{
return
null
;
}
try
if
(
dataType
.
IsEnum
)
{
m_EventSourceInDecodeObject
=
true
;
dataType
=
Enum
.
GetUnderlyingType
(
dataType
)
;
if
(
dataType
.
IsEnum
)
// Enums less than 4 bytes in size should be treated as int.
switch
(
Type
.
GetTypeCode
(
dataType
))
{
dataType
=
Enum
.
GetUnderlyingType
(
dataType
);
// Enums less than 4 bytes in size should be treated as int.
switch
(
Type
.
GetTypeCode
(
dataType
))
{
case
TypeCode
.
Byte
:
case
TypeCode
.
SByte
:
case
TypeCode
.
Int16
:
case
TypeCode
.
UInt16
:
dataType
=
typeof
(
int
);
break
;
}
goto
Again
;
}
// Everything else is marshaled as a string.
// ETW strings are NULL-terminated, so marshal everything up to the first
// null in the string.
if
(
dataPointer
==
IntPtr
.
Zero
)
{
return
null
;
case
TypeCode
.
Byte
:
case
TypeCode
.
SByte
:
case
TypeCode
.
Int16
:
case
TypeCode
.
UInt16
:
dataType
=
typeof
(
int
);
break
;
}
return
new
string
((
char
*)
dataPointer
);
goto
Again
;
}
finally
// Everything else is marshaled as a string.
// ETW strings are NULL-terminated, so marshal everything up to the first
// null in the string.
if
(
dataPointer
==
IntPtr
.
Zero
)
{
m_EventSourceInDecodeObject
=
false
;
return
null
;
}
return
new
string
((
char
*)
dataPointer
);
}
}
...
...
@@ -2039,35 +2021,31 @@ private void LogEventArgsMismatches(int eventId, object?[] args)
private
unsafe
void
WriteToAllListeners
(
int
eventId
,
Guid
*
activityID
,
Guid
*
childActivityID
,
int
eventDataCount
,
EventSource
.
EventData
*
data
)
{
Debug
.
Assert
(
m_eventData
!=
null
);
// We represent a byte[] as a integer denoting the length and then a blob of bytes in the data pointer. This causes a spurious
// warning because eventDataCount is off by one for the byte[] case since a byte[] has 2 items associated it. So we want to check
// that the number of parameters is correct against the byte[] case, but also we the args array would be one too long if
// we just used the modifiedParamCount here -- so we need both.
int
paramCount
=
GetParameterCount
(
m_eventData
[
eventId
]);
int
modifiedParamCount
=
0
;
for
(
int
i
=
0
;
i
<
paramCount
;
i
++)
ref
EventMetadata
metadata
=
ref
m_eventData
[
eventId
];
if
(
eventDataCount
!=
metadata
.
EventListenerParameterCount
)
{
Type
parameterType
=
GetDataType
(
m_eventData
[
eventId
],
i
);
if
(
parameterType
==
typeof
(
byte
[]))
{
modifiedParamCount
+=
2
;
}
else
{
modifiedParamCount
++;
}
ReportOutOfBandMessage
(
SR
.
Format
(
SR
.
EventSource_EventParametersMismatch
,
eventId
,
eventDataCount
,
metadata
.
Parameters
.
Length
));
}
if
(
eventDataCount
!=
modifiedParamCount
)
object
?[]?
args
;
if
(
eventDataCount
==
0
)
{
ReportOutOfBandMessage
(
SR
.
Format
(
SR
.
EventSource_EventParametersMismatch
,
eventId
,
eventDataCount
,
paramCount
));
paramCount
=
Math
.
Min
(
paramCount
,
eventDataCount
);
args
=
Array
.
Empty
<
object
>();
}
else
{
ParameterInfo
[]
parameters
=
metadata
.
Parameters
;
args
=
new
object
[
Math
.
Min
(
eventDataCount
,
parameters
.
Length
)];
EventSource
.
EventData
*
dataPtr
=
data
;
for
(
int
i
=
0
;
i
<
args
.
Length
;
i
++)
{
args
[
i
]
=
DecodeObject
(
parameters
[
i
].
ParameterType
,
ref
dataPtr
);
}
}
object
?[]
args
=
new
object
[
paramCount
];
EventSource
.
EventData
*
dataPtr
=
data
;
for
(
int
i
=
0
;
i
<
paramCount
;
i
++)
args
[
i
]
=
DecodeObject
(
eventId
,
i
,
ref
dataPtr
);
WriteToAllListeners
(
eventId
:
eventId
,
osThreadId
:
null
,
...
...
@@ -2078,7 +2056,7 @@ private unsafe void WriteToAllListeners(int eventId, Guid* activityID, Guid* chi
}
// helper for writing to all EventListeners attached the current eventSource.
internal
unsafe
void
WriteToAllListeners
(
int
eventId
,
uint
*
osThreadId
,
DateTime
*
timeStamp
,
Guid
*
activityID
,
Guid
*
childActivityID
,
params
object
?[]
args
)
internal
unsafe
void
WriteToAllListeners
(
int
eventId
,
uint
*
osThreadId
,
DateTime
*
timeStamp
,
Guid
*
activityID
,
Guid
*
childActivityID
,
object
?[]
args
)
{
EventWrittenEventArgs
eventCallbackArgs
=
new
EventWrittenEventArgs
(
this
);
eventCallbackArgs
.
EventId
=
eventId
;
...
...
@@ -2091,10 +2069,7 @@ internal unsafe void WriteToAllListeners(int eventId, uint* osThreadId, DateTime
if
(
childActivityID
!=
null
)
eventCallbackArgs
.
RelatedActivityId
=
*
childActivityID
;
Debug
.
Assert
(
m_eventData
!=
null
);
eventCallbackArgs
.
EventName
=
m_eventData
[
eventId
].
Name
;
eventCallbackArgs
.
Message
=
m_eventData
[
eventId
].
Message
;
eventCallbackArgs
.
Payload
=
new
ReadOnlyCollection
<
object
?>(
args
);
eventCallbackArgs
.
Payload
=
args
.
Length
==
0
?
EventWrittenEventArgs
.
EmptyPayload
:
new
ReadOnlyCollection
<
object
?>(
args
);
DispatchToAllListeners
(
eventId
,
eventCallbackArgs
);
}
...
...
@@ -2452,23 +2427,12 @@ internal partial struct EventMetadata
public
string
Name
;
// the name of the event
public
string
?
Message
;
// If the event has a message associated with it, this is it.
public
ParameterInfo
[]
Parameters
;
// TODO can we remove?
public
int
EventListenerParameterCount
;
public
TraceLoggingEventTypes
?
TraceLoggingEventTypes
;
public
EventActivityOptions
ActivityOptions
;
}
private
static
int
GetParameterCount
(
EventMetadata
eventData
)
{
return
eventData
.
Parameters
.
Length
;
}
private
static
Type
GetDataType
(
EventMetadata
eventData
,
int
parameterId
)
{
return
eventData
.
Parameters
[
parameterId
].
ParameterType
;
}
private
const
bool
m_EventSourcePreventRecursion
=
false
;
// This is the internal entry point that code:EventListeners call when wanting to send a command to a
// eventSource. The logic is as follows
//
...
...
@@ -3446,6 +3410,19 @@ private static void AddProviderEnumKind(ManifestBuilder manifest, FieldInfo stat
eventData
[
eventAttribute
.
EventId
].
ActivityOptions
=
eventAttribute
.
ActivityOptions
;
eventData
[
eventAttribute
.
EventId
].
HasRelatedActivityID
=
hasRelatedActivityID
;
eventData
[
eventAttribute
.
EventId
].
EventHandle
=
IntPtr
.
Zero
;
// We represent a byte[] with 2 EventData entries: an integer denoting the length and a blob of bytes in the data pointer.
// This causes a spurious warning because eventDataCount is off by one for the byte[] case.
// When writing to EventListeners, we want to check that the number of parameters is correct against the byte[] case.
int
eventListenerParameterCount
=
eventParameters
.
Length
;
foreach
(
ParameterInfo
parameter
in
eventParameters
)
{
if
(
parameter
.
ParameterType
==
typeof
(
byte
[]))
{
eventListenerParameterCount
++;
}
}
eventData
[
eventAttribute
.
EventId
].
EventListenerParameterCount
=
eventListenerParameterCount
;
}
// Helper used by code:CreateManifestAndDescriptors that trims the m_eventData array to the correct
...
...
@@ -3792,9 +3769,6 @@ private bool SelfDescribingEvents
[
ThreadStatic
]
private
static
byte
m_EventSourceExceptionRecurenceCount
;
// current recursion count inside ThrowEventSourceException
[
ThreadStatic
]
private
static
bool
m_EventSourceInDecodeObject
;
#if FEATURE_MANAGED_ETW_CHANNELS
internal
volatile
ulong
[]?
m_channelData
;
#endif
...
...
@@ -4533,6 +4507,8 @@ public class EventSourceCreatedEventArgs : EventArgs
/// </summary>
public
class
EventWrittenEventArgs
:
EventArgs
{
internal
static
readonly
ReadOnlyCollection
<
object
?>
EmptyPayload
=
new
(
Array
.
Empty
<
object
>());
/// <summary>
/// The name of the event.
/// </summary>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录