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