Skip to content

Commit aef6cc3

Browse files
committed
[EventPipe][UserEvents] Deduplicate Event metadata emission
1 parent 6bb8930 commit aef6cc3

File tree

4 files changed

+70
-22
lines changed

4 files changed

+70
-22
lines changed

src/native/eventpipe/ep-event.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ ep_event_alloc (
7272
instance->level = level;
7373
instance->need_stack = need_stack;
7474
instance->enabled_mask = 0;
75+
instance->metadata_written_mask = 0;
7576

7677
if (metadata != NULL) {
7778
instance->metadata = ep_rt_byte_array_alloc (metadata_len);
@@ -102,6 +103,30 @@ ep_event_free (EventPipeEvent *ep_event)
102103
ep_rt_object_free (ep_event);
103104
}
104105

106+
bool
107+
ep_event_update_metadata_written_mask (
108+
EventPipeEvent *ep_event,
109+
uint64_t session_mask,
110+
bool enable)
111+
{
112+
EP_ASSERT (ep_event != NULL);
113+
EP_ASSERT (session_mask != 0);
114+
115+
int64_t expected_value;
116+
int64_t previous_value;
117+
118+
do {
119+
expected_value = ep_rt_volatile_load_int64_t (&ep_event->metadata_written_mask);
120+
if (((expected_value & session_mask) != 0) == enable)
121+
return false; // Already set to the desired state.
122+
123+
int64_t new_value = enable ? (expected_value | session_mask) : (expected_value & ~session_mask);
124+
previous_value = ep_rt_atomic_compare_exchange_int64_t (&ep_event->metadata_written_mask, expected_value, new_value);
125+
} while (previous_value != expected_value);
126+
127+
return true;
128+
}
129+
105130
#endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */
106131
#endif /* ENABLE_PERFTRACING */
107132

src/native/eventpipe/ep-event.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ struct _EventPipeEvent_Internal {
2626
uint64_t keywords;
2727
// The ith bit is 1 iff the event is enabled for the ith session.
2828
volatile int64_t enabled_mask;
29+
// The ith bit is 1 iff the event metadata has been written for the ith session.
30+
volatile int64_t metadata_written_mask;
2931
// Metadata
3032
uint8_t *metadata;
3133
// The provider that contains the event.
@@ -92,5 +94,11 @@ ep_event_alloc (
9294
void
9395
ep_event_free (EventPipeEvent * ep_event);
9496

97+
bool
98+
ep_event_update_metadata_written_mask (
99+
EventPipeEvent *ep_event,
100+
uint64_t session_mask,
101+
bool enable);
102+
95103
#endif /* ENABLE_PERFTRACING */
96104
#endif /* __EVENTPIPE_EVENT_H__ */

src/native/eventpipe/ep-provider.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,16 @@ provider_prepare_callback_data (
3535
// _Requires_lock_held (ep)
3636
static
3737
void
38-
provider_refresh_all_events (EventPipeProvider *provider);
38+
provider_refresh_all_events (
39+
EventPipeProvider *provider,
40+
uint64_t session_mask);
3941

4042
// _Requires_lock_held (ep)
4143
static
4244
void
43-
provider_refresh_event_state (EventPipeEvent *ep_event);
45+
provider_refresh_event_state (
46+
EventPipeEvent *ep_event,
47+
uint64_t session_mask);
4448

4549
// Compute the enabled bit mask, the ith bit is 1 iff an event with the
4650
// given (provider, keywords, eventLevel) is enabled for the ith session.
@@ -96,7 +100,9 @@ provider_prepare_callback_data (
96100

97101
static
98102
void
99-
provider_refresh_all_events (EventPipeProvider *provider)
103+
provider_refresh_all_events (
104+
EventPipeProvider *provider,
105+
uint64_t session_mask)
100106
{
101107
EP_ASSERT (provider != NULL);
102108

@@ -105,7 +111,7 @@ provider_refresh_all_events (EventPipeProvider *provider)
105111
EP_ASSERT (provider->event_list != NULL);
106112

107113
DN_LIST_FOREACH_BEGIN (EventPipeEvent *, current_event, provider->event_list) {
108-
provider_refresh_event_state (current_event);
114+
provider_refresh_event_state (current_event, session_mask);
109115
} DN_LIST_FOREACH_END;
110116

111117
ep_requires_lock_held ();
@@ -114,7 +120,9 @@ provider_refresh_all_events (EventPipeProvider *provider)
114120

115121
static
116122
void
117-
provider_refresh_event_state (EventPipeEvent *ep_event)
123+
provider_refresh_event_state (
124+
EventPipeEvent *ep_event,
125+
uint64_t session_mask)
118126
{
119127
EP_ASSERT (ep_event != NULL);
120128

@@ -129,6 +137,11 @@ provider_refresh_event_state (EventPipeEvent *ep_event)
129137
int64_t enable_mask = provider_compute_event_enable_mask (config, provider, ep_event);
130138
ep_event_set_enabled_mask (ep_event, enable_mask);
131139

140+
// If session_mask is not zero, that session is being enabled/disabled.
141+
// We need to unset the metadata_written_mask for this session.
142+
if (session_mask != 0)
143+
ep_event_update_metadata_written_mask (ep_event, session_mask, false);
144+
132145
ep_requires_lock_held ();
133146
return;
134147
}
@@ -277,7 +290,7 @@ ep_provider_add_event (
277290
// Take the config lock before inserting a new event.
278291
EP_LOCK_ENTER (section1)
279292
ep_raise_error_if_nok_holding_lock (dn_list_push_back (provider->event_list, instance), section1);
280-
provider_refresh_event_state (instance);
293+
provider_refresh_event_state (instance, 0);
281294
EP_LOCK_EXIT (section1)
282295

283296
ep_on_exit:
@@ -323,7 +336,7 @@ provider_set_config (
323336
provider->keywords = keywords_for_all_sessions;
324337
provider->provider_level = level_for_all_sessions;
325338

326-
provider_refresh_all_events (provider);
339+
provider_refresh_all_events (provider, session_mask);
327340
provider_prepare_callback_data (provider, provider->keywords, provider->provider_level, filter_data, callback_data, session_id);
328341

329342
ep_requires_lock_held ();
@@ -352,7 +365,7 @@ provider_unset_config (
352365
provider->keywords = keywords_for_all_sessions;
353366
provider->provider_level = level_for_all_sessions;
354367

355-
provider_refresh_all_events (provider);
368+
provider_refresh_all_events (provider, session_mask);
356369
provider_prepare_callback_data (provider, provider->keywords, provider->provider_level, filter_data, callback_data, (EventPipeSessionID)0);
357370

358371
ep_requires_lock_held ();
@@ -517,7 +530,7 @@ provider_add_event (
517530
ep_raise_error_if_nok (instance != NULL);
518531

519532
ep_raise_error_if_nok (dn_list_push_back (provider->event_list, instance));
520-
provider_refresh_event_state (instance);
533+
provider_refresh_event_state (instance, 0);
521534

522535
ep_on_exit:
523536
ep_requires_lock_held ();

src/native/eventpipe/ep-session.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -815,20 +815,22 @@ session_tracepoint_write_event (
815815
// Extension
816816
uint32_t extension_len = 0;
817817

818-
// Extension Event Metadata
819-
uint32_t metadata_len = ep_event_get_metadata_len (ep_event);
820-
uint8_t extension_metadata[1 + sizeof(uint32_t)];
821-
extension_metadata[0] = 0x01; // label
822-
*(uint32_t*)&extension_metadata[1] = metadata_len;
823-
io[io_index].iov_base = extension_metadata;
824-
io[io_index].iov_len = sizeof(extension_metadata);
825-
io_index++;
826-
extension_len += sizeof(extension_metadata);
818+
bool should_write_metadata = ep_event_update_metadata_written_mask (ep_event, ep_session_get_mask (session), true);
819+
if (should_write_metadata) {
820+
uint8_t extension_metadata[1 + sizeof(uint32_t)];
821+
uint32_t metadata_len = ep_event_get_metadata_len (ep_event);
822+
extension_metadata[0] = 0x01; // label
823+
*(uint32_t*)&extension_metadata[1] = metadata_len;
824+
io[io_index].iov_base = extension_metadata;
825+
io[io_index].iov_len = sizeof(extension_metadata);
826+
io_index++;
827+
extension_len += sizeof(extension_metadata);
827828

828-
io[io_index].iov_base = (void *)ep_event_get_metadata (ep_event);
829-
io[io_index].iov_len = metadata_len;
830-
io_index++;
831-
extension_len += metadata_len;
829+
io[io_index].iov_base = (void *)ep_event_get_metadata (ep_event);
830+
io[io_index].iov_len = metadata_len;
831+
io_index++;
832+
extension_len += metadata_len;
833+
}
832834

833835
// Extension Activity IDs
834836
const int extension_activity_ids_max_len = 2 * (1 + EP_ACTIVITY_ID_SIZE);

0 commit comments

Comments
 (0)