Improve metatrace, allow to be used in production

Before this CL meta-tracing was based on serializing
events on the fly as JSON and writing them on a file.
This had a number of disadvantages: (1) perf, string
manipulation + write() isn't really nice on fast-paths;
(2) interoperaability: it required an env var and
required loading a separate json file.

This CL improves meta-tracing as follows:
1. Events are stored in a statically allocated
  (.rwdata) ring-buffer in a very efficient way
  using 16 bytes per event.
2. They are serialized into protos asynchronously.
3. They can be injected into the real trace, exposed
   as a data source.

Meta-tracing is organized into three layers:
1. The core base class: it only holds event records in a
   ring-buffer and does NOT deal with serialization.
   This allows any part of the codebase to use
   meta-tracing, even base/ if we'll need it in future.
2. A MetatraceWriter class that is able to write event
   records into the trace using a TraceWriter.
3. a MetatraceDataSource: hooks it up to traced-probes.

The split between 2 and 3 is to allow other components
(e.g. Chrome, heapprofd) to take advantage of meta-tracing
outside of traced_probes.

Bug: 133312949
Test: perfetto_unittests --gtest_filter=Metatrace*

Change-Id: Ife1390e599e8c2ca3f4e1039e73398619dbd1af6
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 9e4596c..a8237b5 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -36,6 +36,7 @@
 #include "src/traced/probes/filesystem/inode_file_data_source.h"
 #include "src/traced/probes/ftrace/ftrace_config.h"
 #include "src/traced/probes/ftrace/ftrace_data_source.h"
+#include "src/traced/probes/metatrace/metatrace_data_source.h"
 #include "src/traced/probes/packages_list/packages_list_data_source.h"
 #include "src/traced/probes/power/android_power_data_source.h"
 #include "src/traced/probes/probes_data_source.h"
@@ -129,6 +130,12 @@
     desc.set_name(kPackagesListSourceName);
     endpoint_->RegisterDataSource(desc);
   }
+
+  {
+    DataSourceDescriptor desc;
+    desc.set_name(MetatraceDataSource::kDataSourceName);
+    endpoint_->RegisterDataSource(desc);
+  }
 }
 
 void ProbesProducer::OnDisconnect() {
@@ -183,6 +190,8 @@
     data_source = CreateAndroidLogDataSource(session_id, config);
   } else if (config.name() == kPackagesListSourceName) {
     data_source = CreatePackagesListDataSource(session_id, config);
+  } else if (config.name() == MetatraceDataSource::kDataSourceName) {
+    data_source = CreateMetatraceDataSource(session_id, config);
   }
 
   if (!data_source) {
@@ -312,6 +321,14 @@
                              endpoint_->CreateTraceWriter(buffer_id), config));
 }
 
+std::unique_ptr<ProbesDataSource> ProbesProducer::CreateMetatraceDataSource(
+    TracingSessionID session_id,
+    const DataSourceConfig& config) {
+  auto buffer_id = static_cast<BufferID>(config.target_buffer());
+  return std::unique_ptr<ProbesDataSource>(new MetatraceDataSource(
+      task_runner_, session_id, endpoint_->CreateTraceWriter(buffer_id)));
+}
+
 void ProbesProducer::StopDataSource(DataSourceInstanceID id) {
   PERFETTO_LOG("Producer stop (id=%" PRIu64 ")", id);
   auto it = data_sources_.find(id);
@@ -472,6 +489,7 @@
       case SysStatsDataSource::kTypeId:
       case AndroidLogDataSource::kTypeId:
       case PackagesListDataSource::kTypeId:
+      case MetatraceDataSource::kTypeId:
         break;
       default:
         PERFETTO_DFATAL("Invalid data source.");