• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this 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 */
15
16import {BaseElement, element} from "../../../../base-ui/BaseElement.js";
17import {LitTable} from "../../../../base-ui/table/lit-table.js";
18import {SelectionData, SelectionParam} from "../../../bean/BoxSelection.js";
19import "../../StackBar.js"
20import {getTabThreadStates} from "../../../database/SqlLite.js";
21import {Utils} from "../base/Utils.js";
22import {StackBar} from "../../StackBar.js";
23import {log} from "../../../../log/Log.js";
24
25@element('tabpane-thread-states')
26export class TabPaneThreadStates extends BaseElement {
27    private tbl: LitTable | null | undefined;
28    private range: HTMLLabelElement | null | undefined;
29    private stackBar: StackBar | null | undefined;
30    private source: Array<SelectionData> = []
31
32    set data(val: SelectionParam | any) {
33        //@ts-ignore
34        this.tbl?.shadowRoot?.querySelector(".table")?.style?.height = (this.parentElement!.clientHeight - 45) + "px";
35        // // @ts-ignore
36        this.range!.textContent = "Selected range: " + ((val.rightNs - val.leftNs) / 1000000.0).toFixed(5) + " ms"
37        getTabThreadStates(val.threadIds, val.leftNs, val.rightNs).then((result) => {
38            if (result != null && result.length > 0) {
39                log("getTabThreadStates result size : " + result.length)
40                let sumWall = 0.0;
41                let sumOcc = 0;
42                for (let e of result) {
43                    e.process = e.process == null || e.process.length == 0 ? "[NULL]" : e.process
44                    e.thread = e.thread == null || e.thread.length == 0 ? "[NULL]" : e.thread
45                    sumWall += e.wallDuration
46                    sumOcc += e.occurrences
47                    e.stateJX = e.state
48                    e.state = Utils.getEndState(e.stateJX);
49                    e.wallDuration = parseFloat((e.wallDuration / 1000000.0).toFixed(5));
50                    e.avgDuration = parseFloat((e.avgDuration / 1000000.0).toFixed(5));
51                }
52                let count = new SelectionData()
53                count.process = " "
54                count.state = " "
55                count.wallDuration = parseFloat((sumWall / 1000000.0).toFixed(5));
56                count.occurrences = sumOcc;
57                result.splice(0, 0, count)
58                this.source = result;
59                this.tbl!.recycleDataSource = result
60                this.stackBar!.data = result;
61            } else {
62                this.source = []
63                this.stackBar!.data = []
64                this.tbl!.recycleDataSource = []
65            }
66        })
67    }
68
69    initElements(): void {
70        this.tbl = this.shadowRoot?.querySelector<LitTable>('#tb-thread-states');
71        this.range = this.shadowRoot?.querySelector('#time-range');
72        this.stackBar = this.shadowRoot?.querySelector('#stack-bar');
73        this.tbl!.addEventListener('column-click', (evt: any) => {
74            this.sortByColumn(evt.detail)
75        });
76        new ResizeObserver((entries) => {
77            if (this.parentElement?.clientHeight != 0) {
78                // @ts-ignore
79                this.tbl?.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight - 45) + "px"
80                this.tbl?.reMeauseHeight()
81            }
82        }).observe(this.parentElement!)
83    }
84
85    initHtml(): string {
86        return `
87        <style>
88        :host{
89            display: flex;
90            flex-direction: column;
91            padding: 10px 10px;
92        }
93        </style>
94        <div style="display: flex;height: 20px;align-items: center;flex-direction: row;margin-bottom: 5px">
95            <stack-bar id="stack-bar" style="flex: 1"></stack-bar>
96            <label id="time-range"  style="width: auto;text-align: end;font-size: 10pt;">Selected range:0.0 ms</label>
97        </div>
98        <lit-table id="tb-thread-states" style="height: auto">
99            <lit-table-column width="25%" title="Process" data-index="process" key="process"  align="flex-start" order>
100            </lit-table-column>
101            <lit-table-column width="1fr" title="PID" data-index="pid" key="pid"  align="flex-start" order >
102            </lit-table-column>
103            <lit-table-column width="20%" title="Thread" data-index="thread" key="thread"  align="flex-start" order >
104            </lit-table-column>
105            <lit-table-column width="1fr" title="TID" data-index="tid" key="tid"  align="flex-start" order >
106            </lit-table-column>
107            <lit-table-column width="1fr" title="State" data-index="state" key="state"  align="flex-start" order >
108            </lit-table-column>
109            <lit-table-column width="1fr" title="Wall duration(ms)" data-index="wallDuration" key="wallDuration"  align="flex-start" order >
110            </lit-table-column>
111            <lit-table-column width="1fr" title="Avg Wall duration(ms)" data-index="avgDuration" key="avgDuration"  align="flex-start" order >
112            </lit-table-column>
113            <lit-table-column width="1fr" title="Occurrences" data-index="occurrences" key="occurrences"  align="flex-start" order >
114            </lit-table-column>
115        </lit-table>
116        `;
117    }
118
119    sortByColumn(detail: any) {
120        function compare(property: any, sort: any, type: any) {
121            return function (a: SelectionData | any, b: SelectionData | any) {
122                if (a.process == " " || b.process == " ") {
123                    return 0;
124                }
125                if (type === 'number') {
126                    return sort === 2 ? parseFloat(b[property]) - parseFloat(a[property]) : parseFloat(a[property]) - parseFloat(b[property]);
127                } else {
128                    if (b[property] > a[property]) {
129                        return sort === 2 ? 1 : -1;
130                    } else if (b[property] == a[property]) {
131                        return 0;
132                    } else {
133                        return sort === 2 ? -1 : 1;
134                    }
135                }
136            }
137        }
138
139        if (detail.key === "name" || detail.key === "thread" || detail.key === "state") {
140            this.source.sort(compare(detail.key, detail.sort, 'string'))
141        } else {
142            this.source.sort(compare(detail.key, detail.sort, 'number'))
143        }
144        this.tbl!.recycleDataSource = this.source;
145    }
146
147}