Migrate create_view_function to Perfetto SQL.
R=lalitm@google.com
Change-Id: I4fd050eb75540a2a8255e42a33de0b0b31fdd8a7
diff --git a/python/generators/sql_processing/docs_parse.py b/python/generators/sql_processing/docs_parse.py
index 079a600..8f17b1b 100644
--- a/python/generators/sql_processing/docs_parse.py
+++ b/python/generators/sql_processing/docs_parse.py
@@ -230,14 +230,14 @@
self._validate_only_contains_annotations(doc.annotations, {'@arg', '@ret'})
ret_type, ret_desc = self._parse_ret(doc.annotations, ret)
- name = self._parse_name(upper=True)
+ name = self._parse_name()
if not is_snake_case(name):
self._error('Function name %s is not snake_case (should be %s) ' %
(name, name.casefold()))
return Function(
- name=self._parse_name(upper=True),
+ name=name,
desc=self._parse_desc_not_empty(doc.description),
args=self._parse_args(doc.annotations, args),
return_type=ret_type,
@@ -273,8 +273,14 @@
self._validate_only_contains_annotations(doc.annotations,
{'@arg', '@column'})
+ name = self._parse_name()
+
+ if not is_snake_case(name):
+ self._error('Function name %s is not snake_case (should be %s) ' %
+ (name, name.casefold()))
+
return TableFunction(
- name=self._parse_name(upper=True),
+ name=name,
desc=self._parse_desc_not_empty(doc.description),
cols=self._parse_columns(doc.annotations, columns),
args=self._parse_args(doc.annotations, args),
diff --git a/python/generators/sql_processing/utils.py b/python/generators/sql_processing/utils.py
index 97d7d8f..c701ceb 100644
--- a/python/generators/sql_processing/utils.py
+++ b/python/generators/sql_processing/utils.py
@@ -130,6 +130,12 @@
'Use CREATE PERFETTO FUNCTION instead.\n'
f'Offending file: {path}')
+ if 'create_view_function' in line.casefold():
+ errors.append(
+ 'CREATE_VIEW_FUNCTION is deprecated in trace processor. '
+ 'Use CREATE PERFETTO FUNCTION $name RETURNS TABLE instead.\n'
+ f'Offending file: {path}')
+
if 'import(' in line.casefold():
errors.append('SELECT IMPORT is deprecated in trace processor. '
'Use INCLUDE PERFETTO MODULE instead.\n'
diff --git a/python/test/stdlib_unittest.py b/python/test/stdlib_unittest.py
index d1a90be..479c603 100644
--- a/python/test/stdlib_unittest.py
+++ b/python/test/stdlib_unittest.py
@@ -104,7 +104,7 @@
{ARGS_STR}
{COLS_STR}
SELECT CREATE_VIEW_FUNCTION(
- 'FOO_VIEW_FN({ARGS_SQL_STR})',
+ 'foo_view_fn({ARGS_SQL_STR})',
'{COLS_SQL_STR}',
'{SQL_STR}'
);
@@ -112,7 +112,7 @@
self.assertListEqual(res.errors, [])
fn = res.table_functions[0]
- self.assertEqual(fn.name, 'FOO_VIEW_FN')
+ self.assertEqual(fn.name, 'foo_view_fn')
self.assertEqual(fn.desc, 'First line. Second line.')
self.assertEqual(
fn.args, {
diff --git a/src/trace_processor/metrics/sql/android/android_startup.sql b/src/trace_processor/metrics/sql/android/android_startup.sql
index 5a92db8..d2efb76 100644
--- a/src/trace_processor/metrics/sql/android/android_startup.sql
+++ b/src/trace_processor/metrics/sql/android/android_startup.sql
@@ -43,20 +43,16 @@
-- Returns the slices for forked processes. Never present in hot starts.
-- Prefer this over process start_ts, since the process might have
-- been preforked.
-SELECT CREATE_VIEW_FUNCTION(
- 'ZYGOTE_FORK_FOR_LAUNCH(startup_id INT)',
- 'ts INT, dur INT',
- '
- SELECT slice.ts, slice.dur
- FROM android_startups l
- JOIN slice ON (
- l.ts < slice.ts AND
- slice.ts + slice.dur < l.ts_end AND
- STR_SPLIT(slice.name, ": ", 1) = l.package
- )
- WHERE l.startup_id = $startup_id AND slice.name GLOB "Start proc: *"
- '
-);
+CREATE PERFETTO FUNCTION zygote_fork_for_launch(startup_id INT)
+RETURNS TABLE(ts INT, dur INT) AS
+SELECT slice.ts, slice.dur
+FROM android_startups l
+JOIN slice ON (
+ l.ts < slice.ts AND
+ slice.ts + slice.dur < l.ts_end AND
+ STR_SPLIT(slice.name, ': ', 1) = l.package
+)
+WHERE l.startup_id = $startup_id AND slice.name GLOB 'Start proc: *';
-- Returns the fully drawn slice proto given a launch id.
CREATE PERFETTO FUNCTION report_fully_drawn_for_launch(startup_id INT)
@@ -79,17 +75,14 @@
);
-- Given a launch id and GLOB for a slice name, returns the N longest slice name and duration.
-SELECT CREATE_VIEW_FUNCTION(
- 'GET_LONG_SLICES_FOR_LAUNCH(startup_id INT, slice_name STRING, top_n INT)',
- 'slice_name STRING, slice_dur INT',
- '
- SELECT slice_name, slice_dur
- FROM android_thread_slices_for_all_startups s
- WHERE s.startup_id = $startup_id AND s.slice_name GLOB $slice_name
- ORDER BY slice_dur DESC
- LIMIT $top_n
- '
-);
+CREATE PERFETTO FUNCTION get_long_slices_for_launch(
+ startup_id INT, slice_name STRING, top_n INT)
+RETURNS TABLE(slice_name STRING, slice_dur INT) AS
+SELECT slice_name, slice_dur
+FROM android_thread_slices_for_all_startups s
+WHERE s.startup_id = $startup_id AND s.slice_name GLOB $slice_name
+ORDER BY slice_dur DESC
+LIMIT $top_n;
-- Define the view
DROP VIEW IF EXISTS startup_view;
diff --git a/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql b/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql
index 9c891af..0814320 100644
--- a/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql
+++ b/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql
@@ -190,30 +190,30 @@
-- slice for each of the layers. GROUP BY to deduplicate these rows.
GROUP BY cuj_id, app_upid, app_vsync, sf_upid, sf_vsync;
-SELECT CREATE_VIEW_FUNCTION(
- 'FIND_ANDROID_JANK_CUJ_SF_MAIN_THREAD_SLICE(slice_name_glob STRING)',
- 'cuj_id INT, utid INT, vsync INT, id INT, name STRING, ts LONG, dur LONG, ts_end LONG',
- '
- WITH sf_vsync AS (
- SELECT DISTINCT cuj_id, sf_vsync AS vsync
- FROM android_jank_cuj_app_to_sf_match)
- SELECT
- cuj_id,
- utid,
- sf_vsync.vsync,
- slice.id,
- slice.name,
- slice.ts,
- slice.dur,
- slice.ts + slice.dur AS ts_end
- FROM slice
- JOIN android_jank_cuj_sf_main_thread main_thread USING (track_id)
- JOIN sf_vsync
- ON vsync_from_name(slice.name) = sf_vsync.vsync
- WHERE slice.name GLOB $slice_name_glob AND slice.dur > 0
- ORDER BY cuj_id, vsync;
- '
-);
+CREATE PERFETTO FUNCTION find_android_jank_cuj_sf_main_thread_slice(
+ slice_name_glob STRING)
+RETURNS TABLE(
+ cuj_id INT, utid INT, vsync INT, id INT,
+ name STRING, ts LONG, dur LONG, ts_end LONG)
+AS
+WITH sf_vsync AS (
+ SELECT DISTINCT cuj_id, sf_vsync AS vsync
+ FROM android_jank_cuj_app_to_sf_match)
+SELECT
+ cuj_id,
+ utid,
+ sf_vsync.vsync,
+ slice.id,
+ slice.name,
+ slice.ts,
+ slice.dur,
+ slice.ts + slice.dur AS ts_end
+FROM slice
+JOIN android_jank_cuj_sf_main_thread main_thread USING (track_id)
+JOIN sf_vsync
+ ON vsync_from_name(slice.name) = sf_vsync.vsync
+WHERE slice.name GLOB $slice_name_glob AND slice.dur > 0
+ORDER BY cuj_id, vsync;
DROP TABLE IF EXISTS android_jank_cuj_sf_commit_slice;
CREATE PERFETTO TABLE android_jank_cuj_sf_commit_slice AS
diff --git a/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql b/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql
index b647721..d3fc193 100644
--- a/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql
+++ b/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql
@@ -25,22 +25,18 @@
-- Some CUJs use a dedicated thread for Choreographer callbacks
OR (p.main_thread_override = thread.name);
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_JANK_CUJ_APP_THREAD(thread_name STRING)',
- 'cuj_id INT, upid INT, utid INT, name STRING, track_id INT',
- '
- SELECT
- cuj_id,
- cuj.upid,
- utid,
- thread.name,
- thread_track.id AS track_id
- FROM thread
- JOIN android_jank_cuj cuj USING (upid)
- JOIN thread_track USING (utid)
- WHERE thread.name = $thread_name;
- '
-);
+CREATE PERFETTO FUNCTION android_jank_cuj_app_thread(thread_name STRING)
+RETURNS TABLE(cuj_id INT, upid INT, utid INT, name STRING, track_id INT) AS
+SELECT
+ cuj_id,
+ cuj.upid,
+ utid,
+ thread.name,
+ thread_track.id AS track_id
+FROM thread
+JOIN android_jank_cuj cuj USING (upid)
+JOIN thread_track USING (utid)
+WHERE thread.name = $thread_name;
DROP TABLE IF EXISTS android_jank_cuj_render_thread;
CREATE PERFETTO TABLE android_jank_cuj_render_thread AS
@@ -68,17 +64,13 @@
JOIN thread_track USING (utid)
WHERE thread.is_main_thread;
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_JANK_CUJ_SF_THREAD(thread_name STRING)',
- 'upid INT, utid INT, name STRING, track_id INT',
- '
- SELECT upid, utid, thread.name, thread_track.id AS track_id
- FROM thread
- JOIN android_jank_cuj_sf_process sf_process USING (upid)
- JOIN thread_track USING (utid)
- WHERE thread.name = $thread_name;
- '
-);
+CREATE PERFETTO FUNCTION android_jank_cuj_sf_thread(thread_name STRING)
+RETURNS TABLE(upid INT, utid INT, name STRING, track_id INT) AS
+SELECT upid, utid, thread.name, thread_track.id AS track_id
+FROM thread
+JOIN android_jank_cuj_sf_process sf_process USING (upid)
+JOIN thread_track USING (utid)
+WHERE thread.name = $thread_name;
DROP TABLE IF EXISTS android_jank_cuj_sf_gpu_completion_thread;
CREATE PERFETTO TABLE android_jank_cuj_sf_gpu_completion_thread AS
diff --git a/src/trace_processor/metrics/sql/android/p_state.sql b/src/trace_processor/metrics/sql/android/p_state.sql
index 79d2155..b334fcd 100644
--- a/src/trace_processor/metrics/sql/android/p_state.sql
+++ b/src/trace_processor/metrics/sql/android/p_state.sql
@@ -38,35 +38,32 @@
p_state_cpu_idle_counter PARTITIONED cpu
);
+CREATE PERFETTO FUNCTION p_state_over_interval(
+ start_ns LONG, end_ns LONG)
+RETURNS TABLE(cpu INT, freq_khz INT, idle_value INT, dur_ns INT)
+AS
+WITH sched_freq_idle_windowed AS (
+ SELECT
+ freq_khz,
+ idle_value,
+ cpu,
+ IIF(ts + dur <= $end_ns, ts + dur, $end_ns) - IIF(ts >= $start_ns, ts, $start_ns) AS dur
+ FROM
+ p_state_sched_freq_idle
+ WHERE
+ ts + dur > $start_ns
+ AND ts < $end_ns
+)
SELECT
- CREATE_VIEW_FUNCTION(
- 'P_STATE_OVER_INTERVAL(start_ns LONG, end_ns LONG)',
- 'cpu INT, freq_khz INT, idle_value INT, dur_ns INT',
- '
- WITH sched_freq_idle_windowed AS (
- SELECT
- freq_khz,
- idle_value,
- cpu,
- IIF(ts + dur <= $end_ns, ts + dur, $end_ns) - IIF(ts >= $start_ns, ts, $start_ns) AS dur
- FROM
- p_state_sched_freq_idle
- WHERE
- ts + dur > $start_ns
- AND ts < $end_ns
- )
- SELECT
- cast(cpu AS int) AS cpu,
- cast(freq_khz AS int) AS freq_khz,
- cast(idle_value AS int) AS idle_value,
- cast(sum(dur) AS int) AS dur_ns
- FROM
- sched_freq_idle_windowed
- WHERE
- freq_khz > 0
- GROUP BY
- cpu,
- freq_khz,
- idle_value
- '
- );
+ cast(cpu AS int) AS cpu,
+ cast(freq_khz AS int) AS freq_khz,
+ cast(idle_value AS int) AS idle_value,
+ cast(sum(dur) AS int) AS dur_ns
+FROM
+ sched_freq_idle_windowed
+WHERE
+ freq_khz > 0
+GROUP BY
+ cpu,
+ freq_khz,
+ idle_value;
diff --git a/src/trace_processor/metrics/sql/android/startup/slice_functions.sql b/src/trace_processor/metrics/sql/android/startup/slice_functions.sql
index e003302..7a12590 100644
--- a/src/trace_processor/metrics/sql/android/startup/slice_functions.sql
+++ b/src/trace_processor/metrics/sql/android/startup/slice_functions.sql
@@ -138,17 +138,14 @@
ELSE $loc
END || ": " || $status || "/" || $filter_str || "/" || $reason;
-SELECT CREATE_VIEW_FUNCTION(
- 'BINDER_TRANSACTION_REPLY_SLICES_FOR_LAUNCH(startup_id INT, threshold DOUBLE)',
- 'name STRING',
- '
- SELECT reply.name AS name
- FROM ANDROID_BINDER_TRANSACTION_SLICES_FOR_STARTUP($startup_id, $threshold) request
- JOIN following_flow(request.id) arrow
- JOIN slice reply ON reply.id = arrow.slice_in
- WHERE reply.dur > $threshold AND request.is_main_thread
- '
-);
+CREATE PERFETTO FUNCTION binder_transaction_reply_slices_for_launch(
+ startup_id INT, threshold DOUBLE)
+RETURNS TABLE(name STRING) AS
+SELECT reply.name AS name
+FROM android_binder_transaction_slices_for_startup($startup_id, $threshold) request
+JOIN following_flow(request.id) arrow
+JOIN slice reply ON reply.id = arrow.slice_in
+WHERE reply.dur > $threshold AND request.is_main_thread;
-- Given a launch id, return if unlock is running by systemui during the launch.
CREATE PERFETTO FUNCTION is_unlock_running_during_launch(startup_id LONG)
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql b/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql
index e80913e..e483965 100644
--- a/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql
+++ b/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql
@@ -23,30 +23,38 @@
-- names. For example, LongTaskTracker slices may have associated IPC
-- metadata, or InterestingTask slices for input may have associated IPC to
-- determine whether the task is fling/etc.
-SELECT CREATE_VIEW_FUNCTION(
- 'SELECT_LONG_TASK_SLICES(name STRING)',
- 'interface_name STRING, ipc_hash INT, message_type STRING, id INT, task_name STRING',
- '
- WITH slices_with_mojo_data AS (
- SELECT
- EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
- EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
- CASE
- WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
- ELSE "message"
- END AS message_type,
- id
- FROM slice
- WHERE
- category GLOB "*scheduler.long_tasks*"
- AND name = $name
- )
- SELECT
- *,
- printf("%s %s(hash=%s)", interface_name, message_type, ipc_hash) as task_name
- FROM slices_with_mojo_data;
- '
-);
+CREATE PERFETTO FUNCTION select_long_task_slices(name STRING)
+RETURNS TABLE(
+ interface_name STRING,
+ ipc_hash INT,
+ message_type STRING,
+ id INT,
+ task_name STRING)
+AS
+WITH slices_with_mojo_data AS (
+ SELECT
+ EXTRACT_ARG(
+ arg_set_id,
+ "chrome_mojo_event_info.mojo_interface_tag"
+ ) AS interface_name,
+ EXTRACT_ARG(
+ arg_set_id,
+ "chrome_mojo_event_info.ipc_hash"
+ ) AS ipc_hash,
+ CASE
+ WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
+ ELSE "message"
+ END AS message_type,
+ id
+ FROM slice
+ WHERE
+ category GLOB "*scheduler.long_tasks*"
+ AND name = $name
+)
+SELECT
+ *,
+ printf("%s %s(hash=%s)", interface_name, message_type, ipc_hash) as task_name
+FROM slices_with_mojo_data;
CREATE PERFETTO FUNCTION is_long_choreographer_task(dur LONG)
RETURNS BOOL AS
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql b/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql
index ba96dc3..3cf320c 100644
--- a/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql
+++ b/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql
@@ -23,23 +23,20 @@
-- browser interval. This may differ based on whether the scenario is for
-- topLevel events or LongTask events.
-SELECT CREATE_VIEW_FUNCTION(
- '{{function_prefix}}SELECT_SLOW_BROWSER_TASKS()',
- 'full_name STRING, dur INT, ts INT, id INT, upid INT, thread_dur INT',
- 'SELECT
- task_table.full_name AS full_name,
- task_table.dur AS dur,
- task_table.ts AS ts,
- task_table.id AS id,
- task_table.upid AS upid,
- thread_dur
- FROM
- {{task_table_name}} task_table
- WHERE
- task_table.dur >= {{duration_causing_jank_ms}} * 1e6
- AND task_table.thread_name = "CrBrowserMain"
- '
-);
+CREATE PERFETTO FUNCTION {{function_prefix}}SELECT_SLOW_BROWSER_TASKS()
+RETURNS TABLE(full_name STRING, dur INT, ts INT, id INT, upid INT, thread_dur INT) AS
+SELECT
+ task_table.full_name AS full_name,
+ task_table.dur AS dur,
+ task_table.ts AS ts,
+ task_table.id AS id,
+ task_table.upid AS upid,
+ thread_dur
+FROM
+ {{task_table_name}} task_table
+WHERE
+ task_table.dur >= {{duration_causing_jank_ms}} * 1e6
+ AND task_table.thread_name = "CrBrowserMain";
-- Get the tasks that was running for more than 8ms within windows
-- that we could have started processing input but did not on the
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql b/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql
index 521f2fc..2cfdce0 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql
@@ -211,15 +211,18 @@
-- @column slice_dur Duration of the slice.
-- @column thread_name Name of the thread with the slice.
-- @column arg_set_id Arg set id.
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(startup_id INT, slice_name STRING)',
- 'slice_name STRING, slice_ts INT, slice_dur INT, thread_name STRING, arg_set_id INT',
- '
- SELECT slice_name, slice_ts, slice_dur, thread_name, arg_set_id
- FROM android_thread_slices_for_all_startups
- WHERE startup_id = $startup_id AND slice_name GLOB $slice_name
- '
-);
+CREATE PERFETTO FUNCTION android_slices_for_startup_and_slice_name(
+ startup_id INT, slice_name STRING)
+RETURNS TABLE(
+ slice_name STRING,
+ slice_ts INT,
+ slice_dur INT,
+ thread_name STRING,
+ arg_set_id INT
+) AS
+SELECT slice_name, slice_ts, slice_dur, thread_name, arg_set_id
+FROM android_thread_slices_for_all_startups
+WHERE startup_id = $startup_id AND slice_name GLOB $slice_name;
-- Returns binder transaction slices for a given startup id with duration over threshold.
--
@@ -231,18 +234,30 @@
-- @column process Name of the process with slice.
-- @column arg_set_id Arg set id.
-- @column is_main_thread Whether is main thread.
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_BINDER_TRANSACTION_SLICES_FOR_STARTUP(startup_id INT, threshold DOUBLE)',
- 'id INT, slice_dur INT, thread_name STRING, process STRING, arg_set_id INT, is_main_thread BOOL',
- '
- SELECT slice_id as id, slice_dur, thread_name, process.name as process, s.arg_set_id, is_main_thread
- FROM android_thread_slices_for_all_startups s
- JOIN process ON (
- EXTRACT_ARG(s.arg_set_id, "destination process") = process.pid
- )
- WHERE startup_id = $startup_id AND slice_name GLOB "binder transaction" AND slice_dur > $threshold
- '
-);
+CREATE PERFETTO FUNCTION android_binder_transaction_slices_for_startup(
+ startup_id INT, threshold DOUBLE)
+RETURNS TABLE(
+ id INT,
+ slice_dur INT,
+ thread_name STRING,
+ process STRING,
+ arg_set_id INT,
+ is_main_thread BOOL
+) AS
+SELECT
+ slice_id as id,
+ slice_dur,
+ thread_name,
+ process.name as process,
+ s.arg_set_id,
+ is_main_thread
+FROM android_thread_slices_for_all_startups s
+JOIN process ON (
+ EXTRACT_ARG(s.arg_set_id, "destination process") = process.pid
+)
+WHERE startup_id = $startup_id
+ AND slice_name GLOB "binder transaction"
+ AND slice_dur > $threshold;
-- Returns duration of startup for slice name.
--
@@ -251,11 +266,13 @@
-- @arg startup_id LONG Startup id.
-- @arg slice_name STRING Slice name.
-- @ret INT Sum of duration.
-CREATE PERFETTO FUNCTION android_sum_dur_for_startup_and_slice(startup_id LONG, slice_name STRING)
+CREATE PERFETTO FUNCTION android_sum_dur_for_startup_and_slice(
+ startup_id LONG, slice_name STRING)
RETURNS INT AS
SELECT SUM(slice_dur)
FROM android_thread_slices_for_all_startups
-WHERE startup_id = $startup_id AND slice_name GLOB $slice_name;
+WHERE startup_id = $startup_id
+ AND slice_name GLOB $slice_name;
-- Returns duration of startup for slice name on main thread.
--
@@ -264,8 +281,11 @@
-- @arg startup_id LONG Startup id.
-- @arg slice_name STRING Slice name.
-- @ret INT Sum of duration.
-CREATE PERFETTO FUNCTION android_sum_dur_on_main_thread_for_startup_and_slice(startup_id LONG, slice_name STRING)
+CREATE PERFETTO FUNCTION android_sum_dur_on_main_thread_for_startup_and_slice(
+ startup_id LONG, slice_name STRING)
RETURNS INT AS
SELECT SUM(slice_dur)
FROM android_thread_slices_for_all_startups
-WHERE startup_id = $startup_id AND slice_name GLOB $slice_name AND is_main_thread;
+WHERE startup_id = $startup_id
+ AND slice_name GLOB $slice_name
+ AND is_main_thread;
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/thread.sql b/src/trace_processor/perfetto_sql/stdlib/android/thread.sql
index 3d6fa46..592b476 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/thread.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/thread.sql
@@ -28,34 +28,36 @@
-- @column pid Process pid creating threads.
-- @column thread_name_prefix String prefix of thread names created.
-- @column max_count_per_sec Max number of threads created within a time window.
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_THREAD_CREATION_SPAM(min_thread_dur FLOAT, sliding_window_dur FLOAT)',
- 'process_name STRING, pid INT, thread_name_prefix STRING, max_count_per_sec INT',
- '
- WITH
- x AS (
- SELECT
- pid,
- upid,
- INTERNAL_THREAD_PREFIX(thread.name) AS thread_name_prefix,
- process.name AS process_name,
- COUNT(thread.start_ts)
- OVER (
- PARTITION BY upid, thread.name
- ORDER BY thread.start_ts
- RANGE BETWEEN CURRENT ROW AND CAST($sliding_window_dur AS INT64) FOLLOWING
- ) AS count
- FROM thread
- JOIN process
- USING (upid)
- WHERE
- ($min_thread_dur AND (thread.end_ts - thread.start_ts) <= $min_thread_dur)
- OR $min_thread_dur IS NULL
- )
- SELECT process_name, pid, thread_name_prefix, MAX(count) AS max_count_per_sec
- FROM x
- GROUP BY upid, thread_name_prefix
- HAVING max_count_per_sec > 0
- ORDER BY count DESC;
- '
-);
+CREATE PERFETTO FUNCTION android_thread_creation_spam(
+ min_thread_dur FLOAT, sliding_window_dur FLOAT)
+RETURNS TABLE(
+ process_name STRING,
+ pid INT,
+ thread_name_prefix STRING,
+ max_count_per_sec INT
+) AS
+WITH
+x AS (
+ SELECT
+ pid,
+ upid,
+ INTERNAL_THREAD_PREFIX(thread.name) AS thread_name_prefix,
+ process.name AS process_name,
+ COUNT(thread.start_ts)
+ OVER (
+ PARTITION BY upid, thread.name
+ ORDER BY thread.start_ts
+ RANGE BETWEEN CURRENT ROW AND CAST($sliding_window_dur AS INT64) FOLLOWING
+ ) AS count
+ FROM thread
+ JOIN process
+ USING (upid)
+ WHERE
+ ($min_thread_dur AND (thread.end_ts - thread.start_ts) <= $min_thread_dur)
+ OR $min_thread_dur IS NULL
+)
+SELECT process_name, pid, thread_name_prefix, MAX(count) AS max_count_per_sec
+FROM x
+GROUP BY upid, thread_name_prefix
+HAVING max_count_per_sec > 0
+ORDER BY count DESC;
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
index 167bca2..44e6e1e 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
@@ -95,20 +95,22 @@
-- @column ipc_hash Hash of the IPC call.
-- @column message_type Message type (e.g. reply).
-- @column id The slice ID.
-SELECT CREATE_VIEW_FUNCTION(
- 'CHROME_SELECT_LONG_TASK_SLICES(name STRING)',
- 'interface_name STRING, ipc_hash INT, message_type STRING, id INT',
- 'SELECT
- EXTRACT_ARG(s.arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
- EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
- CASE
- WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
- ELSE "message"
- END AS message_type,
- s.id
- FROM slice s
- WHERE
- category GLOB "*scheduler.long_tasks*"
- AND name = $name
- '
-);
+CREATE PERFETTO FUNCTION chrome_select_long_task_slices(name STRING)
+RETURNS TABLE(
+ interface_name STRING,
+ ipc_hash INT,
+ message_type STRING,
+ id INT
+) AS
+SELECT
+ EXTRACT_ARG(s.arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
+ EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
+ CASE
+ WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
+ ELSE "message"
+ END AS message_type,
+ s.id
+FROM slice s
+WHERE
+ category GLOB "*scheduler.long_tasks*"
+ AND name = $name;
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
index cd45beb..6890ce7 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
@@ -43,7 +43,8 @@
LIMIT 1;
-- Human-readable aliases for a few key navigation tasks.
-CREATE PERFETTO FUNCTION internal_human_readable_navigation_task_name(task_name STRING)
+CREATE PERFETTO FUNCTION internal_human_readable_navigation_task_name(
+ task_name STRING)
RETURNS STRING AS
SELECT
CASE
@@ -310,22 +311,20 @@
-- @column kind The type of Java slice.
-- @column ts The timestamp of the slice.
-- @column name The name of the slice.
-SELECT CREATE_VIEW_FUNCTION(
- 'INTERNAL_SELECT_BEGIN_MAIN_FRAME_JAVA_SLICES(name STRING)',
- 'id INT, kind STRING, ts LONG, dur LONG, name STRING',
- 'SELECT
- id,
- "SingleThreadProxy::BeginMainFrame" AS kind,
- ts,
- dur,
- name
- FROM slice
- WHERE
- (name = $name
- AND internal_get_posted_from(arg_set_id) =
- "cc/trees/single_thread_proxy.cc:ScheduledActionSendBeginMainFrame")
- '
-);
+CREATE PERFETTO FUNCTION internal_select_begin_main_frame_java_slices(
+ name STRING)
+RETURNS TABLE(id INT, kind STRING, ts LONG, dur LONG, name STRING) AS
+SELECT
+ id,
+ "SingleThreadProxy::BeginMainFrame" AS kind,
+ ts,
+ dur,
+ name
+FROM slice
+WHERE
+ (name = $name
+ AND internal_get_posted_from(arg_set_id) =
+ "cc/trees/single_thread_proxy.cc:ScheduledActionSendBeginMainFrame");
-- A list of Chrome tasks which were performing operations with Java views,
-- together with the names of the these views.
@@ -436,17 +435,15 @@
ORDER by depth, ts
LIMIT 1;
-SELECT CREATE_VIEW_FUNCTION('INTERNAL_DESCENDANT_MOJO_SLICE(slice_id INT)',
- 'task_name STRING',
- '
- SELECT
- printf("%s %s (hash=%d)",
- mojo.interface_name, mojo.message_type, mojo.ipc_hash) AS task_name
- FROM slice task
- JOIN internal_chrome_mojo_slices mojo
- ON mojo.id = internal_get_descendant_mojo_slice_candidate($slice_id)
- WHERE task.id = $slice_id
- ');
+CREATE PERFETTO FUNCTION internal_descendant_mojo_slice(slice_id INT)
+RETURNS TABLE(task_name STRING) AS
+SELECT
+ printf("%s %s (hash=%d)",
+ mojo.interface_name, mojo.message_type, mojo.ipc_hash) AS task_name
+FROM slice task
+JOIN internal_chrome_mojo_slices mojo
+ ON mojo.id = internal_get_descendant_mojo_slice_candidate($slice_id)
+WHERE task.id = $slice_id;
-- A list of "Chrome tasks": top-level execution units (e.g. scheduler tasks /
-- IPCs / system callbacks) run by Chrome. For a given thread, the tasks
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/counters.sql b/src/trace_processor/perfetto_sql/stdlib/common/counters.sql
index 91e023d..a7f3157 100644
--- a/src/trace_processor/perfetto_sql/stdlib/common/counters.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/common/counters.sql
@@ -34,9 +34,8 @@
-- @column track_name Name of the counter track.
-- @column track_arg_set_id Counter track set id.
-- @column arg_set_id Counter arg set id.
-SELECT CREATE_VIEW_FUNCTION(
- 'COUNTER_WITH_DUR_FOR_TRACK(counter_track_id INT)',
- '
+CREATE PERFETTO FUNCTION counter_with_dur_for_track(counter_track_id INT)
+RETURNS TABLE(
ts LONG,
dur LONG,
value DOUBLE,
@@ -44,21 +43,18 @@
track_name STRING,
track_arg_set_id INT,
arg_set_id INT
- ',
- '
- SELECT
- ts,
- LEAD(ts, 1, trace_end()) OVER(ORDER BY ts) - ts AS dur,
- value,
- track.id AS track_id,
- track.name AS track_name,
- track.source_arg_set_id AS track_arg_set_id,
- counter.arg_set_id AS arg_set_id
- FROM counter
- JOIN counter_track track ON track.id = counter.track_id
- WHERE track.id = $counter_track_id
- '
-);
+) AS
+SELECT
+ ts,
+ LEAD(ts, 1, trace_end()) OVER(ORDER BY ts) - ts AS dur,
+ value,
+ track.id AS track_id,
+ track.name AS track_name,
+ track.source_arg_set_id AS track_arg_set_id,
+ counter.arg_set_id AS arg_set_id
+FROM counter
+JOIN counter_track track ON track.id = counter.track_id
+WHERE track.id = $counter_track_id;
-- COUNTER_WITH_DUR_FOR_TRACK but in a specified time.
-- Does calculation over the table ends - creates an artificial counter value at
@@ -75,33 +71,30 @@
-- @column track_name Name of the counter track.
-- @column track_arg_set_id Counter track set id.
-- @column arg_set_id Counter arg set id.
-SELECT CREATE_VIEW_FUNCTION(
- 'COUNTER_FOR_TIME_RANGE(counter_track_id INT, start_ts LONG, end_ts LONG)',
- '
- ts LONG,
- dur LONG,
- value DOUBLE,
- track_id INT,
- track_name STRING,
- track_arg_set_id INT,
- arg_set_id INT
- ',
- '
- SELECT
- IIF(ts < $start_ts, $start_ts, ts) AS ts,
- IIF(
- ts < $start_ts,
- dur - ($start_ts - ts),
- IIF(ts + dur > $end_ts, $end_ts - ts, dur)) AS dur,
- value,
- track_id,
- track_name,
- track_arg_set_id,
- arg_set_id
- FROM COUNTER_WITH_DUR_FOR_TRACK($counter_track_id)
- WHERE TRUE
- AND ts + dur >= $start_ts
- AND ts < $end_ts
- ORDER BY ts ASC;
-'
-);
\ No newline at end of file
+CREATE PERFETTO FUNCTION COUNTER_FOR_TIME_RANGE(
+ counter_track_id INT, start_ts LONG, end_ts LONG)
+RETURNS TABLE(
+ ts LONG,
+ dur LONG,
+ value DOUBLE,
+ track_id INT,
+ track_name STRING,
+ track_arg_set_id INT,
+ arg_set_id INT
+) AS
+SELECT
+ IIF(ts < $start_ts, $start_ts, ts) AS ts,
+ IIF(
+ ts < $start_ts,
+ dur - ($start_ts - ts),
+ IIF(ts + dur > $end_ts, $end_ts - ts, dur)) AS dur,
+ value,
+ track_id,
+ track_name,
+ track_arg_set_id,
+ arg_set_id
+FROM counter_with_dur_for_track($counter_track_id)
+WHERE TRUE
+ AND ts + dur >= $start_ts
+ AND ts < $end_ts
+ORDER BY ts ASC;
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql b/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql
index bbba1eb..8b3da9d 100644
--- a/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql
@@ -16,15 +16,13 @@
INCLUDE PERFETTO MODULE common.counters;
INCLUDE PERFETTO MODULE common.timestamps;
-SELECT CREATE_VIEW_FUNCTION(
- 'INTERNAL_NUMBER_GENERATOR(to INT)',
- 'num INT',
- 'WITH NUMS AS
- (SELECT 1 num UNION SELECT num + 1
- from NUMS
- WHERE num < $to)
- SELECT num FROM NUMS;'
-);
+CREATE PERFETTO FUNCTION internal_number_generator(to INT)
+RETURNS TABLE(num INT) AS
+WITH nums AS
+ (SELECT 1 num UNION SELECT num + 1
+ from NUMS
+ WHERE num < $to)
+SELECT num FROM nums;
--
-- Get durations for percentile
@@ -46,44 +44,43 @@
-- @arg end_ts LONG Timestamp of end of time range.
-- @column percentile All of the numbers from 1 to 100.
-- @column value Value for the percentile.
-SELECT CREATE_VIEW_FUNCTION(
- 'COUNTER_PERCENTILES_FOR_TIME_RANGE(counter_track_id INT, start_ts LONG, end_ts LONG)',
- 'percentile INT, value DOUBLE',
- 'WITH percentiles_for_value AS (
- SELECT
- value,
- (CAST(SUM(dur) OVER(ORDER BY value ASC) AS DOUBLE) /
- ($end_ts - MAX($start_ts, earliest_timestamp_for_counter_track($counter_track_id)))) * 100
- AS percentile_for_value
- FROM COUNTER_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
- ORDER BY value ASC
- ),
- with_gaps AS (
- SELECT
- CAST(percentile_for_value AS INT) AS percentile,
- MIN(value) AS value
- FROM percentiles_for_value
- GROUP BY percentile
- ORDER BY percentile ASC)
+CREATE PERFETTO FUNCTION counter_percentiles_for_time_range(
+ counter_track_id INT, start_ts LONG, end_ts LONG)
+RETURNS TABLE(percentile INT, value DOUBLE) AS
+WITH percentiles_for_value AS (
SELECT
- num AS percentile,
- IFNULL(value, MIN(value) OVER (ORDER BY percentile DESC)) AS value
- FROM INTERNAL_NUMBER_GENERATOR(100) AS nums
- LEFT JOIN with_gaps ON with_gaps.percentile = nums.num
- ORDER BY percentile DESC
- '
-);
+ value,
+ (CAST(SUM(dur) OVER(ORDER BY value ASC) AS DOUBLE) /
+ ($end_ts - MAX($start_ts, earliest_timestamp_for_counter_track($counter_track_id)))) * 100
+ AS percentile_for_value
+ FROM COUNTER_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
+ ORDER BY value ASC
+),
+with_gaps AS (
+ SELECT
+ CAST(percentile_for_value AS INT) AS percentile,
+ MIN(value) AS value
+ FROM percentiles_for_value
+ GROUP BY percentile
+ ORDER BY percentile ASC)
+SELECT
+ num AS percentile,
+ IFNULL(value, MIN(value) OVER (ORDER BY percentile DESC)) AS value
+FROM INTERNAL_NUMBER_GENERATOR(100) AS nums
+LEFT JOIN with_gaps ON with_gaps.percentile = nums.num
+ORDER BY percentile DESC;
-- All percentiles (range 1-100) for counter track ID.
--
-- @arg counter_track_id INT Id of the counter track.
-- @column percentile All of the numbers from 1 to 100.
-- @column value Value for the percentile.
-SELECT CREATE_VIEW_FUNCTION(
- 'COUNTER_PERCENTILES_FOR_TRACK(counter_track_id INT)',
- 'percentile INT, value DOUBLE',
- 'SELECT * FROM COUNTER_PERCENTILES_FOR_TIME_RANGE($counter_track_id, trace_start(), trace_end());'
-);
+CREATE PERFETTO FUNCTION counter_percentiles_for_track(
+ counter_track_id INT)
+RETURNS TABLE(percentile INT, value DOUBLE) AS
+SELECT *
+FROM counter_percentiles_for_time_range(
+ $counter_track_id, trace_start(), trace_end());
-- Value for specific percentile (range 1-100) for counter track ID in time range.
--
@@ -98,7 +95,7 @@
end_ts LONG)
RETURNS DOUBLE AS
SELECT value
-FROM COUNTER_PERCENTILES_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
+FROM counter_percentiles_for_time_range($counter_track_id, $start_ts, $end_ts)
WHERE percentile = $percentile;
-- Value for specific percentile (range 1-100) for counter track ID.
diff --git a/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql b/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
index 5b7bf03..f839818 100644
--- a/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
@@ -347,9 +347,8 @@
-- @column is_leaf Whether this span is the leaf in the slice tree.
-- @column depth Tree depth from |root_id|
-- @column root_id Thread state id used to start the recursion. Helpful for SQL JOINs
-SELECT CREATE_VIEW_FUNCTION(
-'EXPERIMENTAL_THREAD_EXECUTING_SPAN_DESCENDANTS(root_id INT)',
-'
+CREATE PERFETTO FUNCTION experimental_thread_executing_span_descendants(root_id INT)
+RETURNS TABLE(
parent_id LONG,
id LONG,
ts LONG,
@@ -373,8 +372,7 @@
is_leaf INT,
depth INT,
root_id INT
-',
-'
+) AS
WITH chain AS (
SELECT
*,
@@ -390,8 +388,7 @@
FROM experimental_thread_executing_span_graph graph
JOIN chain ON chain.id = graph.parent_id
)
-SELECT * FROM chain
-');
+SELECT * FROM chain;
-- All thread_executing_spans that are ancestors of |leaf_id|.
--
@@ -426,9 +423,8 @@
-- @column leaf_blocked_dur Thread state duration blocked of the |leaf_id|.
-- @column leaf_blocked_state Thread state of the |leaf_id|.
-- @column leaf_blocked_function Thread state blocked_function of the |leaf_id|.
-SELECT CREATE_VIEW_FUNCTION(
-'EXPERIMENTAL_THREAD_EXECUTING_SPAN_ANCESTORS(leaf_id INT, leaf_utid INT)',
-'
+CREATE PERFETTO FUNCTION experimental_thread_executing_span_ancestors(leaf_id INT, leaf_utid INT)
+RETURNS TABLE(
parent_id LONG,
id LONG,
ts LONG,
@@ -457,8 +453,7 @@
leaf_blocked_dur LONG,
leaf_blocked_state STRING,
leaf_blocked_function STRING
-',
-'
+) AS
WITH
chain AS (
SELECT
@@ -486,8 +481,7 @@
FROM experimental_thread_executing_span_graph graph
JOIN chain ON chain.parent_id = graph.id AND chain.ts >= (leaf_ts - leaf_blocked_dur)
)
-SELECT * FROM chain
-');
+SELECT * FROM chain;
-- Gets the thread_executing_span id a thread_state belongs to. Returns NULL if thread state is
-- sleeping and not blocked on an interrupt.