• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2019 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use size file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import * as m from 'mithril';
16
17import {drawDoubleHeadedArrow} from '../common/canvas_utils';
18import {translateState} from '../common/thread_state';
19import {timeToCode} from '../common/time';
20
21import {globals} from './globals';
22import {Panel, PanelSize} from './panel';
23
24interface SliceDetailsPanelAttrs {
25  utid: number;
26}
27
28export class SliceDetailsPanel extends Panel<SliceDetailsPanelAttrs> {
29  view({attrs}: m.CVnode<SliceDetailsPanelAttrs>) {
30    const threadInfo = globals.threads.get(attrs.utid);
31    const sliceInfo = globals.sliceDetails;
32    if (threadInfo && sliceInfo.ts && sliceInfo.dur) {
33      return m(
34          '.details-panel',
35          m('.details-panel-heading', `Slice Details:`),
36          m('.details-table', [m('table', [
37              m('tr', m('th', `PID`), m('td', `${threadInfo.pid}`)),
38              m('tr',
39                m('th', `Process name`),
40                m('td', `${threadInfo.procName}`)),
41              m('tr', m('th', `TID`), m('td', `${threadInfo.tid}`)),
42              m('tr',
43                m('th', `Thread name`),
44                m('td', `${threadInfo.threadName}`)),
45              m('tr',
46                m('th', `Start time`),
47                m('td', `${timeToCode(sliceInfo.ts)}`)),
48              m('tr',
49                m('th', `Duration`),
50                m('td', `${timeToCode(sliceInfo.dur)}`)),
51              m('tr', m('th', `Prio`), m('td', `${sliceInfo.priority}`)),
52              m('tr',
53                m('th', `End State`),
54                m('td', `${translateState(sliceInfo.endState)}`))
55            ])], ));
56    }
57  else {
58      return m(
59          '.details-panel', m('.details-panel-heading', `Slice Details:`, ));
60  }
61}
62renderCanvas(ctx: CanvasRenderingContext2D, size: PanelSize) {
63  const details = globals.sliceDetails;
64  // Show expanded details on the scheduling of the currently selected slice.
65  if (details.wakeupTs && details.wakerUtid !== undefined) {
66    const threadInfo = globals.threads.get(details.wakerUtid);
67    // Draw separation line.
68    ctx.fillStyle = '#3c4b5d';
69    ctx.fillRect(size.width / 2, 10, 1, size.height - 10);
70    ctx.font = '16px Google Sans';
71    ctx.fillText('Scheduling Latency:', size.width / 2 + 30, 30);
72    // Draw diamond and vertical line.
73    const startDraw = {x: size.width / 2 + 30, y: 52};
74    ctx.beginPath();
75    ctx.moveTo(startDraw.x, startDraw.y + 28);
76    ctx.fillStyle = 'black';
77    ctx.lineTo(startDraw.x + 6, startDraw.y + 20);
78    ctx.lineTo(startDraw.x, startDraw.y + 12);
79    ctx.lineTo(startDraw.x - 6, startDraw.y + 20);
80    ctx.fill();
81    ctx.closePath();
82    ctx.fillRect(startDraw.x - 1, startDraw.y, 2, 100);
83
84    // Wakeup explanation text.
85    ctx.font = '13px Google Sans';
86    ctx.fillStyle = '#3c4b5d';
87    if (threadInfo) {
88      const displayText =
89          `Wakeup @ ${
90                      timeToCode(
91                          details.wakeupTs - globals.state.traceTime.startSec)
92                    } on CPU ${details.wakerCpu} by`;
93      const processText = `P: ${threadInfo.procName} [${threadInfo.pid}]`;
94      const threadText = `T: ${threadInfo.threadName} [${threadInfo.tid}]`;
95      ctx.fillText(displayText, startDraw.x + 20, startDraw.y + 20);
96      ctx.fillText(processText, startDraw.x + 20, startDraw.y + 37);
97      ctx.fillText(threadText, startDraw.x + 20, startDraw.y + 55);
98    }
99
100    // Draw latency arrow and explanation text.
101    drawDoubleHeadedArrow(ctx, startDraw.x, startDraw.y + 80, 60, true);
102    if (details.ts) {
103      const displayLatency =
104          `Scheduling latency: ${
105                                 timeToCode(
106                                     details.ts -
107                                     (details.wakeupTs -
108                                      globals.state.traceTime.startSec))
109                               }`;
110      ctx.fillText(displayLatency, startDraw.x + 70, startDraw.y + 86);
111      const explain1 =
112          'This is the interval from when the task became eligible to run';
113      const explain2 =
114          '(e.g. because of notifying a wait queue it was suspended on) to';
115      const explain3 = 'when it started running.';
116      ctx.font = '10px Google Sans';
117      ctx.fillText(explain1, startDraw.x + 70, startDraw.y + 86 + 16);
118      ctx.fillText(explain2, startDraw.x + 70, startDraw.y + 86 + 16 + 12);
119      ctx.fillText(explain3, startDraw.x + 70, startDraw.y + 86 + 16 + 24);
120    }
121  }
122}
123}
124