• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2024 The Android Open Source Project
3--
4-- Licensed under the Apache License, Version 2.0 (the "License");
5-- you may not use this file except in compliance with the License.
6-- You may obtain a copy of the License at
7--
8--     https://www.apache.org/licenses/LICENSE-2.0
9--
10-- Unless required by applicable law or agreed to in writing, software
11-- distributed under the License is distributed on an "AS IS" BASIS,
12-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-- See the License for the specific language governing permissions and
14-- limitations under the License.
15--
16
17-- Table of suspended and awake slices.
18--
19-- Selects either the minimal or full ftrace source depending on what's
20-- available, marks suspended periods, and complements them to give awake
21-- periods.
22CREATE PERFETTO TABLE android_suspend_state (
23  -- Timestamp
24  ts TIMESTAMP,
25  -- Duration
26  dur DURATION,
27  -- 'awake' or 'suspended'
28  power_state STRING
29) AS
30WITH
31  suspend_slice_from_minimal AS (
32    SELECT
33      ts,
34      dur
35    FROM track AS t
36    JOIN slice AS s
37      ON s.track_id = t.id
38    WHERE
39      t.name = 'Suspend/Resume Minimal'
40  ),
41  suspend_slice AS (
42    SELECT
43      ts,
44      dur
45    FROM suspend_slice_from_minimal
46    UNION ALL
47    SELECT
48      ts,
49      dur
50    FROM slice
51    JOIN track
52      ON slice.track_id = track.id
53    WHERE
54      track.name = 'Suspend/Resume Latency'
55      AND (
56        slice.name = 'syscore_resume(0)' OR slice.name = 'timekeeping_freeze(0)'
57      )
58      AND dur != -1
59      AND NOT EXISTS(
60        SELECT
61          *
62        FROM suspend_slice_from_minimal
63      )
64  ),
65  awake_slice AS (
66    -- If we don't have any rows, use the trace bounds if bounds are defined.
67    SELECT
68      trace_start() AS ts,
69      trace_dur() AS dur
70    WHERE
71      (
72        SELECT
73          count(*)
74        FROM suspend_slice
75      ) = 0 AND dur > 0
76    UNION ALL
77    -- If we do have rows, create one slice from the trace start to the first suspend.
78    SELECT
79      trace_start() AS ts,
80      (
81        SELECT
82          min(ts)
83        FROM suspend_slice
84      ) - trace_start() AS dur
85    WHERE
86      (
87        SELECT
88          count(*)
89        FROM suspend_slice
90      ) != 0
91    UNION ALL
92    -- And then one slice for each suspend, from the end of the suspend to the
93    -- start of the next one (or the end of the trace if there is no next one).
94    SELECT
95      ts + dur AS ts,
96      coalesce(lead(ts) OVER (ORDER BY ts), trace_end()) - ts - dur AS dur
97    FROM suspend_slice
98  )
99SELECT
100  ts,
101  dur,
102  'awake' AS power_state
103FROM awake_slice
104UNION ALL
105SELECT
106  ts,
107  dur,
108  'suspended' AS power_state
109FROM suspend_slice
110ORDER BY
111  ts;
112
113-- Order by will cause Perfetto table to index by ts.;
114
115-- Extracts the duration without counting CPU suspended time from an event.
116-- This is the same as converting an event duration from wall clock to monotonic clock.
117-- If there was no CPU suspend, the result is same as |dur|.
118CREATE PERFETTO FUNCTION _extract_duration_without_suspend(
119    -- Timestamp of event.
120    ts TIMESTAMP,
121    -- Duration of event.
122    dur DURATION
123)
124RETURNS LONG AS
125SELECT
126  to_monotonic($ts + $dur) - to_monotonic($ts);
127