stdlib: split linux.cpu.idle into linux.cpu.idle_stats

This reduces runtime of linux.cpu.idle where the stats are not needed.

Change-Id: I506c718ab2a64dba5817ad2793540abf5dfa0e10
diff --git a/Android.bp b/Android.bp
index 4cc0adf..a89a992 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13333,6 +13333,7 @@
         "src/trace_processor/perfetto_sql/stdlib/intervals/overlap.sql",
         "src/trace_processor/perfetto_sql/stdlib/linux/cpu/frequency.sql",
         "src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle.sql",
+        "src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle_stats.sql",
         "src/trace_processor/perfetto_sql/stdlib/linux/cpu/utilization/general.sql",
         "src/trace_processor/perfetto_sql/stdlib/linux/cpu/utilization/process.sql",
         "src/trace_processor/perfetto_sql/stdlib/linux/cpu/utilization/system.sql",
diff --git a/BUILD b/BUILD
index d0bb252..dd8c8b4 100644
--- a/BUILD
+++ b/BUILD
@@ -2756,6 +2756,7 @@
     srcs = [
         "src/trace_processor/perfetto_sql/stdlib/linux/cpu/frequency.sql",
         "src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle.sql",
+        "src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle_stats.sql",
     ],
 )
 
diff --git a/CHANGELOG b/CHANGELOG
index eba64e8..bc7ebed 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,10 +14,10 @@
       reason as above.
     * Moved `gpu.frequency` to `android.gpu.frequency` for the same reason as
       above.
-    * Moved `cpu.idle` module to `linux.cpu.idle` for the same
-      reason as above.
-    * Moved content of `linux.cpu_idle` into `linux.cpu.idle` to make it
-      consistent with above changes.
+    * Moved `cpu.idle` module to `linux.cpu.idle` or `linux.cpu.idle_stats` for
+      the same reason as above.
+    * Moved content of `linux.cpu_idle` into `linux.cpu.idle` and
+      `linux.cpu.idle_stats` to make it consistent with above changes.
     * Moved `memory.android.gpu` to `android.memory.gpu`  to make it consistent
       with above changes.`
     * Moved contents of `memory.linux.process` to `linux.memory.process` and
diff --git a/src/trace_processor/perfetto_sql/stdlib/counters/intervals.sql b/src/trace_processor/perfetto_sql/stdlib/counters/intervals.sql
index 5473892..cf9e5a3 100644
--- a/src/trace_processor/perfetto_sql/stdlib/counters/intervals.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/counters/intervals.sql
@@ -68,4 +68,4 @@
     value - lag_value AS delta_value
   FROM base
   WHERE value != lag_value OR lag_value IS NULL
-);
\ No newline at end of file
+);
diff --git a/src/trace_processor/perfetto_sql/stdlib/linux/cpu/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/linux/cpu/BUILD.gn
index a9d870a..42654eb 100644
--- a/src/trace_processor/perfetto_sql/stdlib/linux/cpu/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/linux/cpu/BUILD.gn
@@ -18,6 +18,7 @@
   sources = [
     "frequency.sql",
     "idle.sql",
+    "idle_stats.sql",
   ]
   deps = [ "utilization" ]
 }
diff --git a/src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle.sql b/src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle.sql
index 7019187..61e3f23 100644
--- a/src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle.sql
@@ -14,7 +14,6 @@
 -- limitations under the License.
 
 INCLUDE PERFETTO MODULE counters.intervals;
-INCLUDE PERFETTO MODULE linux.cpu.frequency;
 
 -- Counter information for each idle state change for each CPU. Finds each time
 -- region where a CPU idle state is constant.
@@ -33,8 +32,7 @@
   idle INT,
   -- CPU that corresponds to this counter.
   cpu INT
-)
-AS
+) AS
 SELECT
   count_w_dur.id,
   count_w_dur.track_id,
@@ -42,62 +40,9 @@
   count_w_dur.dur,
   cast_int!(IIF(count_w_dur.value = 4294967295, -1, count_w_dur.value)) AS idle,
   cct.cpu
-FROM
-counter_leading_intervals!((
+FROM counter_leading_intervals!((
   SELECT c.*
   FROM counter c
-  JOIN cpu_counter_track cct
-  ON cct.id = c.track_id and cct.name = 'cpuidle'
-)) count_w_dur
-JOIN cpu_counter_track cct
-ON track_id = cct.id;
-
-CREATE PERFETTO VIEW _freq_counters_for_sp_jn AS
-SELECT ts, dur, cpu
-FROM cpu_frequency_counters;
-
-CREATE PERFETTO VIEW _idle_counters_for_sp_jn AS
-SELECT ts, dur, cpu, idle
-FROM cpu_idle_counters;
-
--- Combined cpu freq & idle counter
-CREATE VIRTUAL TABLE _freq_idle_counters
-USING span_join(
-  _freq_counters_for_sp_jn PARTITIONED cpu,
-  _idle_counters_for_sp_jn PARTITIONED cpu
-);
-
--- Aggregates cpu idle statistics per core.
-CREATE PERFETTO TABLE cpu_idle_stats(
-  -- CPU core number.
-  cpu INT,
-  -- CPU idle state (C-states).
-  state INT,
-  -- The count of entering idle state.
-  count INT,
-  -- Total CPU core idle state duration in nanoseconds.
-  dur INT,
-  -- Average CPU core idle state duration in nanoseconds.
-  avg_dur INT,
-  -- Idle state percentage of non suspend time (C-states + P-states).
-  idle_percent FLOAT
-)
-AS
-WITH
-total AS (
-  SELECT
-    cpu,
-    sum(dur) AS dur
-  FROM _freq_idle_counters
-  GROUP BY cpu
-)
-SELECT
-  cpu,
-  (idle + 1) AS state,
-  COUNT(idle) AS count,
-  SUM(dur) AS dur,
-  SUM(dur) / COUNT(idle) AS avg_dur,
-  SUM(dur) * 100.0 / (SELECT dur FROM total t WHERE t.cpu = ific.cpu) AS idle_percent
-FROM _freq_idle_counters ific
-WHERE idle >=0
-GROUP BY cpu, idle;
+  JOIN cpu_counter_track cct ON cct.id = c.track_id AND cct.name = 'cpuidle'
+)) AS count_w_dur
+JOIN cpu_counter_track AS cct ON track_id = cct.id;
diff --git a/src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle_stats.sql b/src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle_stats.sql
new file mode 100644
index 0000000..b95ec15
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/linux/cpu/idle_stats.sql
@@ -0,0 +1,54 @@
+--
+-- Copyright 2024 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.
+
+INCLUDE PERFETTO MODULE linux.cpu.idle;
+
+-- Aggregates cpu idle statistics per core.
+CREATE PERFETTO TABLE cpu_idle_stats(
+  -- CPU core number.
+  cpu INT,
+  -- CPU idle state (C-states).
+  state INT,
+  -- The count of entering idle state.
+  count INT,
+  -- Total CPU core idle state duration in nanoseconds.
+  dur INT,
+  -- Average CPU core idle state duration in nanoseconds.
+  avg_dur INT,
+  -- Idle state percentage of non suspend time (C-states + P-states).
+  idle_percent FLOAT
+)
+AS
+WITH grouped AS (
+  SELECT
+    cpu,
+    (idle + 1) AS state,
+    COUNT(idle) AS count,
+    SUM(dur) AS dur,
+    SUM(dur) / COUNT(idle) AS avg_dur
+  FROM cpu_idle_counters c
+  WHERE c.idle >= 0
+  GROUP BY c.cpu, c.idle
+),
+total AS (
+  SELECT cpu, SUM(dur) AS dur
+  FROM cpu_idle_counters
+  GROUP BY cpu
+)
+SELECT
+  g.*,
+  g.dur * 100.0 / t.dur AS idle_percent
+FROM grouped g
+JOIN total t USING (cpu);
diff --git a/test/trace_processor/diff_tests/stdlib/linux/cpu.py b/test/trace_processor/diff_tests/stdlib/linux/cpu.py
index b1a4a07..6dfe8bd 100644
--- a/test/trace_processor/diff_tests/stdlib/linux/cpu.py
+++ b/test/trace_processor/diff_tests/stdlib/linux/cpu.py
@@ -249,8 +249,8 @@
             """))
 
   def test_linux_cpu_idle_stats(self):
-      return DiffTestBlueprint(
-          trace=TextProto(r"""
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
           packet {
             ftrace_events {
               cpu: 0
@@ -315,12 +315,11 @@
             trusted_packet_sequence_id: 2
           }
          """),
-         query="""
-         INCLUDE PERFETTO MODULE linux.cpu.idle;
+        query="""
+         INCLUDE PERFETTO MODULE linux.cpu.idle_stats;
          SELECT * FROM cpu_idle_stats;
          """,
-         out=Csv("""
+        out=Csv("""
          "cpu","state","count","dur","avg_dur","idle_percent"
          0,2,2,2000000,1000000,40.000000
          """))
-