1-- 2-- Copyright 2023 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. 15INCLUDE PERFETTO MODULE slices.with_context; 16 17INCLUDE PERFETTO MODULE intervals.overlap; 18 19-- The concept of a "flat slice" is to take the data in the slice table and 20-- remove all notion of nesting; we do this by projecting every slice in a stack to 21-- their ancestor slice, i.e at any point in time, taking the most specific active 22-- slice (i.e. the slice at the bottom of the stack) and representing that as the 23-- *only* slice that was running during that period. 24-- 25-- This concept becomes very useful when you try and linearise a trace and 26-- compare it with other traces spanning the same user action; "self time" (i.e. 27-- time spent in a slice but *not* any children) is easily computed and span 28-- joins with thread state become possible without limiting to only depth zero 29--- slices. 30-- 31-- Note that, no slices will be generated for intervals without without any slices. 32-- 33-- As an example, consider the following slice stack: 34-- ``` 35-- A-------------B. 36-- ----C----D----. 37-- ``` 38-- The flattened slice will be: 39-- ``` 40-- A----C----D----B. 41-- ``` 42-- 43-- @column slice_id Id of most active slice. 44-- @column ts Timestamp when `slice.id` became the most active slice. 45-- @column dur Duration of `slice.id` as the most active slice until the next active slice. 46-- @column depth Depth of `slice.id` in the original stack. 47-- @column name Name of `slice.id`. 48-- @column root_id Id of of the top most slice of the stack. 49-- @column track_id Alias for `slice.track_id`. 50-- @column utid Alias for `thread.utid`. 51-- @column tid Alias for `thread.tid` 52-- @column thread_name Alias for `thread.name`. 53-- @column upid Alias for `process.upid`. 54-- @column pid Alias for `process.pid`. 55-- @column process_name Alias for `process.name`. 56CREATE PERFETTO TABLE _slice_flattened AS 57WITH 58 root_slices AS ( 59 SELECT 60 * 61 FROM slice 62 WHERE 63 parent_id IS NULL 64 ), 65 child_slices AS ( 66 SELECT 67 anc.id AS root_id, 68 slice.* 69 FROM slice, ancestor_slice(slice.id) AS anc 70 WHERE 71 slice.parent_id IS NOT NULL 72 ), 73 flat_slices AS ( 74 SELECT 75 root_id, 76 id, 77 ts, 78 dur 79 FROM _intervals_flatten !(_intervals_merge_root_and_children!(root_slices, child_slices)) 80 ) 81SELECT 82 id AS slice_id, 83 flat_slices.ts, 84 flat_slices.dur, 85 depth, 86 name, 87 root_id, 88 track_id, 89 utid, 90 tid, 91 thread_name, 92 upid, 93 pid, 94 process_name 95FROM flat_slices 96JOIN thread_slice 97 USING (id); 98 99CREATE PERFETTO INDEX _slice_flattened_id_idx ON _slice_flattened(slice_id); 100 101CREATE PERFETTO INDEX _slice_flattened_ts_idx ON _slice_flattened(ts); 102