OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright 2016 The Chromium Authors. All rights reserved. | 3 Copyright 2016 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/extras/chrome/chrome_user_friendly_category_dr
iver.html"> | 8 <link rel="import" href="/tracing/extras/chrome/chrome_user_friendly_category_dr
iver.html"> |
9 <link rel="import" href="/tracing/metrics/metric_registry.html"> | 9 <link rel="import" href="/tracing/metrics/metric_registry.html"> |
10 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> | 10 <link rel="import" href="/tracing/model/helpers/chrome_model_helper.html"> |
11 <link rel="import" href="/tracing/value/histogram.html"> | 11 <link rel="import" href="/tracing/value/histogram.html"> |
12 | 12 |
13 <script> | 13 <script> |
14 'use strict'; | 14 'use strict'; |
15 | 15 |
16 tr.exportTo('tr.metrics.sh', function() { | 16 tr.exportTo('tr.metrics.sh', function() { |
17 const LONG_TASK_MS = 50; | 17 const LONG_TASK_MS = 50; |
18 | 18 |
19 // Anything longer than this should be so rare that its length beyond this is | 19 // Anything longer than this should be so rare that its length beyond this is |
20 // uninteresting. | 20 // uninteresting. |
21 const LONGEST_TASK_MS = 1000; | 21 const LONGEST_TASK_MS = 1000; |
22 | 22 |
23 /** | 23 /** |
24 * This helper function calls |cb| for each of the top-level tasks on the | 24 * This yields the top-level tasks on the given thread in the given range |
25 * given thread in the given range whose duration is longer than LONG_TASK_MS. | 25 * whose duration is longer than LONG_TASK_MS. |
26 * | 26 * |
27 * @param {tr.model.Thread} thread | 27 * @param {tr.model.Thread} thread |
28 * @param {tr.b.math.Range=} opt_range | 28 * @param {tr.b.math.Range=} opt_range |
29 * @param {function()} cb | |
30 * @param {Object=} opt_this | |
31 */ | 29 */ |
32 function iterateLongTopLevelTasksOnThreadInRange( | 30 function* iterateLongTopLevelTasksOnThreadInRange(thread, opt_range) { |
33 thread, opt_range, cb, opt_this) { | 31 for (const slice of thread.sliceGroup.topLevelSlices) { |
34 thread.sliceGroup.topLevelSlices.forEach(function(slice) { | |
35 if (opt_range && | 32 if (opt_range && |
36 !opt_range.intersectsExplicitRangeInclusive(slice.start, slice.end)) { | 33 !opt_range.intersectsExplicitRangeInclusive(slice.start, slice.end)) { |
37 return; | 34 continue; |
38 } | 35 } |
39 | 36 |
40 if (slice.duration < LONG_TASK_MS) return; | 37 if (slice.duration < LONG_TASK_MS) continue; |
41 | 38 |
42 cb.call(opt_this, slice); | 39 yield slice; |
43 }); | 40 } |
44 } | 41 } |
45 | 42 |
46 /** | 43 /** |
47 * This helper function calls |cb| for each of the main renderer threads in | 44 * This yields the main renderer threads in the model. |
48 * the model. | |
49 * | 45 * |
50 * @param {tr.model.Model} model The model. | 46 * @param {tr.model.Model} model The model. |
51 * @param {function()} cb Callback. | |
52 * @param {Object=} opt_this Context object. | |
53 */ | 47 */ |
54 function iterateRendererMainThreads(model, cb, opt_this) { | 48 function* iterateRendererMainThreads(model) { |
55 const modelHelper = model.getOrCreateHelper( | 49 const modelHelper = model.getOrCreateHelper( |
56 tr.model.helpers.ChromeModelHelper); | 50 tr.model.helpers.ChromeModelHelper); |
57 if (modelHelper !== undefined) { | 51 if (modelHelper === undefined) return; |
58 Object.values(modelHelper.rendererHelpers).forEach( | 52 for (const rendererHelper of Object.values(modelHelper.rendererHelpers)) { |
59 function(rendererHelper) { | 53 if (!rendererHelper.mainThread) continue; |
60 if (!rendererHelper.mainThread) return; | 54 yield rendererHelper.mainThread; |
61 | |
62 cb.call(opt_this, rendererHelper.mainThread); | |
63 }); | |
64 } | 55 } |
65 } | 56 } |
66 | 57 |
67 /** | 58 /** |
68 * This metric directly measures long tasks on renderer main threads. | 59 * This metric directly measures long tasks on renderer main threads. |
69 * This metric requires only the 'toplevel' tracing category. | 60 * This metric requires only the 'toplevel' tracing category. |
70 * | 61 * |
71 * @param {!tr.v.HistogramSet} histograms | 62 * @param {!tr.v.HistogramSet} histograms |
72 * @param {!tr.model.Model} model | 63 * @param {!tr.model.Model} model |
73 * @param {!Object=} opt_options | 64 * @param {!Object=} opt_options |
74 */ | 65 */ |
75 function longTasksMetric(histograms, model, opt_options) { | 66 function longTasksMetric(histograms, model, opt_options) { |
76 const rangeOfInterest = opt_options ? opt_options.rangeOfInterest : | 67 const rangeOfInterest = opt_options ? opt_options.rangeOfInterest : |
77 undefined; | 68 undefined; |
78 const longTaskHist = new tr.v.Histogram('long tasks', | 69 const longTaskHist = histograms.createHistogram( |
79 tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, | 70 'longTasks', tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, [], { |
80 tr.v.HistogramBinBoundaries.createLinear( | 71 description: 'wall durations of long tasks', |
81 LONG_TASK_MS, LONGEST_TASK_MS, 40)); | 72 binBoundaries: tr.v.HistogramBinBoundaries.createLinear( |
82 longTaskHist.description = 'durations of long tasks'; | 73 LONG_TASK_MS, LONGEST_TASK_MS, 40), |
83 const slices = new tr.model.EventSet(); | 74 }); |
84 iterateRendererMainThreads(model, function(thread) { | 75 |
85 iterateLongTopLevelTasksOnThreadInRange( | 76 const relatedHistograms = new Map(); |
86 thread, rangeOfInterest, function(task) { | 77 const relatedNames = new tr.v.d.RelatedNameMap(); |
87 longTaskHist.addSample(task.duration, | 78 longTaskHist.diagnostics.set('breakdown', relatedNames); |
88 {relatedEvents: new tr.v.d.RelatedEventSet([task])}); | 79 const binBoundaries = tr.v.HistogramBinBoundaries.createExponential( |
89 slices.push(task); | 80 1, LONGEST_TASK_MS, 40); |
90 slices.addEventSet(task.descendentSlices); | 81 |
| 82 for (const thread of iterateRendererMainThreads(model)) { |
| 83 for (const task of iterateLongTopLevelTasksOnThreadInRange( |
| 84 thread, rangeOfInterest)) { |
| 85 const breakdown = new tr.v.d.Breakdown(); |
| 86 breakdown.colorScheme = |
| 87 tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER; |
| 88 for (const slice of task.descendentSlices) { |
| 89 const category = model.getUserFriendlyCategoryFromEvent(slice) || |
| 90 'unknown'; |
| 91 const relatedName = `longTasks:${category}`; |
| 92 let relatedHist = relatedHistograms.get(category); |
| 93 if (!relatedHist) { |
| 94 relatedHist = histograms.createHistogram( |
| 95 relatedName, longTaskHist.unit, [], { |
| 96 binBoundaries, |
| 97 }); |
| 98 relatedHistograms.set(category, relatedHist); |
| 99 relatedNames.set(category, relatedName); |
| 100 } |
| 101 const sample = slice.cpuSelfTime; |
| 102 breakdown.set(category, breakdown.get(category) + sample); |
| 103 relatedHist.addSample(sample, { |
| 104 event: new tr.v.d.RelatedEventSet(slice), |
91 }); | 105 }); |
92 }); | 106 } |
93 histograms.addHistogram(longTaskHist); | |
94 | 107 |
95 const sampleForEvent = undefined; | 108 longTaskHist.addSample(task.duration, { |
96 const breakdown = tr.v.d.RelatedHistogramBreakdown.buildFromEvents( | 109 breakdown, |
97 histograms, 'long tasks ', slices, | 110 task: new tr.v.d.RelatedEventSet(task), |
98 e => (model.getUserFriendlyCategoryFromEvent(e) || 'unknown'), | 111 }); |
99 tr.b.Unit.byName.timeDurationInMs_smallerIsBetter, sampleForEvent, | 112 } |
100 tr.v.HistogramBinBoundaries.createExponential(1, LONGEST_TASK_MS, 40)); | 113 } |
101 breakdown.colorScheme = | |
102 tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER; | |
103 longTaskHist.diagnostics.set('category', breakdown); | |
104 } | 114 } |
105 | 115 |
106 tr.metrics.MetricRegistry.register(longTasksMetric, { | 116 tr.metrics.MetricRegistry.register(longTasksMetric, { |
107 supportsRangeOfInterest: true | 117 supportsRangeOfInterest: true |
108 }); | 118 }); |
109 | 119 |
110 return { | 120 return { |
111 longTasksMetric, | 121 longTasksMetric, |
112 iterateLongTopLevelTasksOnThreadInRange, | |
113 iterateRendererMainThreads, | |
114 LONG_TASK_MS, | |
115 LONGEST_TASK_MS, | |
116 }; | 122 }; |
117 }); | 123 }); |
118 </script> | 124 </script> |
OLD | NEW |