• 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
16INCLUDE PERFETTO MODULE intervals.intersect;
17
18-- The time a thread spent in each scheduling state during it's lifetime.
19CREATE PERFETTO TABLE sched_time_in_state_for_thread (
20  -- Utid of the thread.
21  utid JOINID(thread.id),
22  -- Total runtime of thread.
23  total_runtime LONG,
24  -- One of the scheduling states of kernel thread.
25  state STRING,
26  -- Total time spent in the scheduling state.
27  time_in_state LONG,
28  -- Percentage of time thread spent in scheduling state in [0-100] range.
29  percentage_in_state LONG
30) AS
31WITH
32  total_dur AS (
33    SELECT
34      utid,
35      sum(dur) AS sum_dur
36    FROM thread_state
37    GROUP BY
38      1
39  ),
40  summed AS (
41    SELECT
42      utid,
43      state,
44      sum(dur) AS time_in_state
45    FROM thread_state
46    GROUP BY
47      1,
48      2
49  )
50SELECT
51  utid,
52  sum_dur AS total_runtime,
53  state,
54  time_in_state,
55  (
56    time_in_state * 100
57  ) / (
58    sum_dur
59  ) AS percentage_in_state
60FROM summed
61JOIN total_dur
62  USING (utid);
63
64CREATE PERFETTO MACRO _case_for_state(
65    state Expr
66)
67RETURNS Expr AS
68max(CASE WHEN state = $state THEN percentage_in_state END);
69
70-- Summary of time spent by thread in each scheduling state, in percentage ([0, 100]
71-- ranges). Sum of all states might be smaller than 100, as those values
72-- are rounded down.
73CREATE PERFETTO TABLE sched_percentage_of_time_in_state (
74  -- Utid of the thread.
75  utid JOINID(thread.id),
76  -- Percentage of time thread spent in running ('Running') state in [0, 100]
77  -- range.
78  running LONG,
79  -- Percentage of time thread spent in runnable ('R') state in [0, 100]
80  -- range.
81  runnable LONG,
82  -- Percentage of time thread spent in preempted runnable ('R+') state in
83  -- [0, 100] range.
84  runnable_preempted LONG,
85  -- Percentage of time thread spent in sleeping ('S') state in [0, 100] range.
86  sleeping LONG,
87  -- Percentage of time thread spent in uninterruptible sleep ('D') state in
88  -- [0, 100] range.
89  uninterruptible_sleep LONG,
90  -- Percentage of time thread spent in other ('T', 't', 'X', 'Z', 'x', 'I',
91  -- 'K', 'W', 'P', 'N') states in [0, 100] range.
92  other LONG
93) AS
94SELECT
95  utid,
96  _case_for_state!('Running') AS running,
97  _case_for_state!('R') AS runnable,
98  _case_for_state!('R+') AS runnable_preempted,
99  _case_for_state!('S') AS sleeping,
100  _case_for_state!('D') AS uninterruptible_sleep,
101  sum(
102    CASE
103      WHEN state IN ('T', 't', 'X', 'Z', 'x', 'I', 'K', 'W', 'P', 'N')
104      THEN time_in_state
105    END
106  ) * 100 / total_runtime AS other
107FROM sched_time_in_state_for_thread
108GROUP BY
109  utid;
110
111-- Time the thread spent each state in a given interval.
112--
113-- This function is only designed to run over a small number of intervals
114-- (10-100 at most). It will be *very slow* for large sets of intervals.
115--
116-- Specifically for any non-trivial subset of thread slices, prefer using
117-- `thread_slice_time_in_state` in the `slices.time_in_state` module for this
118-- purpose instead.
119CREATE PERFETTO FUNCTION sched_time_in_state_for_thread_in_interval(
120    -- The start of the interval.
121    ts TIMESTAMP,
122    -- The duration of the interval.
123    dur DURATION,
124    -- The utid of the thread.
125    utid JOINID(thread.id)
126)
127RETURNS TABLE (
128  -- The scheduling state (from the `thread_state` table).
129  --
130  -- Use the `sched_state_to_human_readable_string` function in the `sched`
131  -- package to get full name.
132  state STRING,
133  -- A (posssibly NULL) boolean indicating, if the device was in uninterruptible
134  -- sleep, if it was an IO sleep.
135  io_wait BOOL,
136  -- If the `state` is uninterruptible sleep, `io_wait` indicates if it was
137  -- an IO sleep. Will be null if `state` is *not* uninterruptible sleep or if
138  -- we cannot tell if it was an IO sleep or not.
139  --
140  -- Only available on Android when
141  -- `sched/sched_blocked_reason` ftrace tracepoint is enabled.
142  blocked_function LONG,
143  -- The duration of time the threads slice spent for each
144  -- (state, io_wait, blocked_function) tuple.
145  dur DURATION
146) AS
147SELECT
148  state,
149  io_wait,
150  blocked_function,
151  sum(ii.dur) AS dur
152FROM thread_state
153JOIN (
154  SELECT
155    *
156  FROM _interval_intersect_single!(
157    $ts, $dur,
158    (
159      SELECT id, ts, dur
160      FROM thread_state
161      WHERE utid = $utid AND dur > 0
162    )
163  )
164) AS ii
165  USING (id)
166GROUP BY
167  1,
168  2,
169  3
170ORDER BY
171  4 DESC;
172
173-- Time the thread spent each state and cpu in a given interval.
174CREATE PERFETTO FUNCTION sched_time_in_state_and_cpu_for_thread_in_interval(
175    -- The start of the interval.
176    ts TIMESTAMP,
177    -- The duration of the interval.
178    dur DURATION,
179    -- The utid of the thread.
180    utid JOINID(thread.id)
181)
182RETURNS TABLE (
183  -- Thread state (from the `thread_state` table).
184  -- Use `sched_state_to_human_readable_string` function to get full name.
185  state STRING,
186  -- A (posssibly NULL) boolean indicating, if the device was in uninterruptible
187  -- sleep, if it was an IO sleep.
188  io_wait BOOL,
189  -- Id of the CPU.
190  cpu LONG,
191  -- Some states can specify the blocked function. Usually NULL.
192  blocked_function LONG,
193  -- Total time spent with this state, cpu and blocked function.
194  dur DURATION
195) AS
196SELECT
197  state,
198  io_wait,
199  cpu,
200  blocked_function,
201  sum(ii.dur) AS dur
202FROM thread_state
203JOIN (
204  SELECT
205    *
206  FROM _interval_intersect_single!(
207    $ts, $dur,
208    (SELECT id, ts, dur
209    FROM thread_state
210    WHERE utid = $utid AND dur > 0))
211) AS ii
212  USING (id)
213GROUP BY
214  1,
215  2,
216  3,
217  4
218ORDER BY
219  5 DESC;
220
221-- Time spent by CPU in each scheduling state in a provided interval.
222CREATE PERFETTO FUNCTION sched_time_in_state_for_cpu_in_interval(
223    -- CPU id.
224    cpu LONG,
225    -- Interval start.
226    ts TIMESTAMP,
227    -- Interval duration.
228    dur LONG
229)
230RETURNS TABLE (
231  -- End state. From `sched.end_state`.
232  end_state STRING,
233  -- Duration in state.
234  dur LONG
235) AS
236WITH
237  sched_for_cpu AS (
238    SELECT
239      id,
240      ts,
241      dur
242    FROM sched
243    WHERE
244      cpu = $cpu AND dur != -1
245  )
246SELECT
247  end_state,
248  sum(ii.dur) AS dur
249FROM sched
250JOIN _interval_intersect_single!($ts, $dur, sched_for_cpu) AS ii
251  USING (id)
252GROUP BY
253  end_state;
254