• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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