private void CalculateParallelEntries(Timeline timeline) { PerNodeThreadRootEntries calculatedPerNodeThreadRootEntries = new PerNodeThreadRootEntries(); foreach (List <TimelineEntry> rootsInNode in timeline.PerNodeRootEntries) { foreach (TimelineEntry root in rootsInNode) { CalculateParallelEntriesFor(root, calculatedPerNodeThreadRootEntries); } } }
private void CalculateParallelEntriesFor(TimelineEntry entry, PerNodeThreadRootEntries nodeThreadRootEntries) { if (entry is TimelineBuildEntry) { entry.ThreadAffinity.SetParameters(entry.ThreadAffinity.ThreadId, 0, ThreadAffinity.s_OffsetMSBuildEntries); } if (entry.Parent != null) { // retrieve all of the overlapping siblings List <TimelineEntry> overlappingSiblings = new List <TimelineEntry>(); foreach (TimelineEntry sibling in entry.Parent.ChildEntries) { if (entry != sibling && entry.OverlapsWith(sibling)) { overlappingSiblings.Add(sibling); } } // we may have calculated some of the siblings, take their information into account foreach (TimelineEntry overlappingSibling in overlappingSiblings) { if (overlappingSibling.ThreadAffinity.Calculated) { entry.ThreadAffinity.AddInvalid(overlappingSibling.ThreadAffinity.ThreadId); } } } // also, check the overlapping root entries from each calculated thread within the same node foreach (var pair in nodeThreadRootEntries) { if (pair.Key.Item1 == entry.NodeId) { foreach (TimelineEntry root in pair.Value) { Debug.Assert(root.ThreadAffinity.Calculated); if (!root.IsAncestorOf(entry) && entry.OverlapsWith(root)) { entry.ThreadAffinity.AddInvalid(root.ThreadAffinity.ThreadId); } } } } // now calculate where we think the entry was executed entry.ThreadAffinity.Calculate(); // are we a new root? if (entry.Parent == null || entry.ThreadAffinity.ThreadId != entry.Parent.ThreadAffinity.ThreadId) { // get or create root list for the <node id, calculated thread id> Tuple <int, int> key = new Tuple <int, int>(entry.NodeId, entry.ThreadAffinity.ThreadId); List <TimelineEntry> rootsInNodeThread = null; if (!nodeThreadRootEntries.TryGetValue(key, out rootsInNodeThread)) { rootsInNodeThread = new List <TimelineEntry>(); nodeThreadRootEntries[key] = rootsInNodeThread; } rootsInNodeThread.Add(entry); } // now that we've decided where the entry was executed, transfer this data to child entries foreach (TimelineEntry child in entry.ChildEntries) { child.ThreadAffinity.InheritDataFrom(entry.ThreadAffinity); } // continue with child entries foreach (TimelineEntry child in entry.ChildEntries) { CalculateParallelEntriesFor(child, nodeThreadRootEntries); } }