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 INT, 25 -- Duration 26 dur INT, 27 -- 'awake' or 'suspended' 28 power_state STRING) AS 29WITH suspend_slice_from_minimal AS ( 30 SELECT ts, dur 31 FROM track t JOIN slice s ON s.track_id = t.id 32 WHERE t.name = 'Suspend/Resume Minimal' 33), 34suspend_slice as ( 35 SELECT ts, dur FROM suspend_slice_from_minimal 36 UNION ALL 37 SELECT 38 ts, 39 dur 40 FROM 41 slice 42 JOIN 43 track 44 ON slice.track_id = track.id 45 WHERE 46 track.name = 'Suspend/Resume Latency' 47 AND (slice.name = 'syscore_resume(0)' OR slice.name = 'timekeeping_freeze(0)') 48 AND dur != -1 49 AND NOT EXISTS(SELECT * FROM suspend_slice_from_minimal) 50), 51awake_slice AS ( 52 -- If we don't have any rows, use the trace bounds. 53 SELECT 54 trace_start() AS ts, 55 trace_dur() AS dur 56 WHERE (SELECT COUNT(*) FROM suspend_slice) = 0 57 UNION ALL 58 -- If we do have rows, create one slice from the trace start to the first suspend. 59 SELECT 60 trace_start() AS ts, 61 (SELECT min(ts) FROM suspend_slice) - trace_start() AS dur 62 WHERE (SELECT COUNT(*) FROM suspend_slice) != 0 63 UNION ALL 64 -- And then one slice for each suspend, from the end of the suspend to the 65 -- start of the next one (or the end of the trace if there is no next one). 66 SELECT 67 ts + dur AS ts, 68 ifnull(lead(ts) OVER (ORDER BY ts), trace_end()) - ts - dur 69 AS dur 70 FROM suspend_slice 71) 72SELECT ts, dur, 'awake' AS power_state 73FROM awake_slice 74UNION ALL 75SELECT ts, dur, 'suspended' AS power_state 76FROM suspend_slice 77ORDER BY ts; -- Order by will cause Perfetto table to index by ts. 78 79 80-- Extracts the duration without counting CPU suspended time from an event. 81-- This is the same as converting an event duration from wall clock to monotonic clock. 82-- If there was no CPU suspend, the result is same as |dur|. 83CREATE PERFETTO FUNCTION _extract_duration_without_suspend( 84 -- Timestamp of event. 85 ts INT, 86 -- Duration of event. 87 dur INT) 88RETURNS INT 89AS 90SELECT to_monotonic($ts + $dur) - to_monotonic($ts); 91