-
Notifications
You must be signed in to change notification settings - Fork 5k
Expose setting CPU SamplingProfiler rate #83635
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
f67de95
0120edd
389516c
b160fe5
6b3a71c
ad342f8
5f5f1fb
54d83a0
40450b5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,17 @@ static | |
void | ||
sample_profiler_enable (void); | ||
|
||
static | ||
void | ||
ep_sample_event_pipe_callback( | ||
const uint8_t* source_id, | ||
unsigned long is_enabled, | ||
uint8_t level, | ||
uint64_t match_any_keywords, | ||
uint64_t match_all_keywords, | ||
EventFilterDescriptor* filter_data, | ||
void* callback_data); | ||
|
||
/* | ||
* EventPipeSampleProfiler. | ||
*/ | ||
|
@@ -205,13 +216,44 @@ sample_profiler_enable (void) | |
} | ||
} | ||
|
||
static | ||
void | ||
ep_sample_event_pipe_callback( | ||
const uint8_t* source_id, | ||
unsigned long is_enabled, | ||
uint8_t level, | ||
uint64_t match_any_keywords, | ||
uint64_t match_all_keywords, | ||
EventFilterDescriptor* filter_data, | ||
void* callback_data) | ||
{ | ||
if (filter_data) { | ||
ep_char8_t *filter_data_char = (ep_char8_t *)((uintptr_t)(filter_data->ptr)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do I read that this is implemented as filter data that is passed to the provider? If so, I have a bit of a concern around how to de-duplicate requests when there are multiple sessions. Right now, this is a single value. If we are going to allow this to be specified on provider enable, we should probably have some behavior that de-conflicts requests. I'm not sure if that means taking the most frequent rate of all session requests, or something else. Another option is to consider having an API outside of enablement that sets this, at which point it can remain a global, and that is expressed at the API level. |
||
const uint32_t filter_data_size = filter_data->size; | ||
ep_char8_t *candidateKey = NULL; | ||
size_t offset = 0; | ||
const ep_char8_t *sampleProfilerIntervalMSKey = "SampleProfilerIntervalMS"; | ||
|
||
while (offset < filter_data_size) { | ||
candidateKey = filter_data_char + offset; | ||
if (strcmp(candidateKey, sampleProfilerIntervalMSKey) == 0) { | ||
ep_sample_profiler_set_sampling_rate(strtoull(candidateKey + 25, NULL, 10) * 1000000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should check that strtoull returns a value greater than 0. If someone passes in a bad value that cannot be parsed it would return 0 and the sample thread would sample continuously and busy lock the app. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably even add logic to make sure the value falls within some accepted limits, so maybe a value between 1000 samples/second (current default and not sure we want to go lower than that with current sampling solution) and some lower limit that makes sense. You might want to sample quite infrequently in some cases, so not sure what the lower limit could be, so maybe we should just cap it at some sane value, like 1 sample/second, since its still a sample profiler that you configure. If you would like to get even more infrequent samples, then maybe it should be handled by a custom provider and not the sample profiler. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed that keeping a sane range is a good idea. For example, ETW will not allow you to sample any more than every 0.125 seconds if I recall correctly. I'm not super concerned about the other side of the range because there isn't a risk of affecting the availability of the app - there is a risk of not getting data. I think it's probably safe to allow any large value, though at a certain point it doesn't really provide much value for the scenarios that we are currently tracking. |
||
break; | ||
} | ||
else { | ||
offset += strlen(candidateKey) + 1; | ||
} | ||
} | ||
} | ||
} | ||
|
||
void | ||
ep_sample_profiler_init (EventPipeProviderCallbackDataQueue *provider_callback_data_queue) | ||
{ | ||
ep_requires_lock_held (); | ||
|
||
if (!_sampling_provider) { | ||
_sampling_provider = provider_create_register (ep_config_get_sample_profiler_provider_name_utf8 (), NULL, NULL, provider_callback_data_queue); | ||
_sampling_provider = provider_create_register (ep_config_get_sample_profiler_provider_name_utf8 (), ep_sample_event_pipe_callback, NULL, provider_callback_data_queue); | ||
ep_raise_error_if_nok (_sampling_provider != NULL); | ||
_thread_time_event = provider_add_event ( | ||
_sampling_provider, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate prototype isn't needed.