• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2023 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
17-- Extracts the blocking thread from a slice name
18--
19-- @arg slice_name STRING   Name of slice
20-- @ret STRING              Blocking thread
21SELECT
22  CREATE_FUNCTION(
23    'ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKING_THREAD(slice_name STRING)',
24    'STRING',
25    '
26    SELECT STR_SPLIT(STR_SPLIT($slice_name, "with owner ", 1), " (", 0)
27  '
28);
29
30-- Extracts the blocking thread tid from a slice name
31--
32-- @arg slice_name STRING   Name of slice
33-- @ret INT                 Blocking thread tid
34SELECT
35  CREATE_FUNCTION(
36    'ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKING_TID(slice_name STRING)',
37    'INT',
38    '
39    SELECT CAST(STR_SPLIT(STR_SPLIT($slice_name, " (", 1), ")", 0) AS INT)
40  '
41);
42
43-- Extracts the blocking method from a slice name
44--
45-- @arg slice_name STRING   Name of slice
46-- @ret STRING              Blocking thread
47SELECT
48  CREATE_FUNCTION(
49    'ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKING_METHOD(slice_name STRING)',
50    'STRING',
51    '
52    SELECT STR_SPLIT(STR_SPLIT($slice_name, ") at ", 1), "(", 0)
53    || "("
54    || STR_SPLIT(STR_SPLIT($slice_name, ") at ", 1), "(", 1)
55  '
56);
57
58-- Extracts a shortened form of the blocking method name from a slice name.
59-- The shortened form discards the parameter and return
60-- types.
61--
62-- @arg slice_name STRING   Name of slice
63-- @ret STRING              Blocking thread
64SELECT
65  CREATE_FUNCTION(
66    'ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_SHORT_BLOCKING_METHOD(slice_name STRING)',
67    'STRING',
68    '
69    SELECT
70    STR_SPLIT(STR_SPLIT(ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKING_METHOD($slice_name), " ", 1), "(", 0)
71  '
72);
73
74-- Extracts the monitor contention blocked method from a slice name
75--
76-- @arg slice_name STRING   Name of slice
77-- @ret STRING              Blocking thread
78SELECT
79  CREATE_FUNCTION(
80    'ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKED_METHOD(slice_name STRING)',
81    'STRING',
82    '
83    SELECT STR_SPLIT(STR_SPLIT($slice_name, "blocking from ", 1), "(", 0)
84    || "("
85    || STR_SPLIT(STR_SPLIT($slice_name, "blocking from ", 1), "(", 1)
86  '
87);
88
89-- Extracts a shortened form of the monitor contention blocked method name
90-- from a slice name. The shortened form discards the parameter and return
91-- types.
92--
93-- @arg slice_name STRING   Name of slice
94-- @ret STRING              Blocking thread
95SELECT
96  CREATE_FUNCTION(
97    'ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_SHORT_BLOCKED_METHOD(slice_name STRING)',
98    'STRING',
99    '
100    SELECT
101    STR_SPLIT(STR_SPLIT(ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKED_METHOD($slice_name), " ", 1), "(", 0)
102  '
103);
104
105-- Extracts the number of waiters on the monitor from a slice name
106--
107-- @arg slice_name STRING   Name of slice
108-- @ret INT                 Count of waiters on the lock
109SELECT
110  CREATE_FUNCTION(
111    'ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_WAITER_COUNT(slice_name STRING)',
112    'INT',
113    '
114    SELECT CAST(STR_SPLIT(STR_SPLIT($slice_name, "waiters=", 1), " ", 0) AS INT)
115  '
116);
117
118-- Extracts the monitor contention blocking source location from a slice name
119--
120-- @arg slice_name STRING   Name of slice
121-- @ret STRING              Blocking thread
122SELECT
123  CREATE_FUNCTION(
124    'ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKING_SRC(slice_name STRING)',
125    'STRING',
126    '
127    SELECT STR_SPLIT(STR_SPLIT($slice_name, ")(", 1), ")", 0)
128  '
129);
130
131-- Extracts the monitor contention blocked source location from a slice name
132--
133-- @arg slice_name STRING   Name of slice
134-- @ret STRING              Blocking thread
135SELECT
136  CREATE_FUNCTION(
137    'ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKED_SRC(slice_name STRING)',
138    'STRING',
139    '
140    SELECT STR_SPLIT(STR_SPLIT($slice_name, ")(", 2), ")", 0)
141  '
142);
143
144CREATE TABLE internal_broken_android_monitor_contention
145AS
146SELECT ancestor.parent_id AS id FROM slice
147    JOIN slice ancestor ON ancestor.id = slice.parent_id
148    WHERE ancestor.name LIKE 'Lock contention on a monitor lock%'
149    GROUP BY ancestor.id;
150
151-- Contains parsed monitor contention slices.
152--
153-- @column blocking_method Name of the method holding the lock.
154-- @column blocked_methhod Name of the method trying to acquire the lock.
155-- @column short_blocking_method Blocking_method without arguments and return types.
156-- @column short_blocked_method Blocked_method without arguments and return types.
157-- @column blocking_src File location of blocking_method in form <filename:linenumber>.
158-- @column blocked_src File location of blocked_method in form <filename:linenumber>.
159-- @column waiter_count Zero indexed number of threads trying to acquire the lock.
160-- @column blocking_utid Utid of thread holding the lock.
161-- @column blocking_thread_name Thread name of thread holding the lock.
162-- @column upid Upid of process experiencing lock contention.
163-- @column process_name Process name of process experiencing lock contention.
164-- @column id Slice id of lock contention.
165-- @column ts Timestamp of lock contention start.
166-- @column dur Duration of lock contention.
167-- @column track_id Thread track id of blocked thread.
168-- @column is_blocked_main_thread Whether the blocked thread is the main thread.
169-- @column is_blocking_main_thread Whether the blocking thread is the main thread.
170-- @column binder_reply_id Slice id of binder reply slice if lock contention was part of a binder txn.
171-- @column binder_reply_ts Timestamp of binder reply slice if lock contention was part of a binder txn.
172-- @column binder_reply_tid Tid of binder reply slice if lock contention was part of a binder txn.
173CREATE TABLE android_monitor_contention
174AS
175SELECT
176  ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKING_METHOD(slice.name) AS blocking_method,
177  ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKED_METHOD(slice.name)  AS blocked_method,
178  ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_SHORT_BLOCKING_METHOD(slice.name) AS short_blocking_method,
179  ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_SHORT_BLOCKED_METHOD(slice.name)  AS short_blocked_method,
180  ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKING_SRC(slice.name) AS blocking_src,
181  ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKED_SRC(slice.name) AS blocked_src,
182  ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_WAITER_COUNT(slice.name) AS waiter_count,
183  thread.utid AS blocked_utid,
184  thread.name AS blocked_thread_name,
185  blocking_thread.utid AS blocking_utid,
186  ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKING_THREAD(slice.name) AS blocking_thread_name,
187  ANDROID_EXTRACT_ANDROID_MONITOR_CONTENTION_BLOCKING_TID(slice.name) AS blocking_tid,
188  thread.upid AS upid,
189  process.name AS process_name,
190  slice.id,
191  slice.ts,
192  slice.dur,
193  slice.track_id,
194  thread.is_main_thread AS is_blocked_thread_main,
195  thread.tid AS blocked_thread_tid,
196  blocking_thread.is_main_thread AS is_blocking_thread_main,
197  blocking_thread.tid AS blocking_thread_tid,
198  binder_reply.id AS binder_reply_id,
199  binder_reply.ts AS binder_reply_ts,
200  binder_reply_thread.tid AS binder_reply_tid,
201  process.pid
202FROM slice
203JOIN thread_track
204  ON thread_track.id = slice.track_id
205LEFT JOIN thread
206  USING (utid)
207LEFT JOIN process
208  USING (upid)
209LEFT JOIN internal_broken_android_monitor_contention ON internal_broken_android_monitor_contention.id = slice.id
210LEFT JOIN ANCESTOR_SLICE(slice.id) binder_reply ON binder_reply.name = 'binder reply'
211LEFT JOIN thread_track binder_reply_thread_track ON binder_reply.track_id = binder_reply_thread_track.id
212LEFT JOIN thread binder_reply_thread ON binder_reply_thread_track.utid = binder_reply_thread.utid
213JOIN thread blocking_thread ON blocking_thread.tid = blocking_tid AND blocking_thread.upid = thread.upid
214WHERE slice.name LIKE 'monitor contention%'
215  AND slice.dur != -1
216  AND internal_broken_android_monitor_contention.id IS NULL
217  AND short_blocking_method IS NOT NULL
218  AND short_blocked_method IS NOT NULL
219GROUP BY slice.id;
220
221-- Contains parsed monitor contention slices with the parent-child relationships.
222--
223-- @column parent_id Id of slice blocking the blocking_thread.
224-- @column blocking_method Name of the method holding the lock.
225-- @column blocked_methhod Name of the method trying to acquire the lock.
226-- @column short_blocking_method Blocking_method without arguments and return types.
227-- @column short_blocked_method Blocked_method without arguments and return types.
228-- @column blocking_src File location of blocking_method in form <filename:linenumber>.
229-- @column blocked_src File location of blocked_method in form <filename:linenumber>.
230-- @column waiter_count Zero indexed number of threads trying to acquire the lock.
231-- @column blocking_utid Utid of thread holding the lock.
232-- @column blocking_thread_name Thread name of thread holding the lock.
233-- @column upid Upid of process experiencing lock contention.
234-- @column process_name Process name of process experiencing lock contention.
235-- @column id Slice id of lock contention.
236-- @column ts Timestamp of lock contention start.
237-- @column dur Duration of lock contention.
238-- @column track_id Thread track id of blocked thread.
239-- @column is_blocked_main_thread Whether the blocked thread is the main thread.
240-- @column is_blocking_main_thread Whether the blocking thread is the main thread.
241-- @column binder_reply_id Slice id of binder reply slice if lock contention was part of a binder txn.
242-- @column binder_reply_ts Timestamp of binder reply slice if lock contention was part of a binder txn.
243-- @column binder_reply_tid Tid of binder reply slice if lock contention was part of a binder txn.
244CREATE TABLE android_monitor_contention_chain
245AS
246SELECT parent.id AS parent_id, child.* FROM android_monitor_contention child
247LEFT JOIN android_monitor_contention parent ON child.blocked_utid = parent.blocking_utid
248    AND parent.ts BETWEEN child.ts AND child.ts + child.dur;
249
250CREATE VIEW internal_blocking_thread_state
251AS
252SELECT utid AS blocking_utid, ts, dur, state, blocked_function
253FROM thread_state;
254
255-- Contains the span join of the |android_monitor_contention_chain| with their
256-- blocking thread thread state.
257--
258-- @column parent_id Id of slice blocking the blocking_thread.
259-- @column blocking_method Name of the method holding the lock.
260-- @column blocked_methhod Name of the method trying to acquire the lock.
261-- @column short_blocking_method Blocking_method without arguments and return types.
262-- @column short_blocked_method Blocked_method without arguments and return types.
263-- @column blocking_src File location of blocking_method in form <filename:linenumber>.
264-- @column blocked_src File location of blocked_method in form <filename:linenumber>.
265-- @column waiter_count Zero indexed number of threads trying to acquire the lock.
266-- @column blocking_utid Utid of thread holding the lock.
267-- @column blocking_thread_name Thread name of thread holding the lock.
268-- @column upid Upid of process experiencing lock contention.
269-- @column process_name Process name of process experiencing lock contention.
270-- @column id Slice id of lock contention.
271-- @column ts Timestamp of lock contention start.
272-- @column dur Duration of lock contention.
273-- @column track_id Thread track id of blocked thread.
274-- @column is_blocked_main_thread Whether the blocked thread is the main thread.
275-- @column is_blocking_main_thread Whether the blocking thread is the main thread.
276-- @column binder_reply_id Slice id of binder reply slice if lock contention was part of a binder txn.
277-- @column binder_reply_ts Timestamp of binder reply slice if lock contention was part of a binder txn.
278-- @column binder_reply_tid Tid of binder reply slice if lock contention was part of a binder txn.
279-- @column blocking_utid Utid of the blocking |thread_state|.
280-- @column ts Timestamp of the blocking |thread_state|.
281-- @column state Thread state of the blocking thread.
282-- @column blocked_function Blocked kernel function of the blocking thread.
283CREATE VIRTUAL TABLE android_monitor_contention_chain_thread_state
284USING
285  SPAN_JOIN(android_monitor_contention_chain PARTITIONED blocking_utid,
286            internal_blocking_thread_state PARTITIONED blocking_utid);
287
288-- Aggregated blocked_functions on the 'blocking thread', the thread holding the lock.
289-- This builds on the data from |android_monitor_contention_chain| and
290-- for each contention slice, it returns the aggregated sum of all the thread states on the
291-- blocking thread.
292--
293-- @column id Slice id of the monitor contention.
294-- @column thread_state A |thread_state| that occurred in the blocking thread during the contention.
295-- @column thread_state_dur Total time the blocking thread spent in the |thread_state| during
296-- contention.
297-- @column thread_state_count Count of all times the blocking thread entered |thread_state| during
298-- the contention.
299CREATE VIEW android_monitor_contention_chain_thread_state_by_txn
300AS
301SELECT
302  id,
303  state AS thread_state,
304  SUM(dur) AS thread_state_dur,
305  COUNT(dur) AS thread_state_count
306FROM android_monitor_contention_chain_thread_state
307GROUP BY id, thread_state;
308
309-- Aggregated blocked_functions on the 'blocking thread', the thread holding the lock.
310-- This builds on the data from |android_monitor_contention_chain| and
311-- for each contention, it returns the aggregated sum of all the kernel
312-- blocked function durations on the blocking thread.
313--
314-- @column id Slice id of the monitor contention.
315-- @column blocked_function Blocked kernel function in a thread state in the blocking thread during
316-- the contention.
317-- @column blocked_function_dur Total time the blocking thread spent in the |blocked_function|
318-- during the contention.
319-- @column blocked_function_count Count of all times the blocking thread executed the
320-- |blocked_function| during the contention.
321CREATE VIEW android_monitor_contention_chain_blocked_functions_by_txn
322AS
323SELECT
324  id,
325  blocked_function,
326  SUM(dur) AS blocked_function_dur,
327  COUNT(dur) AS blocked_function_count
328FROM android_monitor_contention_chain_thread_state
329WHERE blocked_function IS NOT NULL
330GROUP BY id, blocked_function;
331