Пример #1
0
 public UpdateThunk(TangleKey key, ref T value, DecisionUpdateCallback <T> callback)
 {
     Key              = key;
     Value            = value;
     Callback         = null;
     DecisionCallback = callback;
 }
Пример #2
0
 public BatchItem(TangleKey key, ref T value, DecisionUpdateCallback <T> callback)
 {
     Key              = key;
     Value            = value;
     AllowReplacement = false;
     Callback         = null;
     DecisionCallback = callback;
 }
Пример #3
0
 public BatchItem(TangleKey key, ref T value, bool allowReplacement)
 {
     Key              = key;
     Value            = value;
     AllowReplacement = allowReplacement;
     Callback         = null;
     DecisionCallback = null;
 }
Пример #4
0
        public void AddOrUpdate(TangleKey key, ref T value, DecisionUpdateCallback <T> updateCallback)
        {
            if (_Count >= Capacity)
            {
                throw new IndexOutOfRangeException();
            }

            Buffer[_Count++] = new BatchItem <T>(key, ref value, updateCallback);
        }
Пример #5
0
            protected override void OnExecute(Tangle <T> tangle, out int result)
            {
                result = 0;

                var items = Batch.Buffer;

                for (int i = 0, c = Batch.Count; i < c; i++)
                {
                    ShouldReplace    = items[i].AllowReplacement;
                    Callback         = items[i].Callback;
                    DecisionCallback = items[i].DecisionCallback;
                    if (tangle.InternalSet(items[i].Key, ref items[i].Value, this))
                    {
                        result += 1;
                    }
                }
            }
Пример #6
0
        public IEnumerator <object> SaveToDatabase(DatabaseFile db)
        {
            SavedToDatabase = true;

            yield return(db.Snapshots.Set(Index, this.Info));

            {
                var batch = db.Modules.CreateBatch(Modules.Count);

                foreach (var module in Modules)
                {
                    batch.Add(module.Filename, module);
                }

                yield return(batch.Execute());
            }

            yield return(db.SnapshotModules.Set(Index, Modules.Keys.ToArray()));

            {
                var tracebackBatch = db.Tracebacks.CreateBatch(Tracebacks.Count);

                foreach (var traceback in Tracebacks)
                {
                    tracebackBatch.Add(traceback.ID, traceback);
                }

                yield return(tracebackBatch.Execute());
            }

            UInt16 uIndex = (UInt16)Index;

            HashSet <UInt32> addressSet;

            DecisionUpdateCallback <AllocationRanges> rangeUpdater =
                (ref AllocationRanges oldValue, ref AllocationRanges newValue) => {
                var r = newValue.Ranges.Array[newValue.Ranges.Offset];
                newValue = oldValue.Update(r.First, r.TracebackID, r.Size, r.Overhead);
                return(true);
            };

            foreach (var heap in Heaps)
            {
                var fAddressSet = db.HeapAllocations.Get(heap.ID);
                yield return(fAddressSet);

                if (fAddressSet.Failed)
                {
                    addressSet = new HashSet <UInt32>();
                }
                else
                {
                    addressSet = new HashSet <UInt32>(fAddressSet.Result);
                }

                var batch = db.Allocations.CreateBatch(heap.Allocations.Count);

                foreach (var allocation in heap.Allocations)
                {
                    batch.AddOrUpdate(
                        allocation.Address, AllocationRanges.New(
                            uIndex, allocation.TracebackID, allocation.Size, allocation.Overhead
                            ), rangeUpdater
                        );

                    addressSet.Add(allocation.Address);
                }

                yield return(batch.Execute());

                yield return(db.HeapAllocations.Set(heap.ID, addressSet.ToArray()));
            }

            yield return(db.SnapshotHeaps.Set(Index, (from heap in Heaps select heap.Info).ToArray()));
        }
Пример #7
0
 public void AddOrUpdate(TangleKey key, T value, DecisionUpdateCallback <T> updateCallback)
 {
     AddOrUpdate(key, ref value, updateCallback);
 }
Пример #8
0
 /// <summary>
 /// Stores a value into the tangle, assigning it a given key. If the given key already has an associated value, a callback is invoked to determine the new value for the key.
 /// </summary>
 /// <returns>A future that completes once the value has been stored to disk.</returns>
 public Future <bool> AddOrUpdate(TangleKey key, T value, DecisionUpdateCallback <T> updateCallback)
 {
     return(QueueWorkItem(new UpdateThunk(key, ref value, updateCallback)));
 }
Пример #9
0
        protected IEnumerator <object> SymbolResolverTask()
        {
            var batch        = new List <PendingSymbolResolve>();
            var nullProgress = new CallbackProgressListener();

            ActivityIndicator.CountedItem progress = null;

            while (true)
            {
                var count = SymbolResolveBatchSize - batch.Count;
                SymbolResolveQueue.DequeueMultiple(batch, count);

                if (batch.Count == 0)
                {
                    if (progress != null)
                    {
                        progress.Decrement();
                        progress = null;
                    }

                    if (!SymbolResolveState.Progress.Active && (SymbolResolveQueue.Count <= 0))
                    {
                        SymbolResolveState.Count = 0;
                    }

                    var f = SymbolResolveQueue.Dequeue();
                    using (f)
                        yield return(f);

                    batch.Add(f.Result);
                }
                else
                {
                    if (progress == null)
                    {
                        progress = SymbolResolveState.Progress.Increment();
                    }

                    var maximum = SymbolResolveState.Count + Math.Max(0, SymbolResolveQueue.Count) + 1;
                    progress.Maximum  = maximum;
                    progress.Progress = Math.Min(maximum, SymbolResolveState.Count);

                    string infile = Path.GetTempFileName(), outfile = Path.GetTempFileName();

                    var padNumberRight = (Func <uint, int, string>)((num, length) => {
                        var result = String.Format("{0:X}", num);
                        if (result.Length < length)
                        {
                            result = new String(' ', length - result.Length) + result;
                        }

                        return(result);
                    });

                    var symbolModules = SymbolModules.ToArray();
                    yield return(Future.RunInThread(() => {
                        using (var sw = new StreamWriter(infile, false, Encoding.ASCII)) {
                            sw.WriteLine("// Loaded modules:");
                            sw.WriteLine("//     Base Size Module");

                            foreach (var module in symbolModules)
                            {
                                sw.WriteLine(
                                    "//            {0} {1} {2}",
                                    padNumberRight(module.BaseAddress, 8),
                                    padNumberRight(module.Size, 8),
                                    Path.GetFullPath(module.Filename)
                                    );
                            }

                            sw.WriteLine("//");
                            sw.WriteLine("// Process modules enumerated.");

                            sw.WriteLine();
                            sw.WriteLine("*- - - - - - - - - - Heap 0 Hogs - - - - - - - - - -");
                            sw.WriteLine();

                            for (int i = 0; i < batch.Count; i++)
                            {
                                sw.WriteLine(
                                    "{0:X8} bytes + {1:X8} at {2:X8} by BackTrace{3:X8}",
                                    1, 0, i + 1, i + 1
                                    );

                                sw.WriteLine("\t{0:X8}", batch[i].Frame);
                                sw.WriteLine();
                            }
                        }
                    }));

                    var psi = new ProcessStartInfo(
                        Settings.UmdhPath, String.Format(
                            "\"{0}\" -f:\"{1}\"", infile, outfile
                            )
                        );

                    using (var rp = Scheduler.Start(
                               Program.RunProcess(psi, ProcessPriorityClass.Idle),
                               TaskExecutionPolicy.RunAsBackgroundTask
                               ))
                        yield return(rp);

                    using (Finally.Do(() => {
                        try {
                            File.Delete(infile);
                        } catch {
                        }
                        try {
                            File.Delete(outfile);
                        } catch {
                        }
                    })) {
                        var rtc = new RunToCompletion <HeapDiff>(
                            HeapDiff.FromFile(outfile, nullProgress)
                            );

                        using (rtc)
                            yield return(rtc);

                        var fProcess = Future.RunInThread(() => {
                            var cacheBatch = Database.SymbolCache.CreateBatch(batch.Count);

                            DecisionUpdateCallback <HashSet <UInt32> > updateCallback = (ref HashSet <UInt32> oldValue, ref HashSet <UInt32> newValue) => {
                                newValue.UnionWith(oldValue);
                                return(true);
                            };

                            foreach (var traceback in rtc.Result.Tracebacks)
                            {
                                var index = (int)(traceback.Key) - 1;

                                var key   = batch[index].Frame;
                                var frame = traceback.Value.Frames.Array[traceback.Value.Frames.Offset];
                                batch[index].Result.Complete(frame);

                                lock (SymbolResolveLock) {
                                    ResolvedSymbolCache[key] = frame;
                                    PendingSymbolResolves.Remove(key);
                                }

                                cacheBatch.Add(key, frame);
                                if (frame.Function != null)
                                {
                                    var tempHash = new HashSet <uint>();
                                    tempHash.Add(key);
                                }
                            }

                            foreach (var frame in batch)
                            {
                                if (frame.Result.Completed)
                                {
                                    continue;
                                }

                                Interlocked.Increment(ref TotalFrameResolveFailures);

                                var tf = new TracebackFrame(frame.Frame);

                                frame.Result.Complete(tf);

                                lock (SymbolResolveLock) {
                                    ResolvedSymbolCache[frame.Frame] = tf;
                                    PendingSymbolResolves.Remove(frame.Frame);
                                }

                                cacheBatch.Add(frame.Frame, tf);

                                // Console.WriteLine("Could not resolve: {0:X8}", frame.Frame);
                            }

                            return(new IBatch[] { cacheBatch });
                        });

                        yield return(fProcess);

                        foreach (var manglerBatch in fProcess.Result)
                        {
                            yield return(manglerBatch.Execute());
                        }

                        Interlocked.Add(ref SymbolResolveState.Count, batch.Count);
                        batch.Clear();
                    }
                }
            }
        }