trace_processor: Add parsing and storing of cpu_frequency events.

The cpu_freq events are now parsed and stored. The number of cycles for
each slice is calculated as the slices are stored.

Adding a cpu frequency table will be done in a separate CL.

Bug:111252261
Change-Id: I59ab410417d264a3aa988c1df4ebb11a1e56e0fe
diff --git a/src/trace_processor/proto_trace_parser.cc b/src/trace_processor/proto_trace_parser.cc
index 562423e..b3d3dda 100644
--- a/src/trace_processor/proto_trace_parser.cc
+++ b/src/trace_processor/proto_trace_parser.cc
@@ -134,6 +134,12 @@
         ParseSchedSwitch(cpu, timestamp, ftrace.slice(fld_off, fld.size()));
         break;
       }
+      case protos::FtraceEvent::kCpuFrequency: {
+        PERFETTO_DCHECK(timestamp > 0);
+        const size_t fld_off = ftrace.offset_of(fld.data());
+        ParseCpuFreq(timestamp, ftrace.slice(fld_off, fld.size()));
+        break;
+      }
       default:
         break;
     }
@@ -141,6 +147,27 @@
   PERFETTO_DCHECK(decoder.IsEndOfBuffer());
 }
 
+void ProtoTraceParser::ParseCpuFreq(uint64_t timestamp, TraceBlobView view) {
+  ProtoDecoder decoder(view.data(), view.length());
+
+  uint32_t cpu = 0;
+  uint32_t new_freq = 0;
+  for (auto fld = decoder.ReadField(); fld.id != 0; fld = decoder.ReadField()) {
+    switch (fld.id) {
+      case protos::CpuFrequencyFtraceEvent::kCpuIdFieldNumber:
+        cpu = fld.as_uint32();
+        break;
+      case protos::CpuFrequencyFtraceEvent::kStateFieldNumber:
+        new_freq = fld.as_uint32();
+        break;
+    }
+  }
+
+  context_->storage->PushCpuFreq(timestamp, cpu, new_freq);
+
+  PERFETTO_DCHECK(decoder.IsEndOfBuffer());
+}
+
 void ProtoTraceParser::ParseSchedSwitch(uint32_t cpu,
                                         uint64_t timestamp,
                                         TraceBlobView sswitch) {