aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIsabelle Taylor <taylori@google.com>2020-06-09 22:40:16 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-06-09 22:40:16 +0000
commitcf291b56f640cb0dcf6661ffe783140866fec53a (patch)
treebed514f28a019bf3dbc2d9be195d87dd8ce07f65
parente091edaf595bb40892f1bc5df0d096cfc269a6aa (diff)
parent156a1304067a2fdafc4ae0d7dbc80b23fbb1d7de (diff)
downloadperfetto-cf291b56f640cb0dcf6661ffe783140866fec53a.tar.gz
Merge "perfetto-ui: Add go to dest button for binder slices" am: 2911cba7a7 am: 577378cdcc am: e7cd72fb0a am: 156a130406
Original change: https://android-review.googlesource.com/c/platform/external/perfetto/+/1325071 Change-Id: I11d5cf11aa1e3e514a55fa77b7743ec1c4dba55c
-rw-r--r--src/trace_processor/importers/common/slice_tracker.cc13
-rw-r--r--src/trace_processor/importers/common/slice_tracker.h8
-rw-r--r--src/trace_processor/importers/ftrace/binder_tracker.cc30
-rw-r--r--src/trace_processor/importers/ftrace/binder_tracker.h1
-rw-r--r--ui/src/assets/details.scss34
-rw-r--r--ui/src/controller/selection_controller.ts35
-rw-r--r--ui/src/frontend/chrome_slice_panel.ts32
-rw-r--r--ui/src/frontend/globals.ts3
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;