public Threadline(ThreadFlow flow, int order)
 {
     ThreadID = flow.ThreadID;
     Order = order;
     Name = flow.Name;
     IsAlive = flow.IsAlive;
 }
        private static void TrackFunctionCall(int nodeID, XNodeIn node, int thread)
        {
            // check that thread is in map
            ThreadFlow flow;
            if (!FlowMap.TryGetValue(thread, out flow))
            {
                flow = new ThreadFlow()
                {
                    ThreadID = thread,
                    Name = node.Name,
                    Handle = Thread.CurrentThread,
                    IsAlive = true
                };

                FlowMap.Add(thread, flow);

                if (Remote != null)
                    foreach (var client in Remote.SyncClients)
                        lock(client.NewThreads)
                            client.NewThreads[flow.ThreadID] = new Tuple<string,bool>(flow.Name, flow.IsAlive);
            }

            bool isMethod = (node.ObjType == XObjType.Method);

            if(isMethod)
                node.StillInside++;

            // if the first entry, return here
            if (flow.Pos == -1)
            {
                flow.CreateStackItem(nodeID, null, Watch.ElapsedTicks, isMethod, ThreadlineEnabled);
                node.EntryPoint++;
                return;
            }

            // if exceeded tracking max return
            if (flow.Pos >= flow.Stack.Length)
                return;

            // set the source, and put the dest in stack
            int source = flow.Stack[flow.Pos].NodeID;

            // the ids are small and auto-inc based on the # of funcs
            // just hashing together is not unique enough, and many conflicts because the numbers
            // are small and close together. so expand the number to a larger domain.
            // also ensure s->d != d->s
            int hash = source * FunctionCount + nodeID;

            FunctionCall call;
            if (!CallMap.TryGetValue(hash, out call))
                call = CreateNewCall(hash, source, node);

            if (source != call.Source || nodeID != call.Destination)
                LogError("Call mismatch  {0}->{1} != {2}->{3}\r\n", source, nodeID, call.Source, call.Destination);

            call.Hit = ShowTicks;
            call.TotalHits++;

            if (!call.ThreadIDs.Contains(thread))
            {
                call.ThreadIDs.Add(thread);

                if (Remote != null)
                    foreach (var client in Remote.SyncClients)
                        lock(client.CallThreads)
                            client.CallThreads.Add(new Tuple<int, int>(call.ID, thread));
            }

            if (Remote != null)
                foreach (var sync in Remote.SyncClients)
                    lock(sync.CallHits)
                        sync.CallHits.Add(hash);

            // if a method
            if (isMethod)
                call.StillInside++;

            flow.CreateStackItem(nodeID, call, Watch.ElapsedTicks, isMethod, ThreadlineEnabled);

            if(ClassTracking)
                TrackClassCall(call, thread);
        }
Exemple #3
0
        private static void TrackFunctionCall(int dest, XNodeIn node, int thread, object[] parameters, bool loadField=false)
        {
            // check that thread is in map
            ThreadFlow flow;
            if (!FlowMap.TryGetValue(thread, out flow))
            {
                flow = new ThreadFlow()
                {
                    ThreadID = thread,
                    Name = node.Name,
                    Handle = Thread.CurrentThread,
                    IsAlive = true
                };

                FlowMap.Add(thread, flow);

                if (Remote != null)
                    foreach (var client in Remote.SyncClients)
                        lock(client.NewThreads)
                            client.NewThreads[flow.ThreadID] = new Tuple<string,bool>(flow.Name, flow.IsAlive);
            }

            bool isMethod = (node.ObjType == XObjType.Method);

            if(isMethod)
                node.StillInside++;

            // if the first entry, return here
            if (flow.Pos == -1)
            {
                flow.CreateStackItem(dest, null, Watch.ElapsedTicks, isMethod, ThreadlineEnabled);
                node.EntryPoint++;
                return;
            }

            // if exceeded tracking max return
            if (flow.Pos >= flow.Stack.Length)
                return;

            // set the source, and put the dest in stack
            int source = flow.Stack[flow.Pos].NodeID;

            // if loading a fields the call goes from field -> node
            if (loadField && FieldGetLeftToRight)
            {
                int temp = source;
                source = dest;
                dest = temp;
            }

            int hash = PairHash(source, dest);

            FunctionCall call;
            if (!CallMap.TryGetValue(hash, out call))
                call = CreateNewCall(hash, source, node);

            if (source != call.Source || dest != call.Destination)
                LogError("Call mismatch  {0}->{1} != {2}->{3}\r\n", source, dest, call.Source, call.Destination);

            call.Hit = ShowTicks;
            call.TotalHits++;
            call.LastParameters = parameters;

            if (!call.ThreadIDs.Contains(thread))
            {
                call.ThreadIDs.Add(thread);

                if (Remote != null)
                    foreach (var client in Remote.SyncClients)
                        lock(client.CallThreads)
                            client.CallThreads.Add(new Tuple<int, int>(call.ID, thread));
            }

            if (Remote != null)
                foreach (var sync in Remote.SyncClients)
                    lock(sync.CallHits)
                        sync.CallHits.Add(hash);

            // if a method
            if (isMethod)
                call.StillInside++;

            flow.CreateStackItem(dest, call, Watch.ElapsedTicks, isMethod, ThreadlineEnabled);

            if(ClassTracking)
                TrackClassCall(call, thread);
        }
        private bool AddToTimeline(ThreadFlow flow, StackItem item)
        {
            // do stuff with item
            Threadline timeline;
            if (!Threadlines.TryGetValue(flow.ThreadID, out timeline))
            {
                timeline = new Threadline(flow, ThreadOrder++);
                Threadlines[flow.ThreadID] = timeline;
            }

            timeline.IsAlive = flow.IsAlive; // update

            var node = NodeModels[item.NodeID];

            if (node.Show &&
                (CenterMap.Contains(node.ID) ||
                 (ShowOutside && !node.XNode.External) ||
                 (ShowExternal && node.XNode.External)))
            {
                timeline.Sequence.Add(item);

                if (item.Depth > timeline.Deepest)
                    timeline.Deepest = item.Depth;

                timeline.DepthSet.Add(item.Depth);

                return true;
            }
            else
                return false;
        }