allow for heapprofd's signal to be multiplexed

This patch refactors heapprofd_malloc to make it easier to reuse the
reserved signal for multiple purposes. We define a new generic signal
handler for profilers, which dispatches to more specific logic based on
the signal's payload (si_value).

The profiler signal handler is installed during libc preinit, after
malloc initialization (so races against synchronous heapprofd
initialization need not be considered). In terms of code organization, I
copied the existing approach with a loosely referenced function in
bionic_globals.h. Do tell if you'd rather a different approach here.

The profileability of a process is quite tied to the malloc
files/interfaces in bionic - in particular, it's set through
android_mallopt. I do not change that, but instead introduce a new
android_mallopt option to be able to query profileability of the
process (which is now used by the new profiler signal handler). As part
of that, gZygoteChildProfileable is moved from heapprofd_malloc to
common (alongside gZygoteChild).

I've removed the masking and reraising of the heapprofd signal when
racing against malloc_limit init. We're ok with taking a simpler
approach and dropping the heapprofd signal in such an unlikely race.

Note: this requires a corresponding change in heapprofd to use sigqueue()
instead of kill(), as the latter leaves the si_value uninitialized(?) on
the receiving side.

Bug: 144281346
Change-Id: I93bb2e82cff5870e5ca499cf86439860aca9dfa5
diff --git a/libc/bionic/malloc_limit.cpp b/libc/bionic/malloc_limit.cpp
index d8c0ebe..ebc33ab 100644
--- a/libc/bionic/malloc_limit.cpp
+++ b/libc/bionic/malloc_limit.cpp
@@ -264,7 +264,6 @@
 }
 #else
 static bool EnableLimitDispatchTable() {
-  HeapprofdMaskSignal();
   pthread_mutex_lock(&gGlobalsMutateLock);
   // All other code that calls mutate will grab the gGlobalsMutateLock.
   // However, there is one case where the lock cannot be acquired, in the
@@ -272,7 +271,7 @@
   // threads calling mutate at the same time, use an atomic variable to
   // verify that only this function or the signal handler are calling mutate.
   // If this function is called at the same time as the signal handler is
-  // being called, allow up to five ms for the signal handler to complete
+  // being called, allow a short period for the signal handler to complete
   // before failing.
   bool enabled = false;
   size_t num_tries = 20;
@@ -291,7 +290,6 @@
     usleep(1000);
   }
   pthread_mutex_unlock(&gGlobalsMutateLock);
-  HeapprofdUnmaskSignal();
   if (enabled) {
     info_log("malloc_limit: Allocation limit enabled, max size %" PRId64 " bytes\n", gAllocLimit);
   } else {