1-- Copyright 2022 The Android Open Source Project 2-- 3-- Licensed under the Apache License, Version 2.0 (the "License"); 4-- you may not use this file except in compliance with the License. 5-- You may obtain a copy of the License at 6-- 7-- https://www.apache.org/licenses/LICENSE-2.0 8-- 9-- Unless required by applicable law or agreed to in writing, software 10-- distributed under the License is distributed on an "AS IS" BASIS, 11-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12-- See the License for the specific language governing permissions and 13-- limitations under the License. 14 15-- The "reliable range" is defined as follows: 16-- 1. If a thread_track has a first_packet_on_sequence flag, the thread data is reliable for the 17-- entire duration of the trace. 18-- 2. Otherwise, the thread data is reliable from the first thread event till the end of the trace. 19-- 3. The "reliable range" is an intersection of reliable thread ranges for all threads such that: 20-- a. The number of events on the thread is at or above 25p. 21-- b. The event rate for the thread is at or above 75p. 22-- Note: this metric considers only chrome processes and their threads, i.e. the ones coming 23-- from track_event's. 24SELECT IMPORT('common.metadata'); 25 26DROP VIEW IF EXISTS chrome_event_stats_per_thread; 27 28CREATE VIEW chrome_event_stats_per_thread 29AS 30SELECT 31 COUNT(*) AS cnt, CAST(COUNT(*) AS DOUBLE) / (MAX(ts + dur) - MIN(ts)) AS rate, utid 32FROM thread_track 33JOIN slice 34 ON thread_track.id = slice.track_id 35WHERE EXTRACT_ARG(source_arg_set_id, 'source') = 'descriptor' 36GROUP BY utid; 37 38DROP VIEW IF EXISTS chrome_event_cnt_cutoff; 39 40-- Ignore the bottom 25% of threads by event count. 25% is a somewhat arbitrary number. It creates a 41-- cutoff at around 10 events for a typical trace, and threads with fewer events are usually: 42-- 1. Not particularly interesting for the reliable range definition. 43-- 2. Create a lot of noise for other metrics, such as event rate. 44CREATE VIEW chrome_event_cnt_cutoff 45AS 46SELECT cnt 47FROM 48 chrome_event_stats_per_thread 49ORDER BY 50 cnt 51LIMIT 52 1 53 OFFSET( 54 (SELECT COUNT(*) FROM chrome_event_stats_per_thread) / 4); 55 56DROP VIEW IF EXISTS chrome_event_rate_cutoff; 57 58-- Choose the top 25% event rate. 25% is a somewhat arbitrary number. The goal is to strike 59-- balance between not cropping too many events and making sure that the chance of data loss in the 60-- range declared "reliable" is low. 61CREATE VIEW chrome_event_rate_cutoff 62AS 63SELECT rate 64FROM 65 chrome_event_stats_per_thread 66ORDER BY 67 rate 68LIMIT 69 1 70 OFFSET( 71 (SELECT COUNT(*) FROM chrome_event_stats_per_thread) * 3 / 4); 72 73DROP VIEW IF EXISTS chrome_reliable_range_per_thread; 74 75-- This view includes only threads with event count and rate above the cutoff points defined 76-- above. 77-- See b/239830951 for the analysis showing why we don't want to include all threads here 78-- (TL;DR - it makes the "reliable range" too short for a typical trace). 79CREATE VIEW chrome_reliable_range_per_thread 80AS 81SELECT 82 utid, 83 MIN(ts) AS start, 84 MAX(IFNULL(EXTRACT_ARG(source_arg_set_id, 'has_first_packet_on_sequence'), 0)) 85 AS has_first_packet_on_sequence 86FROM thread_track 87JOIN slice 88 ON thread_track.id = slice.track_id 89WHERE 90 utid IN ( 91 SELECT utid 92 FROM chrome_event_stats_per_thread 93 LEFT JOIN chrome_event_cnt_cutoff 94 ON 1 95 LEFT JOIN chrome_event_rate_cutoff 96 ON 1 97 WHERE 98 chrome_event_stats_per_thread.cnt >= chrome_event_cnt_cutoff.cnt 99 AND chrome_event_stats_per_thread.rate >= chrome_event_rate_cutoff.rate 100 ) 101GROUP BY utid; 102 103-- Finds Browser and Renderer processes with a missing main thread. If there 104-- is such a process, the trace definitely has thread data loss, and no part 105-- of the trace is trustworthy/reliable. 106-- As of Jan 2023, all tracing scenarios emit some data from the Browser and 107-- Renderer main thread (assuming that the corresponding process is present). 108DROP VIEW IF EXISTS chrome_processes_with_missing_main; 109 110CREATE VIEW chrome_processes_with_missing_main 111AS 112SELECT 113 upid 114FROM ( 115 SELECT upid, utid 116 FROM process 117 LEFT JOIN 118 -- We can't use is_main_thread column for Chrome traces - Renderer 119 -- processes have is_main_thread = 0 for the logical main thread. 120 (SELECT utid, upid FROM thread WHERE thread.name GLOB '*[Mm]ain*') 121 USING (upid) 122 WHERE 123 EXTRACT_ARG(process.arg_set_id, 'chrome.process_type') 124 IN ('Browser', 'Renderer', 'Gpu') 125) 126WHERE utid is NULL; 127 128DROP VIEW IF EXISTS chrome_processes_data_loss_free_period; 129 130CREATE VIEW chrome_processes_data_loss_free_period 131AS 132SELECT 133 upid AS limiting_upid, 134 -- If reliable_from is NULL, the process has data loss until the end of the trace. 135 IFNULL(reliable_from, (SELECT MAX(ts + dur) FROM slice)) AS start 136FROM 137 ( 138 SELECT upid, reliable_from 139 FROM experimental_missing_chrome_processes 140 UNION ALL 141 -- A missing main thread means that the process data is unreliable for the 142 -- entire duration of the trace. 143 SELECT upid, NULL AS reliable_from 144 FROM chrome_processes_with_missing_main 145 ) 146ORDER BY start DESC 147LIMIT 1; 148 149DROP VIEW IF EXISTS chrome_reliable_range; 150 151CREATE VIEW chrome_reliable_range 152AS 153SELECT 154 -- If the trace has a cropping packet, we don't want to recompute the reliable 155 -- based on cropped track events - the result might be incorrect. 156 IFNULL(EXTRACT_INT_METADATA('range_of_interest_start_us') * 1000, 157 MAX(thread_start, data_loss_free_start)) AS start, 158 IIF(EXTRACT_INT_METADATA('range_of_interest_start_us') IS NOT NULL, 159 'Range of interest packet', 160 IIF(limiting_upid IN (SELECT upid FROM chrome_processes_with_missing_main), 161 'Missing main thread for upid=' || limiting_upid, 162 IIF(thread_start >= data_loss_free_start, 163 'First slice for utid=' || limiting_utid, 164 'Missing process data for upid=' || limiting_upid))) AS reason, 165 limiting_upid AS debug_limiting_upid, 166 limiting_utid AS debug_limiting_utid 167FROM 168 (SELECT 169 COALESCE(MAX(start), 0) AS thread_start, 170 utid AS limiting_utid, 171 COALESCE((SELECT start FROM chrome_processes_data_loss_free_period), 0) AS data_loss_free_start, 172 (SELECT limiting_upid FROM chrome_processes_data_loss_free_period) AS limiting_upid 173 FROM chrome_reliable_range_per_thread 174 WHERE has_first_packet_on_sequence = 0); 175