コード例 #1
0
ファイル: PipHistoricPerfData.cs プロジェクト: uilit/BuildXL
 private static ProcessMemoryCounters Merge(ProcessMemoryCounters oldData, ProcessMemoryCounters newData)
 {
     return(ProcessMemoryCounters.CreateFromMb(
                (int)GetMergeResult((uint)oldData.PeakVirtualMemoryUsageMb, (uint)newData.PeakVirtualMemoryUsageMb),
                (int)GetMergeResult((uint)oldData.PeakWorkingSetMb, (uint)newData.PeakWorkingSetMb),
                (int)GetMergeResult((uint)oldData.PeakCommitUsageMb, (uint)newData.PeakCommitUsageMb)));
 }
コード例 #2
0
ファイル: Worker.cs プロジェクト: rustedwizard/BuildXL
        /// <summary>
        /// Gets the estimated memory counters for the process
        /// </summary>
        public ProcessMemoryCounters GetExpectedMemoryCounters(ProcessRunnablePip runnableProcess)
        {
            if (TotalRamMb == null || TotalCommitMb == null)
            {
                return(ProcessMemoryCounters.CreateFromMb(0, 0, 0, 0));
            }

            if (runnableProcess.ExpectedMemoryCounters.HasValue)
            {
                // If there is already an expected memory counters for the process,
                // it means that we retry the process with another worker due to
                // several reasons including stopped worker, memory exhaustion.
                // That's why, we should reuse the expected memory counters that
                // are updated with recent data from last execution.
                return(runnableProcess.ExpectedMemoryCounters.Value);
            }

            // If there is a historic perf data, use it.
            if (runnableProcess.HistoricPerfData != null)
            {
                return(runnableProcess.HistoricPerfData.Value.MemoryCounters);
            }

            // If there is no historic perf data, use the defaults for the worker.
            return(ProcessMemoryCounters.CreateFromMb(
                       peakWorkingSetMb: DefaultWorkingSetMbPerProcess,
                       averageWorkingSetMb: DefaultWorkingSetMbPerProcess,
                       peakCommitSizeMb: DefaultCommitSizeMbPerProcess,
                       averageCommitSizeMb: DefaultCommitSizeMbPerProcess));
        }
コード例 #3
0
        /// <summary>
        /// Gets the estimated memory counters for the process
        /// </summary>
        public ProcessMemoryCounters GetExpectedMemoryCounters(ProcessRunnablePip runnableProcess, bool isCancelledDueToResourceExhaustion = false)
        {
            if (TotalRamMb == null || TotalCommitMb == null)
            {
                return(ProcessMemoryCounters.CreateFromMb(0, 0, 0));
            }

            if (runnableProcess.ExpectedMemoryCounters == null)
            {
                return(ProcessMemoryCounters.CreateFromMb(
                           peakVirtualMemoryUsageMb: DefaultMemoryUsageMbPerProcess,
                           peakWorkingSetMb: DefaultMemoryUsageMbPerProcess,
                           peakCommitUsageMb: DefaultCommitUsageMbPerProcess));
            }

            var expectedMemoryCounters = runnableProcess.ExpectedMemoryCounters.Value;

            // If the process is cancelled due to resource exhaustion, multiply the memory usage by 1.25; otherwise use the historic memory.
            double multiplier = isCancelledDueToResourceExhaustion ? 1.25 : 1;

            return(ProcessMemoryCounters.CreateFromMb(
                       peakVirtualMemoryUsageMb: (int)(expectedMemoryCounters.PeakVirtualMemoryUsageMb * multiplier),
                       peakWorkingSetMb: (int)(expectedMemoryCounters.PeakWorkingSetMb * multiplier),
                       peakCommitUsageMb: (int)(expectedMemoryCounters.PeakCommitUsageMb * multiplier)));
        }
コード例 #4
0
 private ProcessPipHistoricPerfData(byte timeToLive, uint durationInMs, ProcessMemoryCounters memoryCounters, ushort processorsInPercents, uint diskIOInKB)
 {
     m_entryTimeToLive    = timeToLive;
     DurationInMs         = durationInMs;
     MemoryCounters       = memoryCounters;
     ProcessorsInPercents = processorsInPercents;
     DiskIOInKB           = diskIOInKB;
 }
コード例 #5
0
        public void EverythingAsync()
        {
            const int MaxExecTime = 24 * 3600 * 1000;

            var stream = new MemoryStream();
            var r      = new Random(0);

            for (int i = 0; i < 10; i++)
            {
                int seed = r.Next(100 * 1000);
                HistoricPerfDataTable table = new HistoricPerfDataTable(LoggingContext);
                XAssert.IsTrue(table.Count == 0);

                var s      = new Random(seed);
                var buffer = new byte[sizeof(long)];
                for (int j = 0; j < 10; j++)
                {
                    s.NextBytes(buffer);
                    long semiStableHash = BitConverter.ToInt64(buffer, 0);

                    var execTime = (uint)s.Next(MaxExecTime);
                    var processPipExecutionPerformance = new ProcessPipExecutionPerformance(
                        PipExecutionLevel.Executed,
                        DateTime.UtcNow,
                        DateTime.UtcNow.AddMilliseconds(execTime),
                        FingerprintUtilities.ZeroFingerprint,
                        TimeSpan.FromMilliseconds(execTime),
                        default(FileMonitoringViolationCounters),
                        default(IOCounters),
                        TimeSpan.FromMilliseconds(execTime),
                        TimeSpan.FromMilliseconds(execTime / 2),
                        ProcessMemoryCounters.CreateFromMb(1024, 1024, 1024, 1024),
                        1,
                        workerId: 0,
                        suspendedDurationMs: 0);

                    ProcessPipHistoricPerfData runTimeData = new ProcessPipHistoricPerfData(processPipExecutionPerformance, execTime);
                    table[semiStableHash] = runTimeData;
                }

                XAssert.IsTrue(table.Count == 10);

                stream.Position = 0;
                table.Save(stream);
                stream.Position = 0;
                table           = HistoricPerfDataTable.Load(LoggingContext, stream);
                XAssert.IsTrue(table.Count == 10);

                s = new Random(seed);
                for (int j = 0; j < 10; j++)
                {
                    s.NextBytes(buffer);
                    long semiStableHash = BitConverter.ToInt64(buffer, 0);
                    XAssert.IsTrue(table[semiStableHash].ExeDurationInMs >= (uint)s.Next(MaxExecTime));
                }
            }
        }
コード例 #6
0
 private ProcessPipHistoricPerfData(byte timeToLive, uint exeDurationInMs, uint maxExeDurationInMs, uint runDurationInMs, ProcessMemoryCounters memoryCounters, ushort processorsInPercents, uint diskIOInMB)
 {
     m_entryTimeToLive    = timeToLive;
     ExeDurationInMs      = exeDurationInMs;
     MaxExeDurationInMs   = maxExeDurationInMs;
     RunDurationInMs      = runDurationInMs;
     MemoryCounters       = memoryCounters;
     ProcessorsInPercents = processorsInPercents;
     DiskIOInMB           = diskIOInMB;
 }
コード例 #7
0
        private static ulong GetWorkingSetSize(IntPtr processHandle)
        {
            // ReSharper disable once InlineOutVariableDeclaration
            var memoryCounters = new ProcessMemoryCounters()
            {
                Cb = (uint)Marshal.SizeOf(typeof(ProcessMemoryCounters))
            };

            return(GetProcessMemoryInfo(processHandle, out memoryCounters, memoryCounters.Cb) ? memoryCounters.WorkingSetSize : 0);
        }
コード例 #8
0
        private static ulong GetWorkingSetSize(IntPtr processHandle)
        {
            var memoryCounters = new ProcessMemoryCounters {
                Cb = (uint)Marshal.SizeOf <ProcessMemoryCounters>()
            };

            return(GetProcessMemoryInfo(processHandle, out memoryCounters, memoryCounters.Cb)
                ? memoryCounters.WorkingSetSize
                : 0);
        }
コード例 #9
0
ファイル: PipHistoricPerfData.cs プロジェクト: uilit/BuildXL
        /// <summary>
        /// Construct a new runtime data based on collected performance data
        /// </summary>
        public PipHistoricPerfData(ProcessPipExecutionPerformance executionPerformance)
        {
            Contract.Requires(executionPerformance.ExecutionLevel == PipExecutionLevel.Executed);

            m_entryTimeToLive = DefaultTimeToLive;
            DurationInMs      = (uint)Math.Min(uint.MaxValue, Math.Max(1, executionPerformance.ProcessExecutionTime.TotalMilliseconds));
            // For historical ram usage, we record the peak working set instead of the virtual memory due to the precision.
            MemoryCounters       = executionPerformance.MemoryCounters;
            DiskIOInKB           = (uint)Math.Min(uint.MaxValue, executionPerformance.IO.GetAggregateIO().TransferCount / 1024);
            ProcessorsInPercents = executionPerformance.ProcessorsInPercents;
        }
コード例 #10
0
ファイル: Process.cs プロジェクト: yang-er/joj-win32
        public long GetPeakMemory()
        {
            var pmc = new ProcessMemoryCounters();

            pmc.cb = Marshal.SizeOf <ProcessMemoryCounters>();
            if (!Psapi.GetProcessMemoryInfo(proc, ref pmc, pmc.cb))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            return((long)pmc.PeakWorkingSetSize);
        }
コード例 #11
0
        // <inheritdoc />
        internal override JobObject.AccountingInformation GetJobAccountingInfo()
        {
            if (m_processResourceUsage is null)
            {
                return(base.GetJobAccountingInfo());
            }
            else
            {
                IOCounters            ioCounters;
                ProcessMemoryCounters memoryCounters;
                uint childProcesses = 0;

                try
                {
                    ioCounters = new IOCounters(new IO_COUNTERS()
                    {
                        ReadOperationCount  = m_processResourceUsage.Aggregate(0UL, (acc, usage) => acc + usage.Value.DiskReadOps),
                        ReadTransferCount   = m_processResourceUsage.Aggregate(0UL, (acc, usage) => acc + usage.Value.DiskBytesRead),
                        WriteOperationCount = m_processResourceUsage.Aggregate(0UL, (acc, usage) => acc + usage.Value.DiskWriteOps),
                        WriteTransferCount  = m_processResourceUsage.Aggregate(0UL, (acc, usage) => acc + usage.Value.DiskBytesWritten),
                    });

                    memoryCounters = ProcessMemoryCounters.CreateFromBytes(
                        m_processResourceUsage.Aggregate(0UL, (acc, usage) => acc + usage.Value.PeakWorkingSetSize),
                        m_processResourceUsage.Aggregate(0UL, (acc, usage) => acc + usage.Value.WorkingSetSize),
                        0, 0);

                    childProcesses = m_processResourceUsage.Keys.Count > 0 ? (uint)(m_processResourceUsage.Keys.Count - 1) : 0; // Exclude the root process from the child count
                }
                catch (OverflowException ex)
                {
                    LogProcessState($"Overflow exception caught while calculating AccountingInformation:{Environment.NewLine}{ex.ToString()}");

                    ioCounters = new IOCounters(new IO_COUNTERS()
                    {
                        ReadOperationCount  = 0,
                        WriteOperationCount = 0,
                        ReadTransferCount   = 0,
                        WriteTransferCount  = 0
                    });

                    memoryCounters = ProcessMemoryCounters.CreateFromBytes(0, 0, 0, 0);
                }

                return(new JobObject.AccountingInformation
                {
                    IO = ioCounters,
                    MemoryCounters = memoryCounters,
                    KernelTime = TimeSpan.FromMilliseconds(m_processResourceUsage.Aggregate(0.0, (acc, usage) => acc + usage.Value.SystemTimeNs) / NanosecondsToMillisecondsFactor),
                    UserTime = TimeSpan.FromMilliseconds(m_processResourceUsage.Aggregate(0.0, (acc, usage) => acc + usage.Value.UserTimeNs) / NanosecondsToMillisecondsFactor),
                    NumberOfProcesses = childProcesses,
                });
            }
        }
コード例 #12
0
ファイル: JobObject.cs プロジェクト: erikma/BuildXL
 /// <nodoc />
 public static AccountingInformation Deserialize(BuildXLReader reader)
 {
     return(new AccountingInformation()
     {
         IO = IOCounters.Deserialize(reader),
         UserTime = reader.ReadTimeSpan(),
         KernelTime = reader.ReadTimeSpan(),
         MemoryCounters = ProcessMemoryCounters.Deserialize(reader),
         NumberOfProcesses = reader.ReadUInt32()
     });
 }
コード例 #13
0
        private ResourceScope AcquireResourceScope(Process processPip, ProcessMemoryCounters expectedMemoryCounters, bool allowCancellation)
        {
            Interlocked.Increment(ref m_activeExecutionCount);

            lock (m_syncLock)
            {
                var scope = new ResourceScope(this, processPip, m_nextScopeId++, expectedMemoryCounters, allowCancellation, m_headScope);
                m_headScope = scope;
                m_pipResourceScopes[processPip.PipId] = scope;
                return(scope);
            }
        }
コード例 #14
0
        /// <summary>
        /// Construct a new runtime data based on collected performance data
        /// </summary>
        public ProcessPipHistoricPerfData(ProcessPipExecutionPerformance executionPerformance)
        {
            Contract.Requires(executionPerformance.ExecutionLevel == PipExecutionLevel.Executed);

            m_entryTimeToLive = DefaultTimeToLive;
            // Deduct the suspended duration from the process execution time.
            DurationInMs = (uint)Math.Min(uint.MaxValue, Math.Max(1, executionPerformance.ProcessExecutionTime.TotalMilliseconds - executionPerformance.SuspendedDurationMs));
            // For historical ram usage, we record the peak working set instead of the virtual memory due to the precision.
            MemoryCounters       = executionPerformance.MemoryCounters;
            DiskIOInMB           = (uint)Math.Min(uint.MaxValue, ByteSizeFormatter.ToMegabytes(executionPerformance.IO.GetAggregateIO().TransferCount));
            ProcessorsInPercents = executionPerformance.ProcessorsInPercents;
        }
コード例 #15
0
 public ResourceScope(ProcessResourceManager resourceManager, PipId pipId, int scopeId, ProcessMemoryCounters expectedMemoryCounters, bool allowCancellation, ResourceScope next)
 {
     m_resourceManager      = resourceManager;
     PipId                  = pipId;
     ScopeId                = scopeId;
     ExpectedMemoryCounters = expectedMemoryCounters;
     m_allowCancellation    = allowCancellation;
     Next = next;
     if (next != null)
     {
         next.Prior = this;
     }
 }
コード例 #16
0
        public static bool Deserialize(BuildXLReader reader, out ProcessPipHistoricPerfData result)
        {
            Contract.Requires(reader != null);
            byte timeToLive    = reader.ReadByte();
            byte newTimeToLive = (byte)(timeToLive - 1);

            result = new ProcessPipHistoricPerfData(
                newTimeToLive,
                reader.ReadUInt32(),
                ProcessMemoryCounters.Deserialize(reader),
                reader.ReadUInt16(),
                reader.ReadUInt32());
            return(newTimeToLive > 0);
        }
コード例 #17
0
        public void TimeToLive()
        {
            int  execTime = 1;
            uint runTime  = 2;
            var  processPipExecutionPerformance = new ProcessPipExecutionPerformance(
                PipExecutionLevel.Executed,
                DateTime.UtcNow,
                DateTime.UtcNow.AddMilliseconds(execTime),
                FingerprintUtilities.ZeroFingerprint,
                TimeSpan.FromMilliseconds(execTime),
                default(FileMonitoringViolationCounters),
                default(IOCounters),
                TimeSpan.FromMilliseconds(execTime),
                TimeSpan.FromMilliseconds(execTime / 2),
                ProcessMemoryCounters.CreateFromMb(1024, 1024, 1024, 1024),
                1,
                workerId: 0,
                suspendedDurationMs: 0);

            ProcessPipHistoricPerfData runTimeData = new ProcessPipHistoricPerfData(processPipExecutionPerformance, runTime);
            HistoricPerfDataTable      table       = new HistoricPerfDataTable(LoggingContext);
            var semiStableHashToKeep = 0;

            table[semiStableHashToKeep] = runTimeData;
            var semiStableHashToDrop = 1;

            table[semiStableHashToDrop] = runTimeData;
            var stream = new MemoryStream();

            for (int i = 0; i < ProcessPipHistoricPerfData.DefaultTimeToLive; i++)
            {
                stream.Position = 0;
                table.Save(stream);
                stream.Position = 0;
                table           = HistoricPerfDataTable.Load(LoggingContext, stream);
                Analysis.IgnoreResult(table[semiStableHashToKeep]);
            }

            stream.Position = 0;
            table           = HistoricPerfDataTable.Load(LoggingContext, stream);
            XAssert.AreEqual(1u, table[semiStableHashToKeep].ExeDurationInMs);
            XAssert.AreEqual(0u, table[semiStableHashToDrop].ExeDurationInMs);
        }
コード例 #18
0
        public void PipHistoricPerfDataConstructorDoesntCrash()
        {
            foreach (var obj in ConstructorDoesntCrashTestData())
            {
                var executionStart         = (DateTime)obj[0];
                var executionStop          = (DateTime)obj[1];
                var processExecutionTime   = (TimeSpan)obj[2];
                var fileMonitoringWarnings = (int)obj[3];
                var ioCounters             = (IOCounters)obj[4];
                var userTime          = (TimeSpan)obj[5];
                var kernelTime        = (TimeSpan)obj[6];
                var peakMemoryUsage   = (ulong)obj[7];
                var numberOfProcesses = (uint)obj[8];
                var workerId          = (uint)obj[9];

                if (executionStart > executionStop)
                {
                    continue;
                }

                var performance = new ProcessPipExecutionPerformance(
                    PipExecutionLevel.Executed,
                    executionStart,
                    executionStop,
                    FingerprintUtilities.ZeroFingerprint,
                    processExecutionTime,
                    new FileMonitoringViolationCounters(fileMonitoringWarnings, fileMonitoringWarnings, fileMonitoringWarnings),
                    ioCounters,
                    userTime,
                    kernelTime,
                    ProcessMemoryCounters.CreateFromBytes(peakMemoryUsage, peakMemoryUsage, peakMemoryUsage, peakMemoryUsage),
                    numberOfProcesses,
                    workerId,
                    0);
                var data = new ProcessPipHistoricPerfData(performance, (long)processExecutionTime.TotalMilliseconds);
                data = data.Merge(data);
                Analysis.IgnoreResult(data);
            }
        }
コード例 #19
0
ファイル: WorkerService.cs プロジェクト: erikma/BuildXL
        private void StartStep(RunnablePip runnablePip, PipExecutionStep step)
        {
            var pipId           = runnablePip.PipId;
            var processRunnable = runnablePip as ProcessRunnablePip;

            Tracing.Logger.Log.DistributionWorkerExecutePipRequest(
                runnablePip.LoggingContext,
                runnablePip.Pip.SemiStableHash,
                runnablePip.Description,
                runnablePip.Step.AsString());

            var completionData = m_pendingPipCompletions[pipId];

            completionData.StepExecutionStarted.SetResult(true);

            switch (step)
            {
            case PipExecutionStep.ExecuteProcess:
                if (runnablePip.PipType == PipType.Process)
                {
                    SinglePipBuildRequest pipBuildRequest;
                    bool found = m_pendingBuildRequests.TryGetValue(pipId, out pipBuildRequest);
                    Contract.Assert(found, "Could not find corresponding build request for executed pip on worker");
                    m_pendingBuildRequests[pipId] = null;

                    // Set the cache miss result with fingerprint so ExecuteProcess step can use it
                    var fingerprint = pipBuildRequest.Fingerprint.ToFingerprint();
                    processRunnable.SetCacheResult(RunnableFromCacheResult.CreateForMiss(new WeakContentFingerprint(fingerprint)));

                    processRunnable.ExpectedMemoryCounters = ProcessMemoryCounters.CreateFromMb(
                        peakWorkingSetMb: pipBuildRequest.ExpectedPeakWorkingSetMb,
                        averageWorkingSetMb: pipBuildRequest.ExpectedAverageWorkingSetMb,
                        peakCommitSizeMb: pipBuildRequest.ExpectedPeakCommitSizeMb,
                        averageCommitSizeMb: pipBuildRequest.ExpectedAverageCommitSizeMb);
                }

                break;
            }
        }
コード例 #20
0
        /// <summary>
        /// Attempts to execute the given function for the pip after acquiring the resources to run the pip and
        /// provides cancellation when resources are limited
        /// </summary>
        public async Task <T> ExecuteWithResources <T>(
            OperationContext operationContext,
            PipId pipId,
            ProcessMemoryCounters expectedMemoryCounters,
            bool allowCancellation,
            ManagedResourceExecute <T> execute)
        {
            ResourceScope scope;

            using (operationContext.StartOperation(PipExecutorCounter.AcquireResourcesDuration))
            {
                scope = AcquireResourceScope(pipId, expectedMemoryCounters, allowCancellation);
            }

            using (scope)
            {
                var result = await execute(scope.Token, registerQueryRamUsageMb : scope.RegisterQueryRamUsageMb);

                scope.Complete();
                return(result);
            }
        }
コード例 #21
0
        /// <summary>
        /// Attempts to execute the given function for the pip after acquiring the resources to run the pip and
        /// provides cancellation when resources are limited
        /// </summary>
        public async Task <T> ExecuteWithResourcesAsync <T>(
            OperationContext operationContext,
            Process processPip,
            ProcessMemoryCounters expectedMemoryCounters,
            bool allowCancellation,
            ManagedResourceExecute <T> execute)
        {
            ResourceScope scope;

            using (operationContext.StartOperation(PipExecutorCounter.AcquireResourcesDuration))
            {
                scope = AcquireResourceScope(processPip, expectedMemoryCounters, allowCancellation);
            }

            using (scope)
            {
                var result = await execute(scope);

                scope.Complete();
                return(result);
            }
        }
コード例 #22
0
            public ResourceManagerWorkItemTracker(LoggingContext loggingContext, ProcessResourceManager resourceManager, uint id, int estimatedRamUsage, bool allowCancellation)
            {
                ExecutionCompletionSource      = TaskSourceSlim.Create <int>();
                m_cancellationCompletionSource = TaskSourceSlim.Create <Unit>();
                var context = BuildXLContext.CreateInstanceForTesting();

                m_execute = () => ExecutionTask = resourceManager.ExecuteWithResourcesAsync(
                    OperationContext.CreateUntracked(loggingContext),
                    SchedulerTest.CreateDummyProcess(context, new PipId(id)),
                    ProcessMemoryCounters.CreateFromMb(estimatedRamUsage, estimatedRamUsage, estimatedRamUsage, estimatedRamUsage),
                    allowCancellation,
                    async(resourceScope) =>
                {
                    m_startSemaphore.Release();
                    resourceScope.RegisterQueryRamUsageMb(() => RamUsage);

                    ExecutionCount++;
                    var currrentCancellationCompletionSource = m_cancellationCompletionSource;
                    resourceScope.Token.Register(() =>
                    {
                        XAssert.IsTrue(m_startSemaphore.Wait(millisecondsTimeout: 100000));

                        CancellationCount++;
                        m_cancellationCompletionSource = TaskSourceSlim.Create <Unit>();
                        currrentCancellationCompletionSource.TrySetResult(Unit.Void);
                    });

                    var result = await Task.WhenAny(currrentCancellationCompletionSource.Task, ExecutionCompletionSource.Task);

                    resourceScope.Token.ThrowIfCancellationRequested();

                    XAssert.IsTrue(ExecutionCompletionSource.Task.IsCompleted, "This task should be completed since the cancellation task implies the cancellation token would throw in the preceding line of code.");

                    return(ExecutionCompletionSource.Task.Result);
                });

                StartExecute();
            }
コード例 #23
0
ファイル: Worker.cs プロジェクト: rijulluman-msft/BuildXL
        /// <summary>
        /// Gets the estimated memory counters for the process
        /// </summary>
        public ProcessMemoryCounters GetExpectedMemoryCounters(ProcessRunnablePip runnableProcess)
        {
            if (TotalRamMb == null || TotalCommitMb == null)
            {
                return(ProcessMemoryCounters.CreateFromMb(0, 0, 0));
            }

            if (runnableProcess.ExpectedMemoryCounters == null)
            {
                return(ProcessMemoryCounters.CreateFromMb(
                           peakVirtualMemoryUsageMb: DefaultMemoryUsageMbPerProcess,
                           peakWorkingSetMb: DefaultMemoryUsageMbPerProcess,
                           peakCommitUsageMb: DefaultCommitUsageMbPerProcess));
            }

            var expectedMemoryCounters = runnableProcess.ExpectedMemoryCounters.Value;

            // 5% more to give some slack
            return(ProcessMemoryCounters.CreateFromMb(
                       peakVirtualMemoryUsageMb: (int)(expectedMemoryCounters.PeakVirtualMemoryUsageMb * 1.05),
                       peakWorkingSetMb: (int)(expectedMemoryCounters.PeakWorkingSetMb * 1.05),
                       peakCommitUsageMb: (int)(expectedMemoryCounters.PeakCommitUsageMb * 1.05)));
        }
コード例 #24
0
        public static bool Deserialize(BuildXLReader reader, out ProcessPipHistoricPerfData result)
        {
            Contract.Requires(reader != null);
            byte timeToLive       = reader.ReadByte();
            byte newTimeToLive    = (byte)(timeToLive - 1);
            uint exeDurationMs    = reader.ReadUInt32();
            uint maxExeDurationMs = reader.ReadUInt32();
            uint runDurationMs    = reader.ReadUInt32();
            ProcessMemoryCounters memoryCounters = ProcessMemoryCounters.Deserialize(reader);
            ushort processorsInPercents          = reader.ReadUInt16();
            uint   diskIOInMB = reader.ReadUInt32();

            result = new ProcessPipHistoricPerfData(
                newTimeToLive,
                exeDurationMs,
                maxExeDurationMs,
                runDurationMs,
                memoryCounters,
                processorsInPercents,
                diskIOInMB);

            return(newTimeToLive > 0);
        }
コード例 #25
0
        public void TestProcessExecutionResultSerialization()
        {
            var reportedAccess = CreateRandomReportedFileAccess();

            Fingerprint fingerprint = FingerprintUtilities.CreateRandom();

            var processExecutionResult = ExecutionResult.CreateSealed(
                result: PipResultStatus.Succeeded,
                numberOfWarnings: 12,
                outputContent: ReadOnlyArray <(FileArtifact, FileMaterializationInfo, PipOutputOrigin)> .FromWithoutCopy(CreateRandomOutputContent(), CreateRandomOutputContent()),
                directoryOutputs: ReadOnlyArray <(DirectoryArtifact, ReadOnlyArray <FileArtifact>)> .FromWithoutCopy(CreateRandomOutputDirectory(), CreateRandomOutputDirectory()),
                performanceInformation: new ProcessPipExecutionPerformance(
                    PipExecutionLevel.Executed,
                    DateTime.UtcNow,
                    DateTime.UtcNow + TimeSpan.FromMinutes(2),
                    FingerprintUtilities.ZeroFingerprint,
                    TimeSpan.FromMinutes(2),
                    new FileMonitoringViolationCounters(2, 3, 4),
                    default(IOCounters),
                    TimeSpan.FromMinutes(3),
                    TimeSpan.FromMinutes(3),
                    ProcessMemoryCounters.CreateFromBytes(12324, 12325, 12326, 12326),
                    33,
                    7,
                    0),
                fingerprint: new WeakContentFingerprint(fingerprint),
                fileAccessViolationsNotAllowlisted: new[]
            {
                reportedAccess,
                CreateRandomReportedFileAccess(),

                // Create reported file access that uses the same process to test deduplication during deserialization
                CreateRandomReportedFileAccess(reportedAccess.Process),
            },
                allowlistedFileAccessViolations: new ReportedFileAccess[0],
                mustBeConsideredPerpetuallyDirty: true,
                dynamicallyObservedFiles: ReadOnlyArray <AbsolutePath> .FromWithoutCopy(
                    CreateSourceFile().Path,
                    CreateSourceFile().Path
                    ),
                dynamicallyProbedFiles: ReadOnlyArray <AbsolutePath> .FromWithoutCopy(
                    CreateSourceFile().Path,
                    CreateSourceFile().Path,
                    CreateSourceFile().Path
                    ),
                dynamicallyObservedEnumerations: ReadOnlyArray <AbsolutePath> .FromWithoutCopy(
                    CreateSourceFile().Path
                    ),
                allowedUndeclaredSourceReads: new ReadOnlyHashSet <AbsolutePath> {
                CreateSourceFile().Path,
                CreateSourceFile().Path
            },
                absentPathProbesUnderOutputDirectories: new ReadOnlyHashSet <AbsolutePath> {
                CreateSourceFile().Path,
                CreateSourceFile().Path
            },
                twoPhaseCachingInfo: new TwoPhaseCachingInfo(
                    new WeakContentFingerprint(Fingerprint.Random(FingerprintUtilities.FingerprintLength)),
                    ContentHashingUtilities.CreateRandom(),
                    new StrongContentFingerprint(Fingerprint.Random(FingerprintUtilities.FingerprintLength)),
                    new CacheEntry(ContentHashingUtilities.CreateRandom(), null, CreateRandomContentHashArray())),
                pipCacheDescriptorV2Metadata: null,
                converged: true,
                pathSet: null,
                cacheLookupStepDurations: null,
                pipProperties: new Dictionary <string, int> {
                { "Foo", 1 }, { "Bar", 9 }
            },
                hasUserRetries: true);

            ExecutionResultSerializer serializer = new ExecutionResultSerializer(0, Context);

            ExecutionResult deserializedProcessExecutionResult;

            using (var stream = new MemoryStream())
                using (var writer = new BuildXLWriter(false, stream, true, false))
                    using (var reader = new BuildXLReader(false, stream, true))
                    {
                        serializer.Serialize(writer, processExecutionResult, preservePathCasing: false);

                        stream.Position = 0;

                        deserializedProcessExecutionResult = serializer.Deserialize(reader,
                                                                                    processExecutionResult.PerformanceInformation.WorkerId);
                    }

            // Ensure successful pip result is changed to not materialized.
            XAssert.AreEqual(PipResultStatus.NotMaterialized, deserializedProcessExecutionResult.Result);

            AssertEqual(processExecutionResult, deserializedProcessExecutionResult,
                        r => r.NumberOfWarnings,
                        r => r.Converged,

                        r => r.OutputContent.Length,
                        r => r.DirectoryOutputs.Length,

                        r => r.PerformanceInformation.ExecutionLevel,
                        r => r.PerformanceInformation.ExecutionStop,
                        r => r.PerformanceInformation.ExecutionStart,
                        r => r.PerformanceInformation.ProcessExecutionTime,
                        r => r.PerformanceInformation.FileMonitoringViolations.NumFileAccessViolationsNotAllowlisted,
                        r => r.PerformanceInformation.FileMonitoringViolations.NumFileAccessesAllowlistedAndCacheable,
                        r => r.PerformanceInformation.FileMonitoringViolations.NumFileAccessesAllowlistedButNotCacheable,
                        r => r.PerformanceInformation.UserTime,
                        r => r.PerformanceInformation.KernelTime,
                        r => r.PerformanceInformation.MemoryCounters.PeakWorkingSetMb,
                        r => r.PerformanceInformation.MemoryCounters.AverageWorkingSetMb,
                        r => r.PerformanceInformation.MemoryCounters.PeakCommitSizeMb,
                        r => r.PerformanceInformation.MemoryCounters.AverageCommitSizeMb,

                        r => r.PerformanceInformation.NumberOfProcesses,

                        r => r.FileAccessViolationsNotAllowlisted.Count,
                        r => r.MustBeConsideredPerpetuallyDirty,
                        r => r.DynamicallyObservedFiles.Length,
                        r => r.DynamicallyProbedFiles.Length,
                        r => r.DynamicallyObservedEnumerations.Length,
                        r => r.AllowedUndeclaredReads.Count,

                        r => r.TwoPhaseCachingInfo.WeakFingerprint,
                        r => r.TwoPhaseCachingInfo.StrongFingerprint,
                        r => r.TwoPhaseCachingInfo.PathSetHash,
                        r => r.TwoPhaseCachingInfo.CacheEntry.MetadataHash,
                        r => r.TwoPhaseCachingInfo.CacheEntry.OriginatingCache,
                        r => r.TwoPhaseCachingInfo.CacheEntry.ReferencedContent.Length,

                        r => r.PipProperties.Count,
                        r => r.HasUserRetries,
                        r => r.RetryInfo
                        );

            for (int i = 0; i < processExecutionResult.OutputContent.Length; i++)
            {
                int j = i;
                AssertEqual(processExecutionResult, deserializedProcessExecutionResult,
                            r => r.OutputContent[j].Item1,
                            r => r.OutputContent[j].Item2
                            );

                // Ensure that output origin from deserialzed output content is changed to not materialized.
                XAssert.AreEqual(PipOutputOrigin.NotMaterialized, deserializedProcessExecutionResult.OutputContent[i].Item3);
            }

            for (int i = 0; i < processExecutionResult.DirectoryOutputs.Length; i++)
            {
                var expected = processExecutionResult.DirectoryOutputs[i];
                var result   = deserializedProcessExecutionResult.DirectoryOutputs[i];
                XAssert.AreEqual(expected.Item1, result.Item1);
                XAssert.AreEqual(expected.Item2.Length, result.Item2.Length);

                for (int j = 0; j < expected.Item2.Length; j++)
                {
                    XAssert.AreEqual(expected.Item2[j], result.Item2[j]);
                }
            }

            for (int i = 0; i < processExecutionResult.FileAccessViolationsNotAllowlisted.Count; i++)
            {
                // Compare individual fields for ReportedFileAccess since it uses reference
                // equality for reported process which would not work for serialization/deserialization
                AssertEqual(processExecutionResult.FileAccessViolationsNotAllowlisted[i], deserializedProcessExecutionResult.FileAccessViolationsNotAllowlisted[i]);
            }

            // Ensure that reported process instances are deduplicated.
            XAssert.AreSame(deserializedProcessExecutionResult.FileAccessViolationsNotAllowlisted[0].Process,
                            deserializedProcessExecutionResult.FileAccessViolationsNotAllowlisted[2].Process);

            for (int i = 0; i < processExecutionResult.DynamicallyObservedFiles.Length; i++)
            {
                AssertEqual(processExecutionResult.DynamicallyObservedFiles[i], deserializedProcessExecutionResult.DynamicallyObservedFiles[i]);
            }

            for (int i = 0; i < processExecutionResult.DynamicallyProbedFiles.Length; i++)
            {
                AssertEqual(processExecutionResult.DynamicallyProbedFiles[i], deserializedProcessExecutionResult.DynamicallyProbedFiles[i]);
            }

            for (int i = 0; i < processExecutionResult.DynamicallyObservedEnumerations.Length; i++)
            {
                AssertEqual(processExecutionResult.DynamicallyObservedEnumerations[i], deserializedProcessExecutionResult.DynamicallyObservedEnumerations[i]);
            }

            XAssert.AreSetsEqual(processExecutionResult.AllowedUndeclaredReads, deserializedProcessExecutionResult.AllowedUndeclaredReads, expectedResult: true);

            var referencedContentLength = processExecutionResult.TwoPhaseCachingInfo.CacheEntry.ReferencedContent.Length;

            for (int i = 0; i < referencedContentLength; i++)
            {
                XAssert.AreEqual(
                    processExecutionResult.TwoPhaseCachingInfo.CacheEntry.ReferencedContent[i],
                    deserializedProcessExecutionResult.TwoPhaseCachingInfo.CacheEntry.ReferencedContent[i]);
            }

            XAssert.AreEqual(9, deserializedProcessExecutionResult.PipProperties["Bar"]);
        }
コード例 #26
0
 public static extern int GetProcessMemoryInfo(IntPtr hProcess, out ProcessMemoryCounters counters, int size);
コード例 #27
0
 public static extern int GetProcessMemoryInfo(IntPtr hProcess, out ProcessMemoryCounters counters, int size);
コード例 #28
0
ファイル: Worker.cs プロジェクト: rustedwizard/BuildXL
        private ProcessSemaphoreInfo[] GetAdditionalResourceInfo(ProcessRunnablePip runnableProcess, ProcessMemoryCounters expectedMemoryCounters)
        {
            using (var semaphoreInfoListWrapper = s_semaphoreInfoListPool.GetInstance())
            {
                var semaphores = semaphoreInfoListWrapper.Instance;

                if (runnableProcess.Process.RequiresAdmin &&
                    runnableProcess.Environment.Configuration.Sandbox.AdminRequiredProcessExecutionMode.ExecuteExternalVm() &&
                    runnableProcess.Environment.Configuration.Sandbox.VmConcurrencyLimit > 0)
                {
                    semaphores.Add(new ProcessSemaphoreInfo(
                                       runnableProcess.Environment.Context.StringTable.AddString(PipInVmSemaphoreName),
                                       value: 1,
                                       limit: runnableProcess.Environment.Configuration.Sandbox.VmConcurrencyLimit));
                }

                if (TotalRamMb == null || runnableProcess.Environment.Configuration.Schedule.UseHistoricalRamUsageInfo != true)
                {
                    // Not tracking working set
                    return(semaphores.ToArray());
                }

                if (!m_ramSemaphoreNameId.IsValid)
                {
                    m_ramSemaphoreNameId = runnableProcess.Environment.Context.StringTable.AddString(RamSemaphoreName);
                    m_ramSemaphoreIndex  = m_workerSemaphores.CreateSemaphore(m_ramSemaphoreNameId, ProcessExtensions.PercentageResourceLimit);
                }

                bool enableLessAggresiveMemoryProjection = runnableProcess.Environment.Configuration.Schedule.EnableLessAggresiveMemoryProjection;
                var  ramSemaphoreInfo = ProcessExtensions.GetNormalizedPercentageResource(
                    m_ramSemaphoreNameId,
                    usage: enableLessAggresiveMemoryProjection ? expectedMemoryCounters.AverageWorkingSetMb : expectedMemoryCounters.PeakWorkingSetMb,
                    total: TotalRamMb.Value);

                semaphores.Add(ramSemaphoreInfo);

                if (runnableProcess.Environment.Configuration.Schedule.EnableHistoricCommitMemoryProjection)
                {
                    if (!m_commitSemaphoreNameId.IsValid)
                    {
                        m_commitSemaphoreNameId = runnableProcess.Environment.Context.StringTable.AddString(CommitSemaphoreName);
                        m_commitSemaphoreIndex  = m_workerSemaphores.CreateSemaphore(m_commitSemaphoreNameId, ProcessExtensions.PercentageResourceLimit);
                    }

                    var commitSemaphoreInfo = ProcessExtensions.GetNormalizedPercentageResource(
                        m_commitSemaphoreNameId,
                        usage: enableLessAggresiveMemoryProjection ? expectedMemoryCounters.AverageCommitSizeMb : expectedMemoryCounters.PeakCommitSizeMb,
                        total: TotalCommitMb.Value);

                    semaphores.Add(commitSemaphoreInfo);
                }

                return(semaphores.ToArray());
            }
        }
コード例 #29
0
 private static extern bool GetProcessMemoryInfo(IntPtr hProcess, out ProcessMemoryCounters counters, uint size);
コード例 #30
0
        public void PipHistoricPerfDataConstructorDoesntCrash()
        {
            // TODO: Use IntelliTest/Pex for this.
            var times = new[]
            {
                new DateTime(DateTime.MinValue.Year + 1, 1, 1).ToUniversalTime(),
                new DateTime(2015, 1, 1).ToUniversalTime(),
                new DateTime(DateTime.MaxValue.Year, 1, 1).ToUniversalTime()
            };
            var spans = new[] { TimeSpan.Zero, TimeSpan.FromSeconds(1), TimeSpan.MaxValue };
            var ints  = new[] { 0, int.MaxValue };

            // Let's say that the highest possible memory usage is currently 1TB.
            var ulongs = new ulong[] { 0, 1, (ulong)1024 * 1024 * 1024 * 1024 };
            var uints  = new uint[] { 0, 1, uint.MaxValue };

            foreach (var executionStart in times)
            {
                foreach (var executionStop in times)
                {
                    foreach (var processExecutionTime in spans)
                    {
                        foreach (var fileMonitoringWarnings in ints)
                        {
                            foreach (var ioCounters in new[]
                            {
                                new IOCounters(
                                    readCounters: new IOTypeCounters(operationCount: 1, transferCount: ulong.MaxValue),
                                    writeCounters: new IOTypeCounters(operationCount: 0, transferCount: 0),
                                    otherCounters: new IOTypeCounters(operationCount: 0, transferCount: 0)
                                    ),
                                new IOCounters(
                                    readCounters: new IOTypeCounters(operationCount: 0, transferCount: 0),
                                    writeCounters: new IOTypeCounters(operationCount: 0, transferCount: 0),
                                    otherCounters: new IOTypeCounters(operationCount: 0, transferCount: 0)
                                    )
                            })
                            {
                                foreach (var userTime in spans)
                                {
                                    foreach (var kernelTime in spans)
                                    {
                                        foreach (var peakMemoryUsage in ulongs)
                                        {
                                            foreach (var numberOfProcesses in uints)
                                            {
                                                foreach (var workerId in uints)
                                                {
                                                    if (executionStart > executionStop)
                                                    {
                                                        continue;
                                                    }

                                                    var performance = new ProcessPipExecutionPerformance(
                                                        PipExecutionLevel.Executed,
                                                        executionStart,
                                                        executionStop,
                                                        FingerprintUtilities.ZeroFingerprint,
                                                        processExecutionTime,
                                                        new FileMonitoringViolationCounters(fileMonitoringWarnings, fileMonitoringWarnings, fileMonitoringWarnings),
                                                        ioCounters,
                                                        userTime,
                                                        kernelTime,
                                                        ProcessMemoryCounters.CreateFromBytes(peakMemoryUsage, peakMemoryUsage, peakMemoryUsage),
                                                        numberOfProcesses,
                                                        workerId);
                                                    var data = new PipHistoricPerfData(performance);
                                                    data = data.Merge(data);
                                                    Analysis.IgnoreResult(data);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }