Exemplo n.º 1
0
        public static void TaskLink(TimelineEntry entry)
        {
            if (!IsTaskLink(entry))
            {
                return;
            }

            TimelineBuildEntry timelineBuildEntry = entry as TimelineBuildEntry;

            // because these messages aren't related to each other in any way other than parsing messages,
            // we'll be keeping a list of timeline entries which will open/close as the messages are processed
            List <TimelineEntry>       linkEntries = new List <TimelineEntry>();
            IEnumerable <MessageEvent> messages    = timelineBuildEntry.BuildEntry.ChildEvents.Where(_ => _ is MessageEvent)
                                                     .Select(_ => _ as MessageEvent);

            // find Pass 1 and Pass 2
            foreach (MessageEvent message in messages)
            {
                // Linker: Pass 1
                Match matchLinkerPass1 = s_LinkPass1.Match(message.Message);
                if (matchLinkerPass1.Success)
                {
                    double   elapsedTimeFromMessage = Double.Parse(matchLinkerPass1.Groups[2].Value, CultureInfo.InvariantCulture);
                    TimeSpan elapsedTime            = TimeSpanFromSeconds(elapsedTimeFromMessage);
                    DateTime startTimestamp         = message.Timestamp - elapsedTime;
                    if (startTimestamp < timelineBuildEntry.StartTimestamp)
                    {
                        startTimestamp = timelineBuildEntry.StartTimestamp;
                    }

                    TimelineEntry pass1Entry = new TimelineEntry(s_LinkerPass1Name, message.Context.NodeId, startTimestamp, message.Timestamp);
                    linkEntries.Add(pass1Entry);

                    pass1Entry.ThreadAffinity.SetParameters(pass1Entry.ThreadAffinity.ThreadId, ThreadAffinity.s_OffsetFromParentPostProcessedEntries, ThreadAffinity.s_OffsetFromParentPostProcessedEntriesIncrement);

                    continue;
                }

                // Linker: Pass 2
                Match matchLinkerPass2 = s_LinkPass2.Match(message.Message);
                if (matchLinkerPass2.Success)
                {
                    double   elapsedTimeFromMessage = Double.Parse(matchLinkerPass2.Groups[2].Value, CultureInfo.InvariantCulture);
                    TimeSpan elapsedTime            = TimeSpanFromSeconds(elapsedTimeFromMessage);
                    DateTime startTimestamp         = message.Timestamp - elapsedTime;
                    if (linkEntries.Count > 0 && startTimestamp < linkEntries.Last().EndTimestamp)
                    {
                        startTimestamp = linkEntries.Last().EndTimestamp;
                    }

                    TimelineEntry pass2Entry = new TimelineEntry(s_LinkerPass2Name, message.Context.NodeId, startTimestamp, message.Timestamp);
                    linkEntries.Add(pass2Entry);

                    pass2Entry.ThreadAffinity.SetParameters(pass2Entry.ThreadAffinity.ThreadId, ThreadAffinity.s_OffsetFromParentPostProcessedEntries, ThreadAffinity.s_OffsetFromParentPostProcessedEntriesIncrement);

                    continue;
                }
            }

            // this is the function that will be applied to all common linker messages except Pass 1 and Pass 2 messages
            Action <TimelineEntry, Tuple <MessageEvent, Match> > perCommonLinkerMessage = (parent, tuple) =>
            {
                MessageEvent message = tuple.Item1;
                Match        match   = tuple.Item2;

                double   elapsedTimeFromMessage = Double.Parse(match.Groups[3].Value, CultureInfo.InvariantCulture);
                TimeSpan elapsedTime            = TimeSpanFromSeconds(elapsedTimeFromMessage);
                DateTime startTimestamp         = message.Timestamp - elapsedTime;

                if (parent.ChildEntries.Count == 0 && startTimestamp < parent.StartTimestamp)
                {
                    startTimestamp = parent.StartTimestamp;
                }
                else if (parent.ChildEntries.Count > 0 && startTimestamp < parent.ChildEntries.Last().EndTimestamp)
                {
                    startTimestamp = parent.ChildEntries.Last().EndTimestamp;
                }

                TimelineEntry linkerEntry = new TimelineEntry(match.Groups[2].Value.Trim(), message.Context.NodeId, startTimestamp, message.Timestamp);
                parent.AddChild(linkerEntry);
            };

            // add entries within Pass 1
            TimelineEntry parentEntry = linkEntries.Find(_ => _.Name == s_LinkerPass1Name);

            if (parentEntry != null)
            {
                IEnumerable <Tuple <MessageEvent, Match> > messagesBeforePass1 = messages.TakeWhile(_ => !s_LinkPass1.Match(_.Message).Success)                      // take messages until Pass 1 message
                                                                                 .Select(_ => new Tuple <MessageEvent, Match>(_, s_LinkCommon.Match(_.Message)))     // match with common regex
                                                                                 .Where(_ => _.Item2.Success);                                                       // only take positive ones
                foreach (Tuple <MessageEvent, Match> tuple in messagesBeforePass1)
                {
                    perCommonLinkerMessage(parentEntry, tuple);
                }
            }

            // add entries within Pass 2
            parentEntry = linkEntries.Find(_ => _.Name == s_LinkerPass2Name);
            if (parentEntry != null)
            {
                IEnumerable <Tuple <MessageEvent, Match> > messagesBeforePass2 = messages.SkipWhile(_ => !s_LinkPass1.Match(_.Message).Success)                      // skip all messages until Pass 1
                                                                                 .Skip(1)                                                                            // skip Pass 1 included
                                                                                 .TakeWhile(_ => !s_LinkPass2.Match(_.Message).Success)                              // take messages until Pass 2 message
                                                                                 .Select(_ => new Tuple <MessageEvent, Match>(_, s_LinkCommon.Match(_.Message)))     // match with common regex
                                                                                 .Where(_ => _.Item2.Success);                                                       // only take positive ones
                foreach (Tuple <MessageEvent, Match> tuple in messagesBeforePass2)
                {
                    perCommonLinkerMessage(parentEntry, tuple);
                }
            }

            // add them all to the Link task
            linkEntries.ForEach(timelineBuildEntry.AddChild);
        }
Exemplo n.º 2
0
        private void ProcessMessageEvent(MessageEvent e, TimelineBuilderContext context)
        {
            Debug.Assert(context.HasOpenBuilds);

            // a message can be executed as part of any entry: build, project, target or task
            BuildEntry parentEntry = null;

            // part of the build?
            if (e.Context == null)
            {
                parentEntry = context.RootEntry;
            }
            else
            {
                MessageEventContext messageContext = e.Context as MessageEventContext;

                // part of a task?
                if (messageContext.TaskId != null)
                {
                    Debug.Assert(messageContext.ProjectId != null);
                    Debug.Assert(messageContext.TargetId != null);

                    parentEntry = context.OpenTaskEntries.Find(taskEntry =>
                    {
                        TaskEventContext taskContext = taskEntry.Context as TaskEventContext;
                        Debug.Assert(taskContext != null);

                        return(taskContext.NodeId == messageContext.NodeId &&
                               taskContext.ContextId == messageContext.ContextId &&
                               taskContext.ProjectId == messageContext.ProjectId &&
                               taskContext.TargetId == messageContext.TargetId &&
                               taskContext.TaskId == messageContext.TaskId);
                    });
                }
                // part of a target?
                else if (messageContext.TargetId != null)
                {
                    Debug.Assert(messageContext.ProjectId != null);
                    Debug.Assert(messageContext.TaskId == null);

                    parentEntry = context.OpenTargetEntries.Find(targetEntry =>
                    {
                        TargetEventContext targetContext = targetEntry.Context as TargetEventContext;
                        Debug.Assert(targetContext != null);

                        return(targetContext.NodeId == messageContext.NodeId &&
                               targetContext.ContextId == messageContext.ContextId &&
                               targetContext.ProjectId == messageContext.ProjectId &&
                               targetContext.TargetId == messageContext.TargetId);
                    });
                }
                // part of a project?
                else if (messageContext.ProjectId != null)
                {
                    Debug.Assert(messageContext.TargetId == null);
                    Debug.Assert(messageContext.TaskId == null);

                    parentEntry = context.OpenProjectEntries.Find(projectEntry =>
                    {
                        ProjectEventContext projectContext = projectEntry.Context as ProjectEventContext;
                        Debug.Assert(projectContext != null);

                        return(projectContext.NodeId == messageContext.NodeId &&
                               projectContext.ContextId == messageContext.ContextId &&
                               projectContext.ProjectId == messageContext.ProjectId);
                    });
                }
                // part of the build itself?
                else
                {
                    parentEntry = context.RootEntry;
                }
            }

            Debug.Assert(parentEntry != null);
            parentEntry.AddChild(e);
        }