Add SysStats data source (/proc/{meminfo,stat,vmstat})

Adds a new data source for polling /proc counters.
The polling rate and the counters can be individually
set in the trace config.

The cost (CPU time) of polling and parsing these files,
measured on a Pixel 2, running on little core, is:
- /proc/meminfo: 0.3 ms [read] + 0.07 ms [parse + trace injection]
- /proc/vmstat:  0.2 ms [read] + 0.3 ms [parse + trace injection]
- /proc/stat:    4.1 ms [read] + 1.9 ms [parse + trace injection]

SELinux: aosp/759260
Bug: b/115956288
Test: perfetto_unittests --gtest_filter=SysStatsDataSourceTest.*

Change-Id: I2805f713d418ba6bda9550f11bfce137b378bc1b
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index e56eb73..cc90242 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -50,6 +50,7 @@
 constexpr char kFtraceSourceName[] = "linux.ftrace";
 constexpr char kProcessStatsSourceName[] = "linux.process_stats";
 constexpr char kInodeMapSourceName[] = "linux.inode_file_map";
+constexpr char kSysStatsSourceName[] = "linux.sys_stats";
 
 }  // namespace.
 
@@ -74,17 +75,29 @@
   ResetConnectionBackoff();
   PERFETTO_LOG("Connected to the service");
 
-  DataSourceDescriptor ftrace_descriptor;
-  ftrace_descriptor.set_name(kFtraceSourceName);
-  endpoint_->RegisterDataSource(ftrace_descriptor);
+  {
+    DataSourceDescriptor desc;
+    desc.set_name(kFtraceSourceName);
+    endpoint_->RegisterDataSource(desc);
+  }
 
-  DataSourceDescriptor process_stats_descriptor;
-  process_stats_descriptor.set_name(kProcessStatsSourceName);
-  endpoint_->RegisterDataSource(process_stats_descriptor);
+  {
+    DataSourceDescriptor desc;
+    desc.set_name(kProcessStatsSourceName);
+    endpoint_->RegisterDataSource(desc);
+  }
 
-  DataSourceDescriptor inode_map_descriptor;
-  inode_map_descriptor.set_name(kInodeMapSourceName);
-  endpoint_->RegisterDataSource(inode_map_descriptor);
+  {
+    DataSourceDescriptor desc;
+    desc.set_name(kInodeMapSourceName);
+    endpoint_->RegisterDataSource(desc);
+  }
+
+  {
+    DataSourceDescriptor desc;
+    desc.set_name(kSysStatsSourceName);
+    endpoint_->RegisterDataSource(desc);
+  }
 }
 
 void ProbesProducer::OnDisconnect() {
@@ -129,6 +142,8 @@
     data_source = CreateInodeFileDataSource(session_id, instance_id, config);
   } else if (config.name() == kProcessStatsSourceName) {
     data_source = CreateProcessStatsDataSource(session_id, instance_id, config);
+  } else if (config.name() == kSysStatsSourceName) {
+    data_source = CreateSysStatsDataSource(session_id, instance_id, config);
   }
 
   if (!data_source) {
@@ -214,6 +229,18 @@
   return std::move(data_source);
 }
 
+std::unique_ptr<SysStatsDataSource> ProbesProducer::CreateSysStatsDataSource(
+    TracingSessionID session_id,
+    DataSourceInstanceID id,
+    const DataSourceConfig& config) {
+  base::ignore_result(id);
+  auto buffer_id = static_cast<BufferID>(config.target_buffer());
+  auto data_source = std::unique_ptr<SysStatsDataSource>(
+      new SysStatsDataSource(task_runner_, session_id,
+                             endpoint_->CreateTraceWriter(buffer_id), config));
+  return data_source;
+}
+
 void ProbesProducer::TearDownDataSourceInstance(DataSourceInstanceID id) {
   PERFETTO_LOG("Producer stop (id=%" PRIu64 ")", id);
   auto it = data_sources_.find(id);
@@ -290,6 +317,8 @@
       case ProcessStatsDataSource::kTypeId:
         ps_data_source = static_cast<ProcessStatsDataSource*>(ds);
         break;
+      case SysStatsDataSource::kTypeId:
+        break;
       default:
         PERFETTO_DCHECK(false);
     }  // switch (type_id)