Merge pull request #2805 from alexrp/profiler-sampling-thread2
authormonojenkins <jo.shields+jenkins@xamarin.com>
Fri, 1 Apr 2016 07:00:18 +0000 (08:00 +0100)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Fri, 1 Apr 2016 07:00:18 +0000 (08:00 +0100)
commita7fb596803dad69b8c371e581203b66425656f28
tree6e3020828f09e8b828abef062200be4342500397
parent01aa70d6514d4abcec93e0ced6c09ba9e61a9589
parent2538a352f4ff2bb2636491aa1bb82ce4d03ab80f
Merge pull request #2805 from alexrp/profiler-sampling-thread2

[profiler] Use a background thread to send out sampling signals.

Previously, when using an interval timer, the initial profiling signal could be
delivered to *any* thread in the process. This is not normally a problem, but
if the signaled thread has not even finished its initialization inside libc, it
can happen that it hasn't even set up thread-local storage yet. We then blow up
spectacularly when trying to back up errno in the SIGPROF signal handler, as
it's a TLS variable. Even the SIGSEGV handler blows up immediately after as it
can't access JIT TLS data.

Since there appears to be no reliable and portable way for a library like Mono
to control which exact thread gets the initial timer signal, instead switch to
using a background thread that uses a high-resolution sleep and attempts to
switch itself to real time scheduling if possible. This way, we have full
control over which threads we send SIGPROF to, letting us avoid any threads
which aren't in a 'good' state for profiling.

This commit also gets rid of the multiplexing that was going on in the SIGPROF
signal handler, since we now send out the signals from a background thread. As
this was the only use of the async job API, that API has been removed. This
indirectly fixes the signal storming issue that sometimes popped up, where for
some reason multiple threads would think that they're the initiating thread,
resulting in way too many signals going out.

A nice side-effect of doing the signaling ourselves is that we can now use
real-time signals on systems that have them (e.g. Linux), resulting in a nearly
100% signal delivery rate in all cases. Previously, we would lose a tremendous
amount of signals when an application was under heavy load.