diff options
author | Isabelle Taylor <taylori@google.com> | 2020-06-09 22:52:26 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-06-09 22:52:26 +0000 |
commit | 4d716e44e23012e5eb00e5158fd0a224fd78448d (patch) | |
tree | bed514f28a019bf3dbc2d9be195d87dd8ce07f65 | |
parent | af09d382d8b34997850c01d39c8d66c6f60ab721 (diff) | |
parent | cf291b56f640cb0dcf6661ffe783140866fec53a (diff) | |
download | perfetto-4d716e44e23012e5eb00e5158fd0a224fd78448d.tar.gz |
Merge "perfetto-ui: Add go to dest button for binder slices" am: 2911cba7a7 am: 577378cdcc am: e7cd72fb0a am: 156a130406 am: cf291b56f6
Original change: https://android-review.googlesource.com/c/platform/external/perfetto/+/1325071
Change-Id: I6beb4308dc8df1a504b0680ce8aaffdb52600744
-rw-r--r-- | src/trace_processor/importers/common/slice_tracker.cc | 13 | ||||
-rw-r--r-- | src/trace_processor/importers/common/slice_tracker.h | 8 | ||||
-rw-r--r-- | src/trace_processor/importers/ftrace/binder_tracker.cc | 30 | ||||
-rw-r--r-- | src/trace_processor/importers/ftrace/binder_tracker.h | 1 | ||||
-rw-r--r-- | ui/src/assets/details.scss | 34 | ||||
-rw-r--r-- | ui/src/controller/selection_controller.ts | 35 | ||||
-rw-r--r-- | ui/src/frontend/chrome_slice_panel.ts | 32 | ||||
-rw-r--r-- | ui/src/frontend/globals.ts | 3 |
8 files changed, 115 insertions, 41 deletions
diff --git a/src/trace_processor/importers/common/slice_tracker.cc b/src/trace_processor/importers/common/slice_tracker.cc index 8c82982da..3fca41798 100644 --- a/src/trace_processor/importers/common/slice_tracker.cc +++ b/src/trace_processor/importers/common/slice_tracker.cc @@ -124,25 +124,26 @@ base::Optional<uint32_t> SliceTracker::End(int64_t timestamp, return context_->storage->slice_table().id().IndexOf(*slice_id); } -void SliceTracker::AddArgs(TrackId track_id, - StringId category, - StringId name, - SetArgsCallback args_callback) { +base::Optional<uint32_t> SliceTracker::AddArgs(TrackId track_id, + StringId category, + StringId name, + SetArgsCallback args_callback) { auto& stack = stacks_[track_id]; if (stack.empty()) - return; + return base::nullopt; auto* slices = context_->storage->mutable_slice_table(); base::Optional<uint32_t> stack_idx = MatchingIncompleteSliceIndex(stack, name, category); if (!stack_idx.has_value()) - return; + return base::nullopt; uint32_t slice_idx = stack[*stack_idx].first; PERFETTO_DCHECK(slices->dur()[slice_idx] == kPendingDuration); // Add args to current pending slice. ArgsTracker* tracker = &stack[*stack_idx].second; auto bound_inserter = tracker->AddArgsTo(slices->id()[slice_idx]); args_callback(&bound_inserter); + return slice_idx; } base::Optional<SliceId> SliceTracker::EndGpu(int64_t ts, diff --git a/src/trace_processor/importers/common/slice_tracker.h b/src/trace_processor/importers/common/slice_tracker.h index 804806c72..eac656e71 100644 --- a/src/trace_processor/importers/common/slice_tracker.h +++ b/src/trace_processor/importers/common/slice_tracker.h @@ -75,10 +75,10 @@ class SliceTracker { // Usually args should be added in the Begin or End args_callback but this // method is for the situation where new args need to be added to an // in-progress slice. - void AddArgs(TrackId track_id, - StringId category, - StringId name, - SetArgsCallback args_callback); + base::Optional<uint32_t> AddArgs(TrackId track_id, + StringId category, + StringId name, + SetArgsCallback args_callback); // TODO(lalitm): eventually this method should become End and End should // be renamed EndChrome. diff --git a/src/trace_processor/importers/ftrace/binder_tracker.cc b/src/trace_processor/importers/ftrace/binder_tracker.cc index e9a081da2..b6ef00e24 100644 --- a/src/trace_processor/importers/ftrace/binder_tracker.cc +++ b/src/trace_processor/importers/ftrace/binder_tracker.cc @@ -75,6 +75,7 @@ BinderTracker::BinderTracker(TraceProcessorContext* context) flags_(context->storage->InternString("flags")), code_(context->storage->InternString("code")), calling_tid_(context->storage->InternString("calling tid")), + dest_slice_id_(context->storage->InternString("destination slice id")), data_size_(context->storage->InternString("data size")), offsets_size_(context->storage->InternString("offsets size")) {} @@ -161,17 +162,32 @@ void BinderTracker::TransactionReceived(int64_t ts, } if (transaction_await_rcv.count(transaction_id) > 0) { + // First begin the reply slice to get its slice id. + auto reply_slice_id = context_->slice_tracker->Begin( + ts, track_id, binder_category_id_, reply_id_); // Add accurate dest info to the binder transaction slice. - auto args_inserter = [this, pid, - &thread_name](ArgsTracker::BoundInserter* inserter) { + auto args_inserter = [this, pid, &thread_name, &reply_slice_id]( + ArgsTracker::BoundInserter* inserter) { inserter->AddArg(dest_thread_, Variadic::UnsignedInteger(pid)); inserter->AddArg(dest_name_, Variadic::String(thread_name)); + if (reply_slice_id.has_value()) + inserter->AddArg(dest_slice_id_, + Variadic::UnsignedInteger(reply_slice_id.value())); }; - context_->slice_tracker->AddArgs(transaction_await_rcv[transaction_id], - binder_category_id_, transaction_slice_id_, - args_inserter); - context_->slice_tracker->Begin(ts, track_id, binder_category_id_, - reply_id_); + // Add the dest args to the current transaction slice and get the slice id. + auto transaction_slice_id = context_->slice_tracker->AddArgs( + transaction_await_rcv[transaction_id], binder_category_id_, + transaction_slice_id_, args_inserter); + + // Add the dest slice id to the reply slice that has just begun. + auto reply_dest_inserter = + [this, &transaction_slice_id](ArgsTracker::BoundInserter* inserter) { + if (transaction_slice_id.has_value()) + inserter->AddArg(dest_slice_id_, Variadic::UnsignedInteger( + transaction_slice_id.value())); + }; + context_->slice_tracker->AddArgs(track_id, binder_category_id_, reply_id_, + reply_dest_inserter); transaction_await_rcv.erase(transaction_id); return; } diff --git a/src/trace_processor/importers/ftrace/binder_tracker.h b/src/trace_processor/importers/ftrace/binder_tracker.h index 3c2b98217..a96816d35 100644 --- a/src/trace_processor/importers/ftrace/binder_tracker.h +++ b/src/trace_processor/importers/ftrace/binder_tracker.h @@ -93,6 +93,7 @@ class BinderTracker : public Destructible { const StringId flags_; const StringId code_; const StringId calling_tid_; + const StringId dest_slice_id_; const StringId data_size_; const StringId offsets_size_; }; diff --git a/ui/src/assets/details.scss b/ui/src/assets/details.scss index 7dd5ff724..5efcce554 100644 --- a/ui/src/assets/details.scss +++ b/ui/src/assets/details.scss @@ -93,6 +93,24 @@ font-family: 'Roboto Condensed', sans-serif; font-weight: 300; color: #3c4b5d; + + .material-icons { + @include transition(0.3s); + font-size: 16px; + margin-left: 5px; + &:hover { + cursor: pointer; + } + &.grey { + border-radius: 3px; + border: 1px solid transparent; + background-color: #e8e8e8; + &:hover { + border: #475566 solid 1px; + } + } + } + .details-panel-heading { padding: 10px 0 5px 0; position: sticky; @@ -190,22 +208,6 @@ width: 30%; font-weight: normal; } - .material-icons { - @include transition(0.3s); - font-size: 16px; - margin-left: 5px; - &:hover { - cursor: pointer; - } - &.grey { - border-radius: 3px; - border: 1px solid transparent; - background-color: #e8e8e8; - &:hover { - border: #475566 solid 1px; - } - } - } } button { diff --git a/ui/src/controller/selection_controller.ts b/ui/src/controller/selection_controller.ts index 34dbfd1f1..82ab2ce32 100644 --- a/ui/src/controller/selection_controller.ts +++ b/ui/src/controller/selection_controller.ts @@ -14,7 +14,9 @@ import {Engine} from '../common/engine'; import {fromNs, toNs} from '../common/time'; -import {CounterDetails, SliceDetails} from '../frontend/globals'; +import {Arg, Args, CounterDetails, SliceDetails} from '../frontend/globals'; +import {SLICE_TRACK_KIND} from '../tracks/chrome_slices/common'; + import {Controller} from './controller'; import {globals} from './globals'; @@ -140,8 +142,8 @@ export class SelectionController extends Controller<'main'> { return map; } - async getArgs(argId: number): Promise<Map<string, string>> { - const args = new Map<string, string>(); + async getArgs(argId: number): Promise<Args> { + const args = new Map<string, Arg>(); const query = ` select flat_key AS name, @@ -153,11 +155,36 @@ export class SelectionController extends Controller<'main'> { for (let i = 0; i < result.numRecords; i++) { const name = result.columns[0].stringValues![i]; const value = result.columns[1].stringValues![i]; - args.set(name, value); + if (name === 'destination slice id' && !isNaN(Number(value))) { + const destTrackId = await this.getDestTrackId(value); + args.set( + 'Destination Slice', + {kind: 'SLICE', trackId: destTrackId, sliceId: Number(value)}); + } else { + args.set(name, value); + } } return args; } + async getDestTrackId(sliceId: string): Promise<string> { + const trackIdQuery = `select track_id from slice + where slice_id = ${sliceId}`; + const destResult = await this.args.engine.query(trackIdQuery); + const trackIdTp = destResult.columns[0].longValues![0]; + // TODO(taylori): If we had a consistent mapping from TP track_id + // UI track id for slice tracks this would be unnecessary. + let trackId = ''; + for (const track of Object.values(globals.state.tracks)) { + if (track.kind === SLICE_TRACK_KIND && + (track.config as {trackId: number}).trackId === Number(trackIdTp)) { + trackId = track.id; + break; + } + } + return trackId; + } + async sliceDetails(id: number) { const sqlQuery = `SELECT ts, dur, priority, end_state, utid, cpu FROM sched WHERE id = ${id}`; diff --git a/ui/src/frontend/chrome_slice_panel.ts b/ui/src/frontend/chrome_slice_panel.ts index a0a7f35ea..f211cb7d9 100644 --- a/ui/src/frontend/chrome_slice_panel.ts +++ b/ui/src/frontend/chrome_slice_panel.ts @@ -14,10 +14,12 @@ import * as m from 'mithril'; +import {Actions} from '../common/actions'; import {timeToCode, toNs} from '../common/time'; -import {globals} from './globals'; +import {Args, globals} from './globals'; import {Panel, PanelSize} from './panel'; +import {verticalScrollToTrack} from './scroll_helper'; export class ChromeSliceDetailsPanel extends Panel { view() { @@ -64,11 +66,35 @@ export class ChromeSliceDetailsPanel extends Panel { renderCanvas(_ctx: CanvasRenderingContext2D, _size: PanelSize) {} - getArgs(args?: Map<string, string>): m.Vnode[] { + getArgs(args?: Args): m.Vnode[] { if (!args || args.size === 0) return []; const result = []; for (const [key, value] of args) { - result.push(m('tr', m('th', key), m('td', value))); + if (typeof value === 'string') { + result.push(m('tr', m('th', key), m('td', value))); + } else { + result.unshift( + m('tr', + m('th', key), + m('td', + m('i.material-icons.grey', + { + onclick: () => { + globals.makeSelection(Actions.selectChromeSlice({ + id: value.sliceId, + trackId: value.trackId, + table: 'slice' + })); + // Ideally we want to have a callback to + // findCurrentSelection after this selection has been + // made. Here we do not have the info for horizontally + // scrolling to ts. + verticalScrollToTrack(value.trackId, true); + }, + title: 'Go to destination slice' + }, + 'call_made')))); + } } return result; } diff --git a/ui/src/frontend/globals.ts b/ui/src/frontend/globals.ts index 88650d514..5b859ad2b 100644 --- a/ui/src/frontend/globals.ts +++ b/ui/src/frontend/globals.ts @@ -27,7 +27,8 @@ type TrackDataStore = Map<string, {}>; type QueryResultsStore = Map<string, {}>; type AggregateDataStore = Map<string, AggregateData>; type Description = Map<string, string>; -type Args = Map<string, string>; +export type Arg = string|{kind: 'SLICE', trackId: string, sliceId: number}; +export type Args = Map<string, Arg>; export interface SliceDetails { ts?: number; dur?: number; |