1/*
2 * Copyright (C) 2019 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 *      http://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-- note: These queries do comparisons based on raw_ftrace_entries.id by treating it as if it was equivalent to the temporal timestamp.
18-- in practice, the ID of raw_ftrace_entries is based on its order in the ftrace buffer [and on the same cpu its equivalent].
19-- we can always resort raw_ftrace_entries to ensure id order matches timestamp order. We should rarely need to compare by timestamp directly.
20-- accessing 'floats' is inferior as they are harder to index, and will result in slower queries.
21--
22-- Naming convention note: '_fid' corresponds to 'raw_ftrace_entry.id'.
23DROP VIEW IF EXISTS start_process_ui_threads;
24
25-- Map of started process names to their UI thread's TID (as returned by gettid).
26CREATE VIEW IF NOT EXISTS start_process_ui_threads AS
27WITH
28  start_proc_tids AS (
29    SELECT sp.raw_ftrace_entry_id AS start_proc_fid,
30           sp.atrace_pid AS atrace_pid,
31           sp.process_name AS process_name,
32           --MIN(nc.raw_ftrace_entry_id) as next_comm_fid,
33           nc.raw_ftrace_entry_id AS next_comm_fid,
34           nc.next_pid as next_pid,
35           nc.next_comm as next_comm,
36           SUBSTR(sp.process_name, -15) AS cut      -- why -15? See TASK_MAX in kernel, the sched_switch name is truncated to 16 bytes.
37    FROM start_procs AS sp,
38         sched_switch_next_comm_pids AS nc
39    WHERE sp.process_name LIKE '%' || nc.next_comm  -- kernel truncates the sched_switch::next_comm event, so we must match the prefix of the full name.
40    --WHERE SUBSTR(sp.process_name, -16) == nc.next_comm
41    --WHERE cut == nc.next_comm
42  ),
43  start_proc_tids_filtered AS (
44      SELECT *
45      FROM start_proc_tids
46      WHERE next_comm_fid > start_proc_fid        -- safeguard that avoids choosing "earlier" sched_switch before process was even started.
47      --ORDER BY start_proc_fid, next_comm_fid
48  ),
49  start_proc_all_threads AS (
50    SELECT DISTINCT
51        start_proc_fid, -- this is the ftrace entry of the system server 'Start proc: $process_name'. only need this to join for timestamp.
52        process_name,               -- this is the '$process_name' from the system server entry.
53        -- next up we have all the possible thread IDs as parsed from sched_switch that corresponds most closest to the start proc.
54        next_pid AS ui_thread_tpid, -- sched_switch.next_pid. This can be any of the threads in that process, it's not necessarily the main UI thread yet.
55        next_comm,
56        MIN(next_comm_fid) AS next_comm_fid   -- don't pick the 'later' next_comm_fid because it could correspond to another app start.
57    FROM start_proc_tids_filtered
58    GROUP BY start_proc_fid, ui_thread_tpid
59  ),
60  activity_thread_mains AS (
61    SELECT * FROM tracing_mark_write_split WHERE atrace_message = 'ActivityThreadMain'
62  ),
63  start_proc_ui_threads AS (
64    SELECT start_proc_fid,
65           process_name,
66           ui_thread_tpid,
67           next_comm,
68           next_comm_fid,
69           atm.raw_ftrace_entry_id as atm_fid,
70           atm.atrace_pid as atm_ui_thread_tid
71    FROM start_proc_all_threads AS spt,
72         activity_thread_mains AS atm
73    WHERE atm.atrace_pid == spt.ui_thread_tpid AND atm.raw_ftrace_entry_id > spt.start_proc_fid -- Ensure we ignore earlier ActivityThreadMains prior to their Start proc.
74  ),
75  start_proc_ui_threads_filtered AS (
76    SELECT start_proc_fid,
77           process_name,                -- e.g. 'com.android.settings'
78           --ui_thread_tpid,
79           --next_comm,
80           --next_comm_fid,
81           MIN(atm_fid) AS atm_fid,
82           atm_ui_thread_tid            -- equivalent to gettid() for the process's UI thread.
83    FROM start_proc_ui_threads
84    GROUP BY start_proc_fid, atm_ui_thread_tid    -- find the temporally closest ActivityTaskMain to a "Start proc: $process_name"
85  )
86SELECT * FROM start_proc_ui_threads_filtered;
87
88SELECT * FROM start_process_ui_threads;
89