| -- Copyright 2023 The Chromium Authors |
| -- Use of this source code is governed by a BSD-style license that can be |
| -- found in the LICENSE file. |
| |
| -- Checks if slice has an ancestor with provided name. |
| CREATE PERFETTO FUNCTION _has_parent_slice_with_name( |
| -- Id of the slice to check parents of. |
| id LONG, |
| -- Name of potential ancestor slice. |
| parent_name STRING |
| ) |
| -- Whether `parent_name` is a name of an ancestor slice. |
| RETURNS BOOL AS |
| SELECT |
| EXISTS( |
| SELECT |
| 1 |
| FROM ancestor_slice($id) |
| WHERE |
| name = $parent_name |
| LIMIT 1 |
| ); |
| |
| -- Returns the mojo ipc hash for a given task, looking it up from the |
| -- argument of descendant ScopedSetIpcHash slice. |
| -- This is relevant only for the older Chrome traces, where mojo IPC |
| -- hash was reported in a separate ScopedSetIpcHash slice. |
| CREATE PERFETTO FUNCTION _extract_mojo_ipc_hash( |
| slice_id LONG |
| ) |
| RETURNS LONG AS |
| SELECT |
| extract_arg(arg_set_id, "chrome_mojo_event_info.ipc_hash") |
| FROM descendant_slice($slice_id) |
| WHERE |
| name = "ScopedSetIpcHash" |
| ORDER BY |
| id |
| LIMIT 1; |
| |
| -- Returns the frame type (main frame vs subframe) for key navigation tasks |
| -- which capture the associated RenderFrameHost in an argument. |
| CREATE PERFETTO FUNCTION _extract_frame_type( |
| slice_id LONG |
| ) |
| RETURNS LONG AS |
| SELECT |
| extract_arg(arg_set_id, "render_frame_host.frame_type") |
| FROM descendant_slice($slice_id) |
| WHERE |
| name IN ("RenderFrameHostImpl::BeginNavigation", "RenderFrameHostImpl::DidCommitProvisionalLoad", "RenderFrameHostImpl::DidCommitSameDocumentNavigation", "RenderFrameHostImpl::DidStopLoading") |
| LIMIT 1; |
| |
| -- Human-readable aliases for a few key navigation tasks. |
| CREATE PERFETTO FUNCTION _human_readable_navigation_task_name( |
| task_name STRING |
| ) |
| RETURNS STRING AS |
| SELECT |
| CASE |
| WHEN $task_name = "content.mojom.FrameHost message (hash=2168461044)" |
| THEN "FrameHost::BeginNavigation" |
| WHEN $task_name = "content.mojom.FrameHost message (hash=3561497419)" |
| THEN "FrameHost::DidCommitProvisionalLoad" |
| WHEN $task_name = "content.mojom.FrameHost message (hash=1421450774)" |
| THEN "FrameHost::DidCommitSameDocumentNavigation" |
| WHEN $task_name = "content.mojom.FrameHost message (hash=368650583)" |
| THEN "FrameHost::DidStopLoading" |
| END; |
| |
| -- Takes a task name and formats it correctly for scheduler tasks. |
| CREATE PERFETTO FUNCTION _format_scheduler_task_name( |
| task_name STRING |
| ) |
| RETURNS STRING AS |
| SELECT |
| printf("RunTask(posted_from=%s)", $task_name); |
| |
| -- Takes the category and determines whether it is "Java" only, as opposed to |
| -- "toplevel,Java". |
| CREATE PERFETTO FUNCTION _java_not_top_level_category( |
| category STRING |
| ) |
| RETURNS BOOL AS |
| SELECT |
| $category GLOB "*Java*" AND NOT $category GLOB "*toplevel*"; |
| |
| -- Takes the category and determines whether is any valid |
| -- toplevel category or combination of categories. |
| CREATE PERFETTO FUNCTION _any_top_level_category( |
| category STRING |
| ) |
| RETURNS BOOL AS |
| SELECT |
| $category IN ("toplevel", "toplevel,viz", "toplevel,Java"); |
| |
| -- TODO(altimin): the situations with kinds in this file is a bit of a mess. |
| -- The idea is that it should work as `type` in the `slice` table, pointing to |
| -- a "child" table with more information about the task (e.g. posted_from for |
| -- scheduler tasks). Currently this is not the case and needs a cleanup. |
| -- Also we should align this with how table inheritance should work for |
| -- `CREATE PERFETTO TABLE`. |
| |
| -- Get task type for a given task kind. |
| CREATE PERFETTO FUNCTION _get_java_views_task_type( |
| kind STRING |
| ) |
| RETURNS STRING AS |
| SELECT |
| CASE $kind |
| WHEN "Choreographer" |
| THEN "choreographer" |
| WHEN "SingleThreadProxy::BeginMainFrame" |
| THEN "ui_thread_begin_main_frame" |
| END; |
| |
| -- All slices corresponding to receiving mojo messages. |
| -- On the newer Chrome versions, it's just "Receive mojo message" and |
| -- "Receive mojo reply" slices (or "Receive {mojo_message_name}" if |
| -- built with `extended_tracing_enabled`. On legacy Chrome versions, |
| -- other appropriate messages (like "Connector::DispatchMessage") are used. |
| -- |
| -- @column STRING interface_name Name of the IPC interface. |
| -- @column INT ipc_hash Hash of a message name. |
| -- @column STRING message_type Either 'message' or 'reply'. |
| -- @column INT id Slice id. |
| -- |
| -- Note: this might include messages received within a sync mojo call. |
| -- TODO(altimin): This should use EXTEND_TABLE when it becomes available. |
| CREATE PERFETTO TABLE _chrome_mojo_slices AS |
| WITH |
| -- Select all new-style (post crrev.com/c/3270337) mojo slices and |
| -- generate |task_name| for them. |
| -- If extended tracing is enabled, the slice name will have the full method |
| -- name (i.e. "Receive content::mojom::FrameHost::DidStopLoading") and we |
| -- should use it as a full name. |
| -- If extended tracing is not enabled, we should include the interface name |
| -- and method hash into the full name. |
| new_mojo_slices 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 name |
| WHEN "Receive mojo message" |
| THEN "message" |
| WHEN "Receive mojo reply" |
| THEN "reply" |
| END AS message_type, |
| id |
| FROM slice |
| WHERE |
| category GLOB '*toplevel*' AND name GLOB 'Receive *' |
| ), |
| -- Select old-style slices for channel-associated mojo events. |
| old_associated_mojo_slices AS ( |
| SELECT |
| name AS interface_name, |
| _extract_mojo_ipc_hash(id) AS ipc_hash, |
| "message" AS message_type, |
| id |
| FROM slice |
| WHERE |
| category GLOB "*mojom*" AND name GLOB '*.mojom.*' |
| ), |
| -- Select old-style slices for non-(channel-associated) mojo events. |
| old_non_associated_mojo_slices AS ( |
| SELECT |
| coalesce( |
| extract_arg(arg_set_id, "chrome_mojo_event_info.watcher_notify_interface_tag"), |
| extract_arg(arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") |
| ) AS interface_name, |
| _extract_mojo_ipc_hash(id) AS ipc_hash, |
| "message" AS message_type, |
| id |
| FROM slice |
| WHERE |
| category GLOB "*toplevel*" AND name = "Connector::DispatchMessage" |
| ), |
| merged AS ( |
| -- Merge all mojo slices. |
| SELECT |
| * |
| FROM new_mojo_slices |
| UNION ALL |
| SELECT |
| * |
| FROM old_associated_mojo_slices |
| UNION ALL |
| SELECT |
| * |
| FROM old_non_associated_mojo_slices |
| ) |
| SELECT |
| * |
| FROM merged |
| ORDER BY |
| id; |
| |
| -- This table contains a list of slices corresponding to the _representative_ |
| -- Chrome Java view operations. |
| -- These are the outermost Java view slices after filtering out generic framework views |
| -- (like FitWindowsLinearLayout) and selecting the outermost slices from the remaining ones. |
| -- |
| -- @column id INT Slice id. |
| -- @column ts INT Timestamp. |
| -- @column dur INT Duration. |
| -- @column name STRING Name of the view. |
| -- @column is_software_screenshot BOOL Whether this slice is a part of non-accelerated |
| -- capture toolbar screenshot. |
| -- @column is_hardware_screenshot BOOL Whether this slice is a part of accelerated |
| -- capture toolbar screenshot. |
| CREATE PERFETTO TABLE _chrome_java_views AS |
| WITH |
| -- .draw, .onLayout and .onMeasure parts of the java view names don't add much, strip them. |
| java_slices_with_trimmed_names AS ( |
| SELECT |
| id, |
| replace( |
| replace( |
| replace(replace(replace(s1.name, ".draw", ""), ".onLayout", ""), ".onMeasure", ""), |
| ".Layout", |
| "" |
| ), |
| ".Measure", |
| "" |
| ) AS name, |
| ts, |
| dur |
| FROM slice AS s1 |
| -- Ensure that toplevel Java slices are not included, as they may be logged |
| -- with either category = "toplevel" or category = "toplevel,Java". |
| -- Also filter out the zero duration slices as an attempt to reduce noise as |
| -- "Java" category contains misc events (as it's hard to add new categories). |
| WHERE |
| _java_not_top_level_category(category) AND dur > 0 |
| ), |
| -- We filter out generic slices from various UI frameworks which don't tell us much about |
| -- what exactly this view is doing. |
| interesting_java_slices AS ( |
| SELECT |
| id, |
| name, |
| ts, |
| dur |
| FROM java_slices_with_trimmed_names |
| -- The names below correspond respectively to: |
| -- * AndroidX. |
| -- * Other non-Chrome UI libraries. |
| -- * Generic Chrome frameworks. |
| -- * Non-specific Chrome slices. |
| -- * Screenshots custom annotations. |
| -- * Non-bytecode generated slices. |
| WHERE |
| NOT name IN ("FitWindowsFrameLayout", "FitWindowsLinearLayout", "ContentFrameLayout", "CoordinatorLayout") |
| AND NOT name IN ("ComponentHost") |
| AND NOT name IN ("CompositorView:finalizeLayers", "CompositorViewHolder", "CompositorViewHolder:layout", "CompositorViewHolder:updateContentViewChildrenDimension", "CoordinatorLayoutForPointer", "OptimizedFrameLayout", "ViewResourceAdapter:getBitmap", "ViewResourceFrameLayout") |
| AND NOT name IN ("AppCompatImageButton", "ScrollingBottomViewResourceFrameLayout") |
| AND NOT name IN ("ViewResourceAdapter:captureWithHardwareDraw", "ViewResourceAdapter:captureWithSoftwareDraw") |
| AND NOT name IN ("LayoutDriver:onUpdate") |
| ) |
| SELECT |
| s1.*, |
| -- While the parent slices are too generic to be used by themselves, |
| -- they can provide some useful metadata. |
| _has_parent_slice_with_name(s1.id, "ViewResourceAdapter:captureWithSoftwareDraw") AS is_software_screenshot, |
| _has_parent_slice_with_name(s1.id, "ViewResourceAdapter:captureWithHardwareDraw") AS is_hardware_screenshot |
| FROM interesting_java_slices AS s1 |
| -- We select "outermost" interesting slices: interesting slices which |
| -- do not another interesting slice in their parent chain. |
| WHERE |
| ( |
| SELECT |
| count() |
| FROM ancestor_slice(s1.id) AS s2 |
| JOIN interesting_java_slices AS s3 |
| ON s2.id = s3.id |
| ) = 0; |
| |
| -- A list of slices corresponding to operations on interesting (non-generic) |
| -- Chrome Java views. The view is considered interested if it's not a system |
| -- (ContentFrameLayout) or generic library (CompositorViewHolder) views. |
| -- |
| -- TODO(altimin): Add "columns_from slice" annotation. |
| -- TODO(altimin): convert this to EXTEND_TABLE when it becomes available. |
| CREATE PERFETTO VIEW chrome_java_views ( |
| -- Name of the view. |
| filtered_name STRING, |
| -- Whether this slice is a part of non-accelerated capture toolbar screenshot. |
| is_software_screenshot BOOL, |
| -- Whether this slice is a part of accelerated capture toolbar screenshot. |
| is_hardware_screenshot BOOL, |
| -- Slice id. |
| slice_id LONG |
| ) AS |
| SELECT |
| java_view.name AS filtered_name, |
| java_view.is_software_screenshot, |
| java_view.is_hardware_screenshot, |
| slice.id AS slice_id |
| FROM _chrome_java_views AS java_view |
| JOIN slice |
| USING (id); |
| |
| -- A list of Choreographer tasks (Android frame generation) in Chrome. |
| CREATE PERFETTO VIEW _chrome_choreographer_tasks AS |
| SELECT |
| id, |
| "Choreographer" AS kind, |
| ts, |
| dur, |
| name |
| FROM slice |
| WHERE |
| name GLOB "Looper.dispatch: android.view.Choreographer$FrameHandler*"; |
| |
| -- Extract task's posted_from information from task's arguments. |
| CREATE PERFETTO FUNCTION _get_posted_from( |
| arg_set_id LONG |
| ) |
| RETURNS STRING AS |
| WITH |
| posted_from AS ( |
| SELECT |
| extract_arg($arg_set_id, "task.posted_from.file_name") AS file_name, |
| extract_arg($arg_set_id, "task.posted_from.function_name") AS function_name |
| ) |
| SELECT |
| file_name || ":" || function_name AS posted_from |
| FROM posted_from; |
| |
| -- Selects the BeginMainFrame slices (which as posted from ScheduledActionSendBeginMainFrame), |
| -- used for root-level processing. In top-level/Java based slices, these will correspond to the |
| -- ancestor of descendant slices; in long-task tracking, these tasks will be |
| -- on a custom track and will need to be associated with children by timestamp |
| -- and duration. Corresponds with the Choreographer root slices in |
| -- chrome_choreographer_tasks below. |
| -- |
| -- Schema: |
| -- @column is The slice id. |
| -- @column kind The type of Java slice. |
| -- @column ts The timestamp of the slice. |
| -- @column name The name of the slice. |
| CREATE PERFETTO FUNCTION _select_begin_main_frame_java_slices( |
| name STRING |
| ) |
| RETURNS TABLE ( |
| id LONG, |
| kind STRING, |
| ts TIMESTAMP, |
| dur DURATION, |
| name STRING |
| ) AS |
| SELECT |
| id, |
| "SingleThreadProxy::BeginMainFrame" AS kind, |
| ts, |
| dur, |
| name |
| FROM slice |
| WHERE |
| ( |
| name = $name |
| AND _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 these views. |
| -- @column id INT Slice id. |
| -- @column kind STRING Type of the task. |
| -- @column java_views STRING Concatenated names of Java views used by the task. |
| CREATE PERFETTO VIEW _chrome_slices_with_java_views AS |
| WITH |
| -- Select UI thread BeginMainFrames (which are Chrome scheduler tasks) and |
| -- Choreographer frames (which are looper tasks). |
| root_slices AS ( |
| SELECT |
| id, |
| kind |
| FROM _select_begin_main_frame_java_slices('ThreadControllerImpl::RunTask') |
| UNION ALL |
| SELECT |
| id, |
| kind |
| FROM _chrome_choreographer_tasks |
| ), |
| -- Intermediate step to allow us to sort java view names. |
| root_slice_and_java_view_not_grouped AS ( |
| SELECT |
| root.id, |
| root.kind, |
| java_view.name AS java_view_name |
| FROM root_slices AS root, descendant_slice(root.id) AS child |
| JOIN _chrome_java_views AS java_view |
| ON java_view.id = child.id |
| ) |
| SELECT |
| root.id, |
| root.kind, |
| GROUP_CONCAT(DISTINCT java_view.java_view_name) AS java_views |
| FROM root_slices AS root |
| LEFT JOIN root_slice_and_java_view_not_grouped AS java_view |
| USING (id) |
| GROUP BY |
| root.id; |
| |
| -- A list of tasks executed by Chrome scheduler. |
| CREATE PERFETTO TABLE _chrome_scheduler_tasks AS |
| SELECT |
| id |
| FROM slice |
| WHERE |
| category GLOB "*toplevel*" |
| AND ( |
| name = "ThreadControllerImpl::RunTask" OR name = "ThreadPool_RunTask" |
| ) |
| ORDER BY |
| id; |
| |
| -- A list of tasks executed by Chrome scheduler. |
| CREATE PERFETTO VIEW chrome_scheduler_tasks ( |
| -- Slice id. |
| id LONG, |
| -- Type. |
| type STRING, |
| -- Name of the task. |
| name STRING, |
| -- Timestamp. |
| ts TIMESTAMP, |
| -- Duration. |
| dur DURATION, |
| -- Utid of the thread this task run on. |
| utid LONG, |
| -- Name of the thread this task run on. |
| thread_name STRING, |
| -- Upid of the process of this task. |
| upid LONG, |
| -- Name of the process of this task. |
| process_name STRING, |
| -- Same as slice.track_id. |
| track_id LONG, |
| -- Same as slice.category. |
| category STRING, |
| -- Same as slice.depth. |
| depth LONG, |
| -- Same as slice.parent_id. |
| parent_id LONG, |
| -- Same as slice.arg_set_id. |
| arg_set_id LONG, |
| -- Same as slice.thread_ts. |
| thread_ts TIMESTAMP, |
| -- Same as slice.thread_dur. |
| thread_dur DURATION, |
| -- Source location where the PostTask was called. |
| posted_from STRING |
| ) AS |
| SELECT |
| task.id, |
| "chrome_scheduler_tasks" AS type, |
| _format_scheduler_task_name(_get_posted_from(slice.arg_set_id)) AS name, |
| slice.ts, |
| slice.dur, |
| thread.utid, |
| thread.name AS thread_name, |
| process.upid, |
| process.name AS process_name, |
| slice.track_id, |
| slice.category, |
| slice.depth, |
| slice.parent_id, |
| slice.arg_set_id, |
| slice.thread_ts, |
| slice.thread_dur, |
| _get_posted_from(slice.arg_set_id) AS posted_from |
| FROM _chrome_scheduler_tasks AS task |
| JOIN slice |
| USING (id) |
| JOIN thread_track |
| ON slice.track_id = thread_track.id |
| JOIN thread |
| USING (utid) |
| JOIN process |
| USING (upid) |
| ORDER BY |
| task.id; |
| |
| -- Select the slice that might be the descendant mojo slice for the given task |
| -- slice if it exists. |
| CREATE PERFETTO FUNCTION _get_descendant_mojo_slice_candidate( |
| slice_id LONG |
| ) |
| RETURNS LONG AS |
| SELECT |
| id |
| FROM descendant_slice($slice_id) |
| WHERE |
| -- The tricky case here is dealing with sync mojo IPCs: we do not want to |
| -- pick up sync IPCs when we are in a non-IPC task. |
| -- So we look at all toplevel events and pick up the first one: |
| -- for sync mojo messages, it will be "Send mojo message", which then |
| -- will fail. |
| -- Some events are excluded as they can legimately appear under "RunTask" |
| -- before "Receive mojo message". |
| category GLOB "*toplevel*" |
| AND NOT name IN ("SimpleWatcher::OnHandleReady", "MessagePipe peer closed") |
| ORDER BY |
| depth, |
| ts |
| LIMIT 1; |
| |
| CREATE PERFETTO FUNCTION _descendant_mojo_slice( |
| slice_id LONG |
| ) |
| 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 AS task |
| JOIN _chrome_mojo_slices AS mojo |
| ON mojo.id = _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 |
| -- will not intersect. |
| -- |
| -- @column task_name STRING Name for the given task. |
| -- @column task_type STRING Type of the task (e.g. "scheduler"). |
| -- @column scheduling_delay LONG |
| CREATE PERFETTO TABLE _chrome_tasks AS |
| WITH |
| -- Select slices from "toplevel" category which do not have another |
| -- "toplevel" slice as ancestor. The possible cases include sync mojo messages |
| -- and tasks in nested runloops. Toplevel events may also be logged as with |
| -- the Java category. |
| non_embedded_toplevel_slices AS ( |
| SELECT |
| * |
| FROM slice |
| WHERE |
| _any_top_level_category(category) |
| AND ( |
| SELECT |
| count() |
| FROM ancestor_slice(slice.id) AS anc |
| WHERE |
| anc.category GLOB "*toplevel*" OR anc.category GLOB "*toplevel.viz*" |
| ) = 0 |
| ), |
| -- Select slices from "Java" category which do not have another "Java" or |
| -- "toplevel" slice as parent. In the longer term they should probably belong |
| -- to "toplevel" category as well, but for now this will have to do. Ensure |
| -- that "Java" slices do not include "toplevel" slices as those would be |
| -- handled elsewhere. |
| non_embedded_java_slices AS ( |
| SELECT |
| id, |
| name AS task_name, |
| "java" AS task_type |
| FROM slice AS s |
| WHERE |
| _java_not_top_level_category(category) |
| AND ( |
| SELECT |
| count() |
| FROM ancestor_slice(s.id) AS s2 |
| WHERE |
| s2.category GLOB "*toplevel*" OR s2.category GLOB "*Java*" |
| ) = 0 |
| ), |
| -- Generate full names for tasks with java views. |
| java_views_tasks AS ( |
| SELECT |
| id, |
| printf('%s(java_views=%s)', kind, java_views) AS task_name, |
| _get_java_views_task_type(kind) AS task_type |
| FROM _chrome_slices_with_java_views |
| ), |
| scheduler_tasks AS ( |
| SELECT |
| id, |
| name AS task_name, |
| "scheduler" AS task_type |
| FROM chrome_scheduler_tasks |
| ), |
| -- Select scheduler tasks which are used to run mojo messages and use the mojo names |
| -- as full names for these slices. |
| -- We restrict this to specific scheduler tasks which are expected to run mojo |
| -- tasks due to sync mojo events, which also emit similar events. |
| scheduler_tasks_with_mojo AS ( |
| SELECT |
| -- We use the "RunTask" as the task, and pick up the name from its child |
| -- "Receive mojo message" event. |
| task.id, |
| receive_message.task_name, |
| "mojo" AS task_type |
| FROM chrome_scheduler_tasks AS task, _descendant_mojo_slice(task.id) AS receive_message |
| WHERE |
| task.posted_from IN ("mojo/public/cpp/system/simple_watcher.cc:Notify", "mojo/public/cpp/system/simple_watcher.cc:ArmOrNotify", "mojo/public/cpp/bindings/lib/connector.cc:PostDispatchNextMessageFromPipe", "ipc/ipc_mojo_bootstrap.cc:Accept") |
| ), |
| navigation_tasks AS ( |
| WITH |
| tasks_with_readable_names AS ( |
| SELECT |
| id, |
| _human_readable_navigation_task_name(task_name) AS readable_name, |
| coalesce(_extract_frame_type(id), 'unknown frame type') AS frame_type |
| FROM scheduler_tasks_with_mojo |
| ) |
| SELECT |
| id, |
| printf("%s (%s)", readable_name, frame_type) AS task_name, |
| 'navigation_task' AS task_type |
| FROM tasks_with_readable_names |
| WHERE |
| readable_name IS NOT NULL |
| ), |
| -- Add scheduler and mojo full names to non-embedded slices from |
| -- the "toplevel" category, with mojo ones taking precedence. |
| non_embedded_toplevel_slices_with_task_name AS ( |
| SELECT |
| task.id AS id, |
| coalesce( |
| navigation.task_name, |
| java_views.task_name, |
| mojo.task_name, |
| scheduler.task_name, |
| task.name |
| ) AS name, |
| coalesce(navigation.task_type, java_views.task_type, mojo.task_type, scheduler.task_type, "other") AS task_type |
| FROM non_embedded_toplevel_slices AS task |
| LEFT JOIN scheduler_tasks_with_mojo AS mojo |
| ON mojo.id = task.id |
| LEFT JOIN scheduler_tasks AS scheduler |
| ON scheduler.id = task.id |
| LEFT JOIN java_views_tasks AS java_views |
| ON java_views.id = task.id |
| LEFT JOIN navigation_tasks AS navigation |
| ON navigation.id = task.id |
| ) |
| -- Merge slices from toplevel and Java categories. |
| SELECT |
| * |
| FROM non_embedded_toplevel_slices_with_task_name |
| UNION ALL |
| SELECT |
| * |
| FROM non_embedded_java_slices |
| ORDER BY |
| 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 slices |
| -- corresponding to these tasks will not intersect. |
| CREATE PERFETTO VIEW chrome_tasks ( |
| -- Id for the given task, also the id of the slice this task corresponds to. |
| id LONG, |
| -- Name for the given task. |
| name STRING, |
| -- Type of the task (e.g. "scheduler"). |
| task_type STRING, |
| -- Thread name. |
| thread_name STRING, |
| -- Utid. |
| utid LONG, |
| -- Process name. |
| process_name STRING, |
| -- Upid. |
| upid LONG, |
| -- Alias of |slice.ts|. |
| ts TIMESTAMP, |
| -- Alias of |slice.dur|. |
| dur DURATION, |
| -- Alias of |slice.track_id|. |
| track_id LONG, |
| -- Alias of |slice.category|. |
| category STRING, |
| -- Alias of |slice.arg_set_id|. |
| arg_set_id LONG, |
| -- Alias of |slice.thread_ts|. |
| thread_ts TIMESTAMP, |
| -- Alias of |slice.thread_dur|. |
| thread_dur DURATION, |
| -- STRING Legacy alias for |name|. |
| full_name STRING |
| ) AS |
| SELECT |
| cti.id, |
| cti.name, |
| task_type, |
| thread.name AS thread_name, |
| thread.utid, |
| process.name AS process_name, |
| thread.upid, |
| s.ts, |
| s.dur, |
| s.track_id, |
| s.category, |
| s.arg_set_id, |
| s.thread_ts, |
| s.thread_dur, |
| cti.name AS full_name |
| FROM _chrome_tasks AS cti |
| JOIN slice AS s |
| ON cti.id = s.id |
| JOIN thread_track AS tt |
| ON s.track_id = tt.id |
| JOIN thread |
| USING (utid) |
| JOIN process |
| USING (upid); |