Exemple #1
0
        private void CalculateParallelEntries(Timeline timeline)
        {
            PerNodeThreadRootEntries calculatedPerNodeThreadRootEntries = new PerNodeThreadRootEntries();

            foreach (List <TimelineEntry> rootsInNode in timeline.PerNodeRootEntries)
            {
                foreach (TimelineEntry root in rootsInNode)
                {
                    CalculateParallelEntriesFor(root, calculatedPerNodeThreadRootEntries);
                }
            }
        }
Exemple #2
0
        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);
            }
        }