|
2 | 2 | // Licensed under the MIT License. |
3 | 3 | using System; |
4 | 4 | using System.Collections.Generic; |
| 5 | +using System.Diagnostics; |
5 | 6 | using System.IO; |
6 | 7 | using System.Linq; |
7 | 8 | using System.Reflection; |
|
14 | 15 | using PerfettoCds.Pipeline.DataOutput; |
15 | 16 | using PerfettoCds.Pipeline.SourceDataCookers; |
16 | 17 | using PerfettoProcessor; |
17 | | -using Utilities; |
18 | 18 |
|
19 | 19 | namespace PerfettoCds.Pipeline.CompositeDataCookers |
20 | 20 | { |
@@ -182,7 +182,43 @@ from processTrackProcess in pd2.DefaultIfEmpty() |
182 | 182 | select new { slice, args, threadTrack, thread, threadProcess, threadProcessProcess, processTrackProcess }; |
183 | 183 |
|
184 | 184 | var longestRelTS = joined.Max(f => f.slice?.RelativeTimestamp); |
185 | | - var longestEndTs = longestRelTS.HasValue ? new Timestamp(longestRelTS.Value) : Timestamp.MaxValue; |
| 185 | + var longestEndTs = longestRelTS.HasValue ? new Timestamp(longestRelTS.Value) : Timestamp.MaxValue; |
| 186 | + |
| 187 | + Dictionary<int, long> SliceId_DurationExclusive = new Dictionary<int, long>(); |
| 188 | + // Duration Exclusion calculation (Duration minus child durations) |
| 189 | + // First we need to walk all the events & their direct parent |
| 190 | + // Slices seem to be per-thread in Perfetto and thus are non-overlapping (time-wise work) |
| 191 | + // Thus we can just subtract children time |
| 192 | + foreach (var result in joined) |
| 193 | + { |
| 194 | + int? parentId = result.slice.ParentId; |
| 195 | + |
| 196 | + if (!SliceId_DurationExclusive.ContainsKey(result.slice.Id)) |
| 197 | + { |
| 198 | + SliceId_DurationExclusive[result.slice.Id] = result.slice.Duration; |
| 199 | + } |
| 200 | + |
| 201 | + if (parentId.HasValue) |
| 202 | + { |
| 203 | + var parentPerfettoSliceEvent = sliceData[parentId.Value]; |
| 204 | + if (parentPerfettoSliceEvent != null) |
| 205 | + { |
| 206 | + if (SliceId_DurationExclusive.TryGetValue(parentId.Value, out long currentParentExDuration)) |
| 207 | + { |
| 208 | + // Some slices have negative duration and we don't want to increase exclusive duration of parent for this |
| 209 | + if (result.slice.Duration > 0 && currentParentExDuration > 0) |
| 210 | + { |
| 211 | + SliceId_DurationExclusive[parentId.Value] = currentParentExDuration - result.slice.Duration; |
| 212 | + } |
| 213 | + Debug.Assert(SliceId_DurationExclusive[parentId.Value] >= -1); // Verify non-overlapping otherwise duration will go negative excluding bad durations |
| 214 | + } |
| 215 | + else |
| 216 | + { |
| 217 | + SliceId_DurationExclusive.Add(parentId.Value, parentPerfettoSliceEvent.Duration); |
| 218 | + } |
| 219 | + } |
| 220 | + } |
| 221 | + } |
186 | 222 |
|
187 | 223 | // Create events out of the joined results |
188 | 224 | foreach (var result in joined) |
@@ -238,14 +274,14 @@ from processTrackProcess in pd2.DefaultIfEmpty() |
238 | 274 | } |
239 | 275 |
|
240 | 276 | int parentTreeDepthLevel = 0; |
241 | | - long? currentParentId = result.slice.ParentId; |
| 277 | + int? currentParentId = result.slice.ParentId; |
242 | 278 | List<string> tmpParentEventNameTreeBranch = new List<string>(); |
243 | 279 | tmpParentEventNameTreeBranch.Add(result.slice.Name); |
244 | 280 |
|
245 | 281 | // Walk the parent tree |
246 | 282 | while (currentParentId.HasValue) |
247 | 283 | { |
248 | | - var parentPerfettoSliceEvent = sliceData[(int)currentParentId.Value]; |
| 284 | + var parentPerfettoSliceEvent = sliceData[currentParentId.Value]; |
249 | 285 | // Debug.Assert(parentPerfettoSliceEvent == null || (parentPerfettoSliceEvent.Id == currentParentId.Value)); // Should be guaranteed by slice Id ordering. Since we are relying on index being the Id |
250 | 286 |
|
251 | 287 | if (parentPerfettoSliceEvent != null) |
@@ -273,9 +309,11 @@ from processTrackProcess in pd2.DefaultIfEmpty() |
273 | 309 |
|
274 | 310 | PerfettoGenericEvent ev = new PerfettoGenericEvent |
275 | 311 | ( |
| 312 | + result.slice.Id, |
276 | 313 | result.slice.Name, |
277 | 314 | result.slice.Type, |
278 | 315 | new TimestampDelta(result.slice.Duration), |
| 316 | + new TimestampDelta(SliceId_DurationExclusive[result.slice.Id]), |
279 | 317 | new Timestamp(result.slice.RelativeTimestamp), |
280 | 318 | result.slice.Duration >= 0 ? // Duration can be not complete / negative |
281 | 319 | new Timestamp(result.slice.RelativeTimestamp + result.slice.Duration) : |
|
0 commit comments