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); }
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; }