xref: /openbmc/openbmc-tools/dbus-vis/boost_handler_timeline_vis.js (revision 27cf933227bdd9cb91eade05b65bc5e1de00bb20)
1b65280ffSSui Chen// This script deals with Boost ASIO handlers
2b65280ffSSui Chen// Will need to add code to visualize one-shot events
3b65280ffSSui Chen
4b65280ffSSui Chen// Fields: HandlerNumber, Level,
5b65280ffSSui Chen// Creation time, Enter time, Exit time, EnterDescription,
6b65280ffSSui Chen//    [ [Operation, time] ]
7b65280ffSSui Chen
8b65280ffSSui Chen// Will use g_StartingSec as the starting of epoch
9b65280ffSSui Chen
10b65280ffSSui Chenvar ASIO_Data = [];
11b65280ffSSui Chenvar ASIO_Timestamp = [];
12b65280ffSSui Chen
13b65280ffSSui Chenfunction FindFirstEntrySlot(slots) {
14b65280ffSSui Chen  let i = 0;
15b65280ffSSui Chen  for (; i < slots.length; i++) {
16b65280ffSSui Chen    if (slots[i] == undefined) break;
17b65280ffSSui Chen  }
18b65280ffSSui Chen  if (i >= slots.length) slots.push(undefined);
19b65280ffSSui Chen  return i;
20b65280ffSSui Chen}
21b65280ffSSui Chen
22b65280ffSSui Chenfunction SimplifyDesc(desc) {
23b65280ffSSui Chen  const idx0 = desc.indexOf('0x');
24b65280ffSSui Chen  if (idx0 == -1)
25b65280ffSSui Chen    return desc;
26b65280ffSSui Chen  else {
27b65280ffSSui Chen    const d1 = desc.substr(idx0 + 2);
28b65280ffSSui Chen    let idx1 = 0;
29b65280ffSSui Chen    while (idx1 + 1 < d1.length &&
30b65280ffSSui Chen           ((d1[idx1] >= '0' && d1[idx1] <= '9') ||
31b65280ffSSui Chen            (d1[idx1] >= 'A' && d1[idx1] <= 'F') ||
32b65280ffSSui Chen            (d1[idx1] >= 'a' && d1[idx1] <= 'f'))) {
33b65280ffSSui Chen      idx1++;
34b65280ffSSui Chen    }
35b65280ffSSui Chen    return desc.substr(0, idx0) + d1.substr(idx1)
36b65280ffSSui Chen  }
37b65280ffSSui Chen}
38b65280ffSSui Chen
39b65280ffSSui Chenfunction ParseBoostHandlerTimeline(content) {
40b65280ffSSui Chen  let parsed_entries = [];
41b65280ffSSui Chen  const lines = content.split('\n');
42b65280ffSSui Chen  let slots = [];               // In-flight handlers
43b65280ffSSui Chen  let in_flight_id2level = {};  // In-flight ID to level
44b65280ffSSui Chen
45b65280ffSSui Chen  for (let lidx = 0; lidx < lines.length; lidx++) {
46b65280ffSSui Chen    const line = lines[lidx];
47b65280ffSSui Chen    if (line.startsWith('@asio|') == false) continue;
48b65280ffSSui Chen    const sp = line.split('|');
49b65280ffSSui Chen
50b65280ffSSui Chen    const tag = sp[0], ts = sp[1], action = sp[2], desc = sp[3];
51b65280ffSSui Chen    let handler_id = -999;
52b65280ffSSui Chen    let ts_sec = parseFloat(ts);
53b65280ffSSui Chen    const simp_desc = SimplifyDesc(desc);
54b65280ffSSui Chen
55b65280ffSSui Chen    if (action.indexOf('*') != -1) {
56b65280ffSSui Chen      const idx = action.indexOf('*');
57b65280ffSSui Chen      const handler_id = parseInt(action.substr(idx + 1));
58b65280ffSSui Chen      const level = FindFirstEntrySlot(slots);
59b65280ffSSui Chen
60b65280ffSSui Chen      // Create an entry here
61b65280ffSSui Chen      let entry = [
62b65280ffSSui Chen        handler_id, level, ts_sec, undefined, undefined, desc, simp_desc, []
63b65280ffSSui Chen      ];
64b65280ffSSui Chen
65b65280ffSSui Chen      slots[level] = entry;
66b65280ffSSui Chen      in_flight_id2level[handler_id] = level;
67b65280ffSSui Chen    } else if (action[0] == '>') {  // The program enters handler number X
68b65280ffSSui Chen      handler_id = parseInt(action.substr(1));
69b65280ffSSui Chen      if (handler_id in in_flight_id2level) {
70b65280ffSSui Chen        const level = in_flight_id2level[handler_id];
71b65280ffSSui Chen        let entry = slots[level];
72b65280ffSSui Chen        entry[3] = ts_sec;
73b65280ffSSui Chen      }
74b65280ffSSui Chen    } else if (action[0] == '<') {
75b65280ffSSui Chen      handler_id = parseInt(action.substr(1));
76b65280ffSSui Chen      if (handler_id in in_flight_id2level) {
77b65280ffSSui Chen        const level = in_flight_id2level[handler_id];
78b65280ffSSui Chen        let entry = slots[level];
79b65280ffSSui Chen        entry[4] = ts_sec;
80b65280ffSSui Chen        slots[level] = undefined;
81b65280ffSSui Chen        parsed_entries.push(entry);
82b65280ffSSui Chen        delete in_flight_id2level[handler_id];
83b65280ffSSui Chen      }
84b65280ffSSui Chen    } else if (action[0] == '.') {  // syscalls
85b65280ffSSui Chen    }
86b65280ffSSui Chen  }
87b65280ffSSui Chen
88b65280ffSSui Chen  console.log(
89b65280ffSSui Chen      'Boost handler log: ' + parsed_entries.length + ' entries' +
90b65280ffSSui Chen      ', ' + slots.length + ' levels');
91b65280ffSSui Chen  ASIO_Data = parsed_entries;
92b65280ffSSui Chen  return parsed_entries;
93b65280ffSSui Chen}
94b65280ffSSui Chen
95b65280ffSSui Chenfunction Group_ASIO(preprocessed, group_by) {
96b65280ffSSui Chen  let grouped = {};
97b65280ffSSui Chen  const IDXES = {'Layout Level': 1, 'Description': 5, 'Description1': 6};
98b65280ffSSui Chen  for (var n = 0; n < preprocessed.length; n++) {
99b65280ffSSui Chen    var key = ''
100b65280ffSSui Chen    for (var i = 0; i < group_by.length; i++) {
101b65280ffSSui Chen      if (i > 0) key += ' ';
102b65280ffSSui Chen      key += ('' + preprocessed[n][IDXES[group_by[i]]]);
103b65280ffSSui Chen    }
104b65280ffSSui Chen    if (grouped[key] == undefined) grouped[key] = [];
105b65280ffSSui Chen    grouped[key].push(preprocessed[n]);
106b65280ffSSui Chen  }
107b65280ffSSui Chen  return grouped;
108b65280ffSSui Chen}
109b65280ffSSui Chen
110b65280ffSSui Chenfunction OnGroupByConditionChanged_ASIO() {
111b65280ffSSui Chen  var tags = ['bah1', 'bah2', 'bah3'];
112b65280ffSSui Chen  const v = boost_asio_handler_timeline_view;
113b65280ffSSui Chen  v.GroupBy = [];
114b65280ffSSui Chen  v.GroupByStr = '';
115b65280ffSSui Chen  for (let i = 0; i < tags.length; i++) {
116b65280ffSSui Chen    let cb = document.getElementById(tags[i]);
117b65280ffSSui Chen    if (cb.checked) {
118b65280ffSSui Chen      v.GroupBy.push(cb.value);
119b65280ffSSui Chen      if (v.GroupByStr.length > 0) {
120b65280ffSSui Chen        v.GroupByStr += ', ';
121b65280ffSSui Chen      }
122b65280ffSSui Chen      v.GroupByStr += cb.value;
123b65280ffSSui Chen    }
124b65280ffSSui Chen  }
125b65280ffSSui Chen  let preproc = ASIO_Data;
126b65280ffSSui Chen  let grouped = Group_ASIO(preproc, v.GroupBy);
127b65280ffSSui Chen  GenerateTimeLine_ASIO(grouped);
128b65280ffSSui Chen  boost_asio_handler_timeline_view.IsCanvasDirty = true;
129b65280ffSSui Chen}
130b65280ffSSui Chen
131b65280ffSSui Chenfunction GenerateTimeLine_ASIO(grouped) {
132b65280ffSSui Chen  const keys = Object.keys(grouped);
133b65280ffSSui Chen  let sortedKeys = keys.slice();
134b65280ffSSui Chen  let intervals = [];
135b65280ffSSui Chen  let titles = [];
136b65280ffSSui Chen
137b65280ffSSui Chen  const was_starting_time_undefined = (g_StartingSec == undefined);
138b65280ffSSui Chen
139b65280ffSSui Chen  for (let i = 0; i < sortedKeys.length; i++) {
140b65280ffSSui Chen    titles.push({"header":false, "title":sortedKeys[i], "intervals_idxes":[i] });
141b65280ffSSui Chen    line = [];
142b65280ffSSui Chen    for (let j = 0; j < grouped[sortedKeys[i]].length; j++) {
143b65280ffSSui Chen      let entry = grouped[sortedKeys[i]][j];
144b65280ffSSui Chen      let t0 = parseFloat(entry[3]);
145b65280ffSSui Chen      let t1 = parseFloat(entry[4]);
146b65280ffSSui Chen
147b65280ffSSui Chen      if (was_starting_time_undefined) {
148b65280ffSSui Chen        if (g_StartingSec == undefined) {
149b65280ffSSui Chen          g_StartingSec = t0;
150b65280ffSSui Chen        }
151b65280ffSSui Chen        g_StartingSec = Math.min(g_StartingSec, t0);
152b65280ffSSui Chen      }
153b65280ffSSui Chen
154b65280ffSSui Chen      line.push([t0, t1, entry, 'ok', 0]);
155b65280ffSSui Chen    }
156b65280ffSSui Chen    intervals.push(line);
157b65280ffSSui Chen  }
158b65280ffSSui Chen
159b65280ffSSui Chen  // Time shift
160b65280ffSSui Chen  for (let i = 0; i < intervals.length; i++) {
161b65280ffSSui Chen    for (let j = 0; j < intervals[i].length; j++) {
162b65280ffSSui Chen      let x = intervals[i][j];
163b65280ffSSui Chen      x[0] -= g_StartingSec;
164b65280ffSSui Chen      x[1] -= g_StartingSec;
165b65280ffSSui Chen    }
166b65280ffSSui Chen  }
167b65280ffSSui Chen
168b65280ffSSui Chen  boost_asio_handler_timeline_view.Intervals = intervals.slice();
169b65280ffSSui Chen  boost_asio_handler_timeline_view.Titles = titles.slice();
170b65280ffSSui Chen  boost_asio_handler_timeline_view.LayoutForOverlappingIntervals();
171b65280ffSSui Chen}
172b65280ffSSui Chen
173b65280ffSSui Chen// Main view object for Boost handler timeline
174b65280ffSSui Chen
175b65280ffSSui Chenboost_asio_handler_timeline_view = new BoostASIOHandlerTimelineView();
176b65280ffSSui Chenboost_asio_handler_timeline_view.IsCanvasDirty = true;
177b65280ffSSui Chen
178b65280ffSSui Chenfunction draw_timeline_boost_asio_handler(ctx) {
179b65280ffSSui Chen  boost_asio_handler_timeline_view.Render(ctx);
180b65280ffSSui Chen}
181b65280ffSSui Chen
182b65280ffSSui Chenlet Canvas_Asio = document.getElementById('my_canvas_boost_asio_handler');
183b65280ffSSui Chen
184b65280ffSSui ChenCanvas_Asio.onmousemove = function(event) {
185b65280ffSSui Chen  const v = boost_asio_handler_timeline_view;
186b65280ffSSui Chen  v.MouseState.x = event.pageX - this.offsetLeft;
187b65280ffSSui Chen  v.MouseState.y = event.pageY - this.offsetTop;
188*27cf9332SSui Chen  if (v.MouseState.pressed == true &&
189*27cf9332SSui Chen      v.MouseState.hoveredSide == 'timeline') {  // Update highlighted area
190b65280ffSSui Chen    v.HighlightedRegion.t1 = v.MouseXToTimestamp(v.MouseState.x);
191b65280ffSSui Chen  }
192b65280ffSSui Chen  v.OnMouseMove();
193b65280ffSSui Chen  v.IsCanvasDirty = true;
194b65280ffSSui Chen
195b65280ffSSui Chen  v.linked_views.forEach(function(u) {
196b65280ffSSui Chen    u.MouseState.x = event.pageX - Canvas_Asio.offsetLeft;
197b65280ffSSui Chen    u.MouseState.y = 0;                  // Do not highlight any entry
198*27cf9332SSui Chen    if (u.MouseState.pressed == true &&
199*27cf9332SSui Chen        u.MouseState.hoveredSide == 'timeline') {  // Update highlighted area
200b65280ffSSui Chen      u.HighlightedRegion.t1 = u.MouseXToTimestamp(u.MouseState.x);
201b65280ffSSui Chen    }
202b65280ffSSui Chen    u.OnMouseMove();
203b65280ffSSui Chen    u.IsCanvasDirty = true;
204b65280ffSSui Chen  });
205b65280ffSSui Chen};
206b65280ffSSui Chen
207b65280ffSSui ChenCanvas_Asio.onmousedown = function(event) {
208b65280ffSSui Chen  if (event.button == 0) {
209b65280ffSSui Chen    boost_asio_handler_timeline_view.OnMouseDown();
210b65280ffSSui Chen  }
211b65280ffSSui Chen};
212b65280ffSSui Chen
213b65280ffSSui ChenCanvas_Asio.onmouseup = function(event) {
214b65280ffSSui Chen  if (event.button == 0) {
215b65280ffSSui Chen    boost_asio_handler_timeline_view.OnMouseUp();
216b65280ffSSui Chen  }
217b65280ffSSui Chen};
218b65280ffSSui Chen
219b65280ffSSui ChenCanvas_Asio.onwheel = function(event) {
220b65280ffSSui Chen  boost_asio_handler_timeline_view.OnMouseWheel(event);
221b65280ffSSui Chen}
222