Merge "Test: remove TreeHuggerOnly run e2e tests also on CI emulator"
diff --git a/Android.bp b/Android.bp
index 1fad0af..1fb9914 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3679,6 +3679,7 @@
         "protos/perfetto/metrics/android/hwcomposer.proto",
         "protos/perfetto/metrics/android/hwui_metric.proto",
         "protos/perfetto/metrics/android/ion_metric.proto",
+        "protos/perfetto/metrics/android/irq_runtime_metric.proto",
         "protos/perfetto/metrics/android/jank_metric.proto",
         "protos/perfetto/metrics/android/java_heap_histogram.proto",
         "protos/perfetto/metrics/android/java_heap_stats.proto",
@@ -3739,6 +3740,7 @@
         "protos/perfetto/metrics/android/hwcomposer.proto",
         "protos/perfetto/metrics/android/hwui_metric.proto",
         "protos/perfetto/metrics/android/ion_metric.proto",
+        "protos/perfetto/metrics/android/irq_runtime_metric.proto",
         "protos/perfetto/metrics/android/jank_metric.proto",
         "protos/perfetto/metrics/android/java_heap_histogram.proto",
         "protos/perfetto/metrics/android/java_heap_stats.proto",
@@ -8085,6 +8087,7 @@
         "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
         "src/trace_processor/metrics/sql/android/android_hwui_threads.sql",
         "src/trace_processor/metrics/sql/android/android_ion.sql",
+        "src/trace_processor/metrics/sql/android/android_irq_runtime.sql",
         "src/trace_processor/metrics/sql/android/android_jank.sql",
         "src/trace_processor/metrics/sql/android/android_lmk.sql",
         "src/trace_processor/metrics/sql/android/android_lmk_reason.sql",
diff --git a/BUILD b/BUILD
index 3be7c1c..5f2820a 100644
--- a/BUILD
+++ b/BUILD
@@ -1049,6 +1049,7 @@
         "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
         "src/trace_processor/metrics/sql/android/android_hwui_threads.sql",
         "src/trace_processor/metrics/sql/android/android_ion.sql",
+        "src/trace_processor/metrics/sql/android/android_irq_runtime.sql",
         "src/trace_processor/metrics/sql/android/android_jank.sql",
         "src/trace_processor/metrics/sql/android/android_lmk.sql",
         "src/trace_processor/metrics/sql/android/android_lmk_reason.sql",
@@ -2616,6 +2617,7 @@
         "protos/perfetto/metrics/android/hwcomposer.proto",
         "protos/perfetto/metrics/android/hwui_metric.proto",
         "protos/perfetto/metrics/android/ion_metric.proto",
+        "protos/perfetto/metrics/android/irq_runtime_metric.proto",
         "protos/perfetto/metrics/android/jank_metric.proto",
         "protos/perfetto/metrics/android/java_heap_histogram.proto",
         "protos/perfetto/metrics/android/java_heap_stats.proto",
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index 3e0b2e7..4b4923b 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -33,6 +33,7 @@
     "hwcomposer.proto",
     "hwui_metric.proto",
     "ion_metric.proto",
+    "irq_runtime_metric.proto",
     "jank_metric.proto",
     "java_heap_histogram.proto",
     "java_heap_stats.proto",
diff --git a/protos/perfetto/metrics/android/irq_runtime_metric.proto b/protos/perfetto/metrics/android/irq_runtime_metric.proto
new file mode 100644
index 0000000..dd2ed51
--- /dev/null
+++ b/protos/perfetto/metrics/android/irq_runtime_metric.proto
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// measure max IRQ runtime and IRQ tasks running over threshold.
+message AndroidIrqRuntimeMetric {
+  message IrqSlice {
+    // IRQ name
+    optional string irq_name = 1;
+    // timestamp
+    optional int64 ts = 2;
+    // runtime of IRQ task
+    optional int64 dur = 3;
+  }
+  message ThresholdMetric {
+    // Threshold value
+    optional string threshold = 1;
+    // over threshold count
+    optional int64 over_threshold_count = 2;
+    // anomaly ratio (over threshold count / total count)
+    optional double anomaly_ratio= 3;
+  }
+  message IrqRuntimeMetric {
+    // max runtime of IRQ tasks
+    optional int64 max_runtime = 1;
+    // total IRQ tasks
+    optional int64 total_count = 2;
+    // over threshold metric
+    optional ThresholdMetric threshold_metric = 3;
+    // information for top 10 IRQ tasks
+    repeated IrqSlice longest_irq_slices = 4;
+  }
+
+  // metrics for hardirq and softirq
+  optional IrqRuntimeMetric hw_irq = 1;
+  optional IrqRuntimeMetric sw_irq = 2;
+}
+
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index 8b1a173..1731c8d 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -31,6 +31,7 @@
 import "protos/perfetto/metrics/android/hwcomposer.proto";
 import "protos/perfetto/metrics/android/hwui_metric.proto";
 import "protos/perfetto/metrics/android/ion_metric.proto";
+import "protos/perfetto/metrics/android/irq_runtime_metric.proto";
 import "protos/perfetto/metrics/android/jank_metric.proto";
 import "protos/perfetto/metrics/android/java_heap_histogram.proto";
 import "protos/perfetto/metrics/android/java_heap_stats.proto";
@@ -97,7 +98,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 43
+// Next id: 44
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -207,8 +208,12 @@
   // is clear that this data is necessary.
   optional AndroidCameraUnaggregatedMetric android_camera_unagg = 41;
 
+  // Metrics for RT runtime.
   optional AndroidRtRuntimeMetric android_rt_runtime = 42;
 
+  // Metrics for IRQ runtime.
+  optional AndroidIrqRuntimeMetric android_irq_runtime = 43;
+
   // Demo extensions.
   extensions 450 to 499;
 
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 7472ce3..4c4a0bc 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -545,6 +545,45 @@
 
 // End of protos/perfetto/metrics/android/ion_metric.proto
 
+// Begin of protos/perfetto/metrics/android/irq_runtime_metric.proto
+
+// measure max IRQ runtime and IRQ tasks running over threshold.
+message AndroidIrqRuntimeMetric {
+  message IrqSlice {
+    // IRQ name
+    optional string irq_name = 1;
+    // timestamp
+    optional int64 ts = 2;
+    // runtime of IRQ task
+    optional int64 dur = 3;
+  }
+  message ThresholdMetric {
+    // Threshold value
+    optional string threshold = 1;
+    // over threshold count
+    optional int64 over_threshold_count = 2;
+    // anomaly ratio (over threshold count / total count)
+    optional double anomaly_ratio= 3;
+  }
+  message IrqRuntimeMetric {
+    // max runtime of IRQ tasks
+    optional int64 max_runtime = 1;
+    // total IRQ tasks
+    optional int64 total_count = 2;
+    // over threshold metric
+    optional ThresholdMetric threshold_metric = 3;
+    // information for top 10 IRQ tasks
+    repeated IrqSlice longest_irq_slices = 4;
+  }
+
+  // metrics for hardirq and softirq
+  optional IrqRuntimeMetric hw_irq = 1;
+  optional IrqRuntimeMetric sw_irq = 2;
+}
+
+
+// End of protos/perfetto/metrics/android/irq_runtime_metric.proto
+
 // Begin of protos/perfetto/metrics/android/jank_metric.proto
 
 message AndroidJankMetrics {
@@ -1420,7 +1459,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 43
+// Next id: 44
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -1530,8 +1569,12 @@
   // is clear that this data is necessary.
   optional AndroidCameraUnaggregatedMetric android_camera_unagg = 41;
 
+  // Metrics for RT runtime.
   optional AndroidRtRuntimeMetric android_rt_runtime = 42;
 
+  // Metrics for IRQ runtime.
+  optional AndroidIrqRuntimeMetric android_irq_runtime = 43;
+
   // Demo extensions.
   extensions 450 to 499;
 
diff --git a/python/perfetto/batch_trace_processor/platform.py b/python/perfetto/batch_trace_processor/platform.py
index 63f1d6c..677c8a5 100644
--- a/python/perfetto/batch_trace_processor/platform.py
+++ b/python/perfetto/batch_trace_processor/platform.py
@@ -19,9 +19,10 @@
 class PlatformDelegate:
   """Abstracts operations which can vary based on platform."""
 
-  def create_query_executor(trace_count: int
+  def create_query_executor(self, trace_count: int
                            ) -> Optional[cf.ThreadPoolExecutor]:
     return None
 
-  def create_load_executor(trace_count: int) -> Optional[cf.ThreadPoolExecutor]:
+  def create_load_executor(self,
+                           trace_count: int) -> Optional[cf.ThreadPoolExecutor]:
     return None
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index 053e838..7c82b50 100644
--- a/python/perfetto/trace_processor/metrics.descriptor
+++ b/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/python/perfetto/trace_processor/metrics.descriptor.sha1 b/python/perfetto/trace_processor/metrics.descriptor.sha1
index 17f0868..fb38d4e 100644
--- a/python/perfetto/trace_processor/metrics.descriptor.sha1
+++ b/python/perfetto/trace_processor/metrics.descriptor.sha1
@@ -2,5 +2,5 @@
 // SHA1(tools/gen_binary_descriptors)
 // c4a38769074f8a8c2ffbf514b267919b5f2d47df
 // SHA1(protos/perfetto/metrics/metrics.proto)
-// 22722c7fde543d5abd1299f48edd49c69c5f5c3e
+// 3b323de4f6dc7cbf8d725751627d3eb2b0fce8ce
   
\ No newline at end of file
diff --git a/python/test/api_integrationtest.py b/python/test/api_integrationtest.py
index f7d035e..2b01a30 100644
--- a/python/test/api_integrationtest.py
+++ b/python/test/api_integrationtest.py
@@ -17,9 +17,85 @@
 import os
 import unittest
 
-from perfetto.trace_processor.api import TraceProcessor
+import pandas as pd
+
+from perfetto.trace_processor.api import PLATFORM_DELEGATE, TraceProcessor
 from perfetto.trace_processor.api import TraceProcessorConfig
 from perfetto.trace_processor.api import TraceReference
+from perfetto.trace_processor.resolver import TraceUriResolver
+from perfetto.trace_processor.resolver_registry import ResolverRegistry
+from perfetto.trace_processor.path_resolver import PathUriResolver
+
+from perfetto.batch_trace_processor.api import BatchTraceProcessor
+from perfetto.batch_trace_processor.api import BatchTraceProcessorConfig
+from perfetto.batch_trace_processor.api import TraceListReference
+
+
+class SimpleResolver(TraceUriResolver):
+  PREFIX = 'simple'
+
+  def __init__(self, path, skip_resolve_file=False):
+    self.path = path
+    self.file = open(example_android_trace_path(), 'rb')
+    self.skip_resolve_file = skip_resolve_file
+
+  def file_gen(self):
+    with open(example_android_trace_path(), 'rb') as f:
+      yield f.read()
+
+  def resolve(self):
+    res = [
+        TraceUriResolver.Result(
+            self.file_gen(), metadata={'source': 'generator'}),
+        TraceUriResolver.Result(
+            example_android_trace_path(), metadata={'source': 'path'}),
+    ]
+    if not self.skip_resolve_file:
+      res.extend([
+          TraceUriResolver.Result(
+              PathUriResolver(example_android_trace_path()),
+              metadata={'source': 'path_resolver'}),
+          TraceUriResolver.Result(self.file, metadata={'source': 'file'}),
+      ])
+    return res
+
+
+class RecursiveResolver(SimpleResolver):
+  PREFIX = 'recursive'
+
+  def __init__(self, path, skip_resolve_file):
+    super().__init__(path=path, skip_resolve_file=skip_resolve_file)
+
+  def resolve(self):
+    srf = self.skip_resolve_file
+    return [
+        TraceUriResolver.Result(
+            self.file_gen(), metadata={'source': 'recursive_gen'}),
+        TraceUriResolver.Result(
+            f'simple:path={self.path};skip_resolve_file={srf}',
+            metadata={
+                'source': 'recursive_path',
+                'root_source': 'recursive_path'
+            }),
+        TraceUriResolver.Result(
+            SimpleResolver(
+                path=self.path, skip_resolve_file=self.skip_resolve_file),
+            metadata={
+                'source': 'recursive_obj',
+                'root_source': 'recursive_obj'
+            }),
+    ]
+
+
+def create_batch_tp(traces: TraceListReference):
+  default = PLATFORM_DELEGATE().default_resolver_registry()
+  default.register(SimpleResolver)
+  default.register(RecursiveResolver)
+  return BatchTraceProcessor(
+      traces=traces,
+      config=BatchTraceProcessorConfig(
+          TraceProcessorConfig(
+              bin_path=os.environ["SHELL_PATH"], resolver_registry=default)))
 
 
 def create_tp(trace: TraceReference):
@@ -102,3 +178,43 @@
 
       for num, row in enumerate(qr_iterator):
         self.assertEqual(row.dur, dur_result[num])
+
+  def test_simple_resolver(self):
+    dur = [178646, 178646, 178646, 178646]
+    source = ['generator', 'path', 'path_resolver', 'file']
+    expected = pd.DataFrame(list(zip(dur, source)), columns=['dur', 'source'])
+
+    with create_batch_tp(
+        traces='simple:path={}'.format(example_android_trace_path())) as btp:
+      df = btp.query_and_flatten('select dur from slice limit 1')
+      pd.testing.assert_frame_equal(df, expected, check_dtype=False)
+
+    with create_batch_tp(
+        traces=SimpleResolver(path=example_android_trace_path())) as btp:
+      df = btp.query_and_flatten('select dur from slice limit 1')
+      pd.testing.assert_frame_equal(df, expected, check_dtype=False)
+
+  def test_recursive_resolver(self):
+    dur = [
+        178646, 178646, 178646, 178646, 178646, 178646, 178646, 178646, 178646
+    ]
+    source = ['recursive_gen', 'generator', 'path', 'generator', 'path']
+    root_source = [
+        None, 'recursive_path', 'recursive_path', 'recursive_obj',
+        'recursive_obj'
+    ]
+    expected = pd.DataFrame(
+        list(zip(dur, source, root_source)),
+        columns=['dur', 'source', 'root_source'])
+
+    uri = 'recursive:path={};skip_resolve_file=true'.format(
+        example_android_trace_path())
+    with create_batch_tp(traces=uri) as btp:
+      df = btp.query_and_flatten('select dur from slice limit 1')
+      pd.testing.assert_frame_equal(df, expected, check_dtype=False)
+
+    with create_batch_tp(
+        traces=RecursiveResolver(
+            path=example_android_trace_path(), skip_resolve_file=True)) as btp:
+      df = btp.query_and_flatten('select dur from slice limit 1')
+      pd.testing.assert_frame_equal(df, expected, check_dtype=False)
diff --git a/src/trace_processor/metrics/sql/BUILD.gn b/src/trace_processor/metrics/sql/BUILD.gn
index 6d9f8f3..20a36ed 100644
--- a/src/trace_processor/metrics/sql/BUILD.gn
+++ b/src/trace_processor/metrics/sql/BUILD.gn
@@ -63,6 +63,7 @@
   "android/process_oom_score.sql",
   "android/profiler_smaps.sql",
   "android/android_rt_runtime.sql",
+  "android/android_irq_runtime.sql",
   "android/mem_stats_priority_breakdown.sql",
   "android/android_multiuser.sql",
   "android/android_multiuser_populator.sql",
diff --git a/src/trace_processor/metrics/sql/android/android_irq_runtime.sql b/src/trace_processor/metrics/sql/android/android_irq_runtime.sql
new file mode 100644
index 0000000..e57bdf5
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_irq_runtime.sql
@@ -0,0 +1,123 @@
+--
+-- Copyright 2022 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+DROP VIEW IF EXISTS irq_runtime_all;
+
+CREATE VIEW irq_runtime_all
+AS
+SELECT ts, dur, name
+FROM slice
+WHERE category = 'irq';
+
+DROP VIEW IF EXISTS hw_irq_runtime;
+
+CREATE VIEW hw_irq_runtime
+AS
+SELECT ts, dur, name
+FROM irq_runtime_all
+WHERE name LIKE 'IRQ (%)'
+ORDER BY dur DESC;
+
+DROP VIEW IF EXISTS hw_irq_runtime_statistics;
+
+CREATE VIEW hw_irq_runtime_statistics
+AS
+SELECT
+  MAX(dur) AS max_runtime,
+  COUNT(IIF(dur > 1e6, 1, NULL)) AS over_threshold_count,
+  COUNT(*) AS total_count
+FROM hw_irq_runtime;
+
+DROP VIEW IF EXISTS sw_irq_runtime;
+
+CREATE VIEW sw_irq_runtime
+AS
+SELECT ts, dur, name
+FROM irq_runtime_all
+WHERE name NOT LIKE 'IRQ (%)'
+ORDER BY dur DESC;
+
+CREATE VIEW sw_irq_runtime_statistics
+AS
+SELECT
+  MAX(dur) AS max_runtime,
+  COUNT(IIF(dur > 5e6, 1, NULL)) AS over_threshold_count,
+  COUNT(*) AS total_count
+FROM sw_irq_runtime;
+
+DROP VIEW IF EXISTS android_irq_runtime_output;
+
+CREATE VIEW android_irq_runtime_output
+AS
+SELECT
+  AndroidIrqRuntimeMetric(
+    'hw_irq',
+    (
+      SELECT
+        AndroidIrqRuntimeMetric_IrqRuntimeMetric(
+          'max_runtime',
+          max_runtime,
+          'total_count',
+          total_count,
+          'threshold_metric',
+          AndroidIrqRuntimeMetric_ThresholdMetric(
+            'threshold',
+            '1ms',
+            'over_threshold_count',
+            over_threshold_count,
+            'anomaly_ratio',
+            CAST(
+              over_threshold_count AS DOUBLE)
+              / CAST(
+                total_count AS DOUBLE)),
+          'longest_irq_slices',
+          (
+            SELECT
+              RepeatedField(
+                AndroidIrqRuntimeMetric_IrqSlice(
+                  'irq_name', name, 'ts', ts, 'dur', dur))
+            FROM (SELECT ts, dur, name FROM hw_irq_runtime LIMIT 10)
+          ))
+      FROM hw_irq_runtime_statistics
+    ),
+    'sw_irq',
+    (
+      SELECT
+        AndroidIrqRuntimeMetric_IrqRuntimeMetric(
+          'max_runtime',
+          max_runtime,
+          'total_count',
+          total_count,
+          'threshold_metric',
+          AndroidIrqRuntimeMetric_ThresholdMetric(
+            'threshold',
+            '5ms',
+            'over_threshold_count',
+            over_threshold_count,
+            'anomaly_ratio',
+            CAST(
+              over_threshold_count AS DOUBLE)
+              / CAST(
+                total_count AS DOUBLE)),
+          'longest_irq_slices',
+          (
+            SELECT
+              RepeatedField(
+                AndroidIrqRuntimeMetric_IrqSlice(
+                  'irq_name', name, 'ts', ts, 'dur', dur))
+            FROM (SELECT ts, dur, name FROM sw_irq_runtime LIMIT 10)
+          ))
+      FROM sw_irq_runtime_statistics
+    ));
diff --git a/test/trace_processor/include_index b/test/trace_processor/include_index
index de04954..7405914 100644
--- a/test/trace_processor/include_index
+++ b/test/trace_processor/include_index
@@ -14,3 +14,4 @@
 tables/index
 track_event/index
 network/index
+performance/index
diff --git a/test/trace_processor/performance/index b/test/trace_processor/performance/index
new file mode 100644
index 0000000..9687108
--- /dev/null
+++ b/test/trace_processor/performance/index
@@ -0,0 +1,2 @@
+# IRQ max runtime and count over 1ms
+irq_runtime_metric.textproto android_irq_runtime irq_runtime_metric.out
diff --git a/test/trace_processor/performance/irq_runtime_metric.out b/test/trace_processor/performance/irq_runtime_metric.out
new file mode 100644
index 0000000..8bfe557
--- /dev/null
+++ b/test/trace_processor/performance/irq_runtime_metric.out
@@ -0,0 +1,50 @@
+android_irq_runtime: {
+  hw_irq: {
+    max_runtime: 4000000
+    total_count: 4
+    threshold_metric: {
+      threshold: "1ms"
+      over_threshold_count: 3
+      anomaly_ratio: 0.75
+    }
+    longest_irq_slices: {
+      irq_name: "IRQ (resource3)"
+      ts: 300005000000
+      dur: 4000000
+    }
+    longest_irq_slices: {
+      irq_name: "IRQ (resource3)"
+      ts: 300001000000
+      dur: 3000000
+    }
+    longest_irq_slices: {
+      irq_name: "IRQ (resource2)"
+      ts: 200001000000
+      dur: 2000000
+    }
+    longest_irq_slices: {
+      irq_name: "IRQ (resource1)"
+      ts: 100001000000
+      dur: 1000000
+    }
+  }
+  sw_irq: {
+    max_runtime: 6000000
+    total_count: 2
+    threshold_metric: {
+      threshold: "5ms"
+      over_threshold_count: 1
+      anomaly_ratio: 0.5
+    }
+    longest_irq_slices: {
+      irq_name: "TIMER"
+      ts: 500001000000
+      dur: 6000000
+    }
+    longest_irq_slices: {
+      irq_name: "BLOCK"
+      ts: 400001000000
+      dur: 800000
+    }
+  }
+}
diff --git a/test/trace_processor/performance/irq_runtime_metric.textproto b/test/trace_processor/performance/irq_runtime_metric.textproto
new file mode 100644
index 0000000..9da0b11
--- /dev/null
+++ b/test/trace_processor/performance/irq_runtime_metric.textproto
@@ -0,0 +1,97 @@
+packet {
+  ftrace_events {
+    cpu: 1
+    event {
+      timestamp: 100001000000
+      pid: 10
+      irq_handler_entry {
+        irq: 100
+        name : "resource1"
+      }
+    }
+    event {
+      timestamp: 100002000000
+      pid: 10
+      irq_handler_exit {
+        irq: 100
+        ret: 1
+      }
+    }
+    event {
+      timestamp: 200001000000
+      pid: 20
+      irq_handler_entry {
+        irq: 200
+        name : "resource2"
+      }
+    }
+    event {
+      timestamp: 200003000000
+      pid: 20
+      irq_handler_exit {
+        irq: 200
+        ret: 1
+      }
+    }
+    event {
+      timestamp: 300001000000
+      pid: 30
+      irq_handler_entry {
+        irq: 300
+        name : "resource3"
+      }
+    }
+    event {
+      timestamp: 300004000000
+      pid: 30
+      irq_handler_exit {
+        irq: 300
+        ret: 1
+      }
+    }
+    event {
+      timestamp: 300005000000
+      pid: 30
+      irq_handler_entry {
+        irq: 300
+        name : "resource3"
+      }
+    }
+    event {
+      timestamp: 300009000000
+      pid: 30
+      irq_handler_exit {
+        irq: 300
+        ret: 1
+      }
+    }
+    event {
+      timestamp: 400001000000
+      pid: 40
+      softirq_entry {
+        vec: 4
+      }
+    }
+    event {
+      timestamp: 400001800000
+      pid: 40
+      softirq_exit {
+        vec: 4
+       }
+    }
+    event {
+      timestamp: 500001000000
+      pid: 50
+      softirq_entry {
+        vec: 1
+      }
+    }
+    event {
+      timestamp: 500007000000
+      pid: 50
+      softirq_exit {
+        vec: 1
+      }
+    }
+  }
+}