Add Mono EventPipe Sample Profiler support. (#47858)
authorJohan Lorensson <lateralusx.github@gmail.com>
Fri, 12 Feb 2021 14:20:46 +0000 (15:20 +0100)
committerGitHub <noreply@github.com>
Fri, 12 Feb 2021 14:20:46 +0000 (15:20 +0100)
commit86835b839ca255c6c157beebda665f562e4def26
treee096b6dcbdabcc29f2e856fc7f09611b5174fae4
parentfb41bd645b5dc162159caa5d259e766e08a3a341
Add Mono EventPipe Sample Profiler support. (#47858)

Implement support for EventPipe Sample Profiler on Mono inline with CoreClr Sample Profiler behaviour. By default CoreClr sample profiler tries to run at 1000 hertz (every ms) and on each sample it will stop runtime, snap callstacks for all managed threads, submit EventPipe sample profile events and resume runtime. Doing a full stop/restart of the runtime on every sample could be quite invasive, but is probably the most portable way of implementing it working on most platforms.

This PR implements the same logic, but on Mono runtime, stopping the runtime, record all callstacks for all managed threads that should be sampled, restart runtime and then write all sample profile events into EventPipe. Note that events are written after the runtime has resumed since all code executed when runtime is stopped needs to be async safe (needed when running in preemptive mode) so we can't call into EventPipe at that point.

Going forward we should investigate alternative ways to do sample profiling depending on underlying platform and OS support. Currently implementation will work on all supported platforms, but it will not be as accurate as it could be (especially when using safe points and coop enabled runtime) and impacts measured target. Mono's profiler uses Signals/SuspendThread and for platforms supporting these API's, that could be an alternative implementation. It could also be worth to look into CPU hardware counters using ETW kernel log session on Windows and perf_event_open on Linux.
src/mono/mono/eventpipe/ep-rt-mono.h
src/mono/mono/metadata/boehm-gc.c
src/mono/mono/metadata/gc-internals.h
src/mono/mono/metadata/icall-eventpipe.c
src/mono/mono/metadata/mono-gc.h
src/mono/mono/metadata/null-gc.c
src/mono/mono/metadata/sgen-mono.c
src/mono/mono/metadata/sgen-stw.c
src/mono/mono/mini/interp/interp.c