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 17INCLUDE PERFETTO MODULE slices.with_context; 18 19INCLUDE PERFETTO MODULE counters.intervals; 20 21-- Converts an oom_adj score Integer to String sample name. 22-- One of: cached, background, job, foreground_service, bfgs, foreground and 23-- system. 24CREATE PERFETTO FUNCTION android_oom_adj_score_to_bucket_name( 25 -- `oom_score` value 26 oom_score LONG 27) 28-- Returns the sample bucket based on the oom score. 29RETURNS STRING AS 30SELECT 31 CASE 32 WHEN $oom_score >= 900 33 THEN 'cached' 34 WHEN $oom_score BETWEEN 250 AND 900 35 THEN 'background' 36 WHEN $oom_score BETWEEN 201 AND 250 37 THEN 'job' 38 WHEN $oom_score = 200 39 THEN 'foreground_service' 40 WHEN $oom_score BETWEEN 100 AND 200 41 THEN 'bfgs' 42 WHEN $oom_score BETWEEN 0 AND 100 43 THEN 'foreground' 44 WHEN $oom_score < 0 45 THEN 'system' 46 END; 47 48-- Converts an oom_adj score Integer to String bucket name. 49-- Deprecated: use `android_oom_adj_score_to_bucket_name` instead. 50CREATE PERFETTO FUNCTION android_oom_adj_score_to_detailed_bucket_name( 51 -- oom_adj score. 52 value LONG, 53 -- android_app id of the process. 54 android_appid LONG 55) 56-- Returns the oom_adj bucket. 57RETURNS STRING AS 58SELECT 59 CASE 60 WHEN $value = -1000 61 THEN 'native' 62 WHEN $value = -900 63 THEN 'system' 64 WHEN $value = -800 65 THEN 'persistent_proc' 66 WHEN $value = -700 67 THEN 'persistent_service' 68 WHEN $value = -600 69 THEN 'logcat' 70 WHEN $value = 0 71 THEN 'foreground_app' 72 WHEN $value = 50 73 THEN 'perceptible_foreground_app' 74 WHEN $value BETWEEN 100 AND 199 75 THEN 'visible_app' 76 WHEN $value BETWEEN 200 AND 224 77 THEN 'perceptible_app' 78 WHEN $value BETWEEN 225 AND 249 79 THEN 'perceptible_medium_app' 80 WHEN $value BETWEEN 250 AND 299 81 THEN 'perceptible_low_app' 82 WHEN $value BETWEEN 300 AND 399 83 THEN 'backup' 84 WHEN $value BETWEEN 400 AND 499 85 THEN 'heavy_weight_app' 86 WHEN $value BETWEEN 500 AND 599 87 THEN 'service' 88 WHEN $value BETWEEN 600 AND 699 89 THEN 'home_app' 90 WHEN $value BETWEEN 700 AND 799 91 THEN 'previous_app' 92 WHEN $value BETWEEN 800 AND 899 93 THEN 'service_b' 94 WHEN $value BETWEEN 900 AND 949 95 THEN 'cached_app' 96 WHEN $value >= 950 97 THEN 'cached_app_lmk_first' 98 WHEN $android_appid IS NULL 99 THEN 'unknown' 100 WHEN $android_appid < 10000 101 THEN 'unknown_native' 102 ELSE 'unknown_app' 103 END; 104 105CREATE PERFETTO TABLE _oom_adjuster_intervals AS 106WITH 107 reason AS ( 108 SELECT 109 thread_slice.id AS oom_adj_id, 110 thread_slice.ts AS oom_adj_ts, 111 thread_slice.dur AS oom_adj_dur, 112 thread_slice.track_id AS oom_adj_track_id, 113 utid AS oom_adj_utid, 114 thread_name AS oom_adj_thread_name, 115 str_split(thread_slice.name, '_', 1) AS oom_adj_reason, 116 slice.name AS oom_adj_trigger, 117 lead(thread_slice.ts) OVER (ORDER BY thread_slice.ts) AS oom_adj_next_ts 118 FROM thread_slice 119 LEFT JOIN slice 120 ON slice.id = thread_slice.parent_id AND slice.dur != -1 121 WHERE 122 thread_slice.name GLOB 'updateOomAdj_*' AND process_name = 'system_server' 123 ) 124SELECT 125 ts, 126 dur, 127 cast_int!(value) AS score, 128 process.upid, 129 process.name AS process_name, 130 reason.oom_adj_id, 131 reason.oom_adj_ts, 132 reason.oom_adj_dur, 133 reason.oom_adj_track_id, 134 reason.oom_adj_thread_name, 135 reason.oom_adj_utid, 136 reason.oom_adj_reason, 137 reason.oom_adj_trigger, 138 android_appid 139FROM counter_leading_intervals 140 !( 141 ( 142 SELECT counter.* 143 FROM counter 144 JOIN counter_track track 145 ON track.id = counter.track_id AND track.name = 'oom_score_adj' 146 )) AS counter 147JOIN process_counter_track AS track 148 ON counter.track_id = track.id 149JOIN process 150 USING (upid) 151LEFT JOIN reason 152 ON counter.ts BETWEEN oom_adj_ts AND coalesce(oom_adj_next_ts, trace_end()) 153WHERE 154 track.name = 'oom_score_adj'; 155 156-- All oom adj state intervals across all processes along with the reason for the state update. 157CREATE PERFETTO VIEW android_oom_adj_intervals ( 158 -- Timestamp the oom_adj score of the process changed 159 ts TIMESTAMP, 160 -- Duration until the next oom_adj score change of the process. 161 dur DURATION, 162 -- oom_adj score of the process. 163 score LONG, 164 -- oom_adj bucket of the process. 165 bucket STRING, 166 -- Upid of the process having an oom_adj update. 167 upid JOINID(process.id), 168 -- Name of the process having an oom_adj update. 169 process_name STRING, 170 -- Slice id of the latest oom_adj update in the system_server. 171 oom_adj_id LONG, 172 -- Timestamp of the latest oom_adj update in the system_server. 173 oom_adj_ts TIMESTAMP, 174 -- Duration of the latest oom_adj update in the system_server. 175 oom_adj_dur DURATION, 176 -- Track id of the latest oom_adj update in the system_server 177 oom_adj_track_id JOINID(track.id), 178 -- Thread name of the latest oom_adj update in the system_server. 179 oom_adj_thread_name STRING, 180 -- Reason for the latest oom_adj update in the system_server. 181 oom_adj_reason STRING, 182 -- Trigger for the latest oom_adj update in the system_server. 183 oom_adj_trigger STRING 184) AS 185SELECT 186 ts, 187 dur, 188 score, 189 android_oom_adj_score_to_bucket_name(score) AS bucket, 190 upid, 191 process_name, 192 oom_adj_id, 193 oom_adj_ts, 194 oom_adj_dur, 195 oom_adj_track_id, 196 oom_adj_thread_name, 197 oom_adj_reason, 198 oom_adj_trigger 199FROM _oom_adjuster_intervals; 200