コード例 #1
0
        public static bool TrySetAffinity(
            [NotNull] this Process process,
            IntPtr processorAffinity,
            [NotNull] ILogger logger)
        {
            if (process == null)
            {
                throw new ArgumentNullException(nameof(process));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            if (!RuntimeInformation.IsWindows() && !RuntimeInformation.IsLinux())
            {
                return(false);
            }

            try
            {
                process.ProcessorAffinity = FixAffinity(processorAffinity);
                return(true);
            }
            catch (Exception ex)
            {
                logger.WriteLineError(
                    $"// ! Failed to set up processor affinity 0x{(long)processorAffinity:X} for process {process}. Make sure you have the right permissions. Message: {ex.Message}");
            }

            return(false);
        }
コード例 #2
0
        public void CurrentRuntimeIsProperlyRecognized()
        {
            var runtime = RuntimeInformation.GetCurrentRuntime();

#if NETFRAMEWORK
            if (RuntimeInformation.IsWindows())
            {
                Assert.True(runtime is ClrRuntime);
            }
            else
            {
                Assert.True(runtime is MonoRuntime);
            }
#elif NETCOREAPP2_1
            Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.TargetFrameworkMoniker == TargetFrameworkMoniker.NetCoreApp21);
#elif NETCOREAPP2_2
            Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.TargetFrameworkMoniker == TargetFrameworkMoniker.NetCoreApp22);
#elif NETCOREAPP3_0
            Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.TargetFrameworkMoniker == TargetFrameworkMoniker.NetCoreApp30);
#elif NETCOREAPP3_1
            Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.TargetFrameworkMoniker == TargetFrameworkMoniker.NetCoreApp31);
#elif NETCOREAPP5_0
            Assert.True(runtime is CoreRuntime coreRuntime && coreRuntime.TargetFrameworkMoniker == TargetFrameworkMoniker.NetCoreApp50);
#endif
        }
コード例 #3
0
        private static bool TryFindRScript(ILogger consoleLogger, out string rscriptPath)
        {
            string rscriptExecutable = RuntimeInformation.IsWindows() ? "Rscript.exe" : "Rscript";

            rscriptPath = null;
            string rHome = Environment.GetEnvironmentVariable("R_HOME");

            if (rHome != null)
            {
                rscriptPath = Path.Combine(rHome, "bin", rscriptExecutable);
                if (File.Exists(rscriptPath))
                {
                    return(true);
                }

                consoleLogger.WriteLineError($"RPlotExporter requires R_HOME to point to the parent directory of the existing '{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}{rscriptExecutable} (currently points to {rHome})");
            }

            // No R_HOME, or R_HOME points to a wrong folder, try the path
            rscriptPath = FindInPath(rscriptExecutable);
            if (rscriptPath == null)
            {
                consoleLogger.WriteLineError($"RPlotExporter couldn't find {rscriptExecutable} in your PATH and no R_HOME environment variable is defined");
                return(false);
            }

            return(true);
        }
コード例 #4
0
 // ReSharper disable once VirtualMemberCallInConstructor
 public TheoryWindowsOnlyAttribute(string nonWindowsSkipReason)
 {
     if (!RuntimeInformation.IsWindows())
     {
         Skip = nonWindowsSkipReason;
     }
 }
コード例 #5
0
        internal static ClrRuntime GetCurrentVersion()
        {
            if (!RuntimeInformation.IsWindows())
            {
                throw new NotSupportedException("Full .NET Framework supports Windows OS only.");
            }

            // this logic is put to a separate method to avoid any assembly loading issues on non Windows systems
            string sdkVersion = FrameworkVersionHelper.GetLatestNetDeveloperPackVersion();

            string version = sdkVersion
                             ?? FrameworkVersionHelper.GetFrameworkReleaseVersion(); // .NET Developer Pack is not installed

            switch (version)
            {
            case "4.6.1": return(Net461);

            case "4.6.2": return(Net462);

            case "4.7":   return(Net47);

            case "4.7.1": return(Net471);

            case "4.7.2": return(Net472);

            case "4.8":   return(Net48);

            default:     // unlikely to happen but theoretically possible
                return(new ClrRuntime(RuntimeMoniker.NotRecognized, $"net{version.Replace(".", null)}", $".NET {version}"));
            }
        }
コード例 #6
0
        public override bool IsSupported(Benchmark benchmark, ILogger logger, IResolver resolver)
        {
            if (!base.IsSupported(benchmark, logger, resolver))
            {
                return(false);
            }

            if (!RuntimeInformation.IsWindows())
            {
                logger.WriteLineError($"Classic .NET toolchain is supported only for Windows, benchmark '{benchmark.DisplayInfo}' will not be executed");
                return(false);
            }

            if (!HostEnvironmentInfo.GetCurrent().IsDotNetCliInstalled())
            {
                logger.WriteLineError($"BenchmarkDotNet requires dotnet cli toolchain to be installed, benchmark '{benchmark.DisplayInfo}' will not be executed");
                return(false);
            }

            if (benchmark.Job.ResolveValue(EnvMode.JitCharacteristic, resolver) == Jit.LegacyJit)
            {
                logger.WriteLineError($"Currently dotnet cli toolchain supports only RyuJit, benchmark '{benchmark.DisplayInfo}' will not be executed");
                return(false);
            }

            return(true);
        }
コード例 #7
0
 public IEnumerable <ValidationError> Validate(ValidationParameters validationParameters)
 {
     if (!RuntimeInformation.IsWindows())
     {
         yield return(new ValidationError(true, $"{GetType().Name} is supported only on Windows"));
     }
 }
コード例 #8
0
        public override bool IsSupported(Benchmark benchmark, ILogger logger, IResolver resolver)
        {
            if (!base.IsSupported(benchmark, logger, resolver))
            {
                return(false);
            }

            if (!RuntimeInformation.IsWindows())
            {
                logger.WriteLineError($"Classic .NET toolchain is supported only for Windows, benchmark '{benchmark.DisplayInfo}' will not be executed");
                return(false);
            }

            if (!HostEnvironmentInfo.GetCurrent().IsDotNetCliInstalled())
            {
                logger.WriteLineError($"BenchmarkDotNet requires dotnet cli toolchain to be installed, benchmark '{benchmark.DisplayInfo}' will not be executed");
                return(false);
            }

            if (benchmark.Job.HasValue(EnvMode.JitCharacteristic) && benchmark.Job.Env.Jit == Jit.LegacyJit)
            {
                logger.WriteLineError($"Currently dotnet cli toolchain supports only RyuJit, benchmark '{benchmark.DisplayInfo}' will not be executed");
                return(false);
            }

#if NETCOREAPP1_1
            if (benchmark.Job.HasValue(InfrastructureMode.EnvironmentVariablesCharacteristic))
            {
                logger.WriteLineError($"ProcessStartInfo.EnvironmentVariables is avaialable for .NET Core 2.0, benchmark '{benchmark.DisplayInfo}' will not be executed");
                return(false);
            }
#endif

            return(true);
        }
コード例 #9
0
        protected override void GenerateBuildScript(Benchmark benchmark, ArtifactsPaths artifactsPaths, IResolver resolver)
        {
            var prefix = RuntimeInformation.IsWindows() ? "" : "#!/bin/bash\n";
            var list   = new List <string>();

            if (!RuntimeInformation.IsWindows())
            {
                list.Add("mono");
            }
            list.Add("csc");
            list.Add("/noconfig");
            list.Add("/target:exe");
            list.Add("/optimize");
            list.Add("/unsafe");
            list.Add("/platform:" + benchmark.Job.Env.Platform.Resolve(resolver).ToConfig());
            list.Add("/appconfig:" + artifactsPaths.AppConfigPath.Escape());
            var references = GetAllReferences(benchmark).Select(assembly => assembly.Location.Escape());

            list.Add("/reference:" + string.Join(",", references));
            list.Add(Path.GetFileName(artifactsPaths.ProgramCodePath));

            File.WriteAllText(
                artifactsPaths.BuildScriptFilePath,
                prefix + string.Join(" ", list));
        }
コード例 #10
0
 private static IToolchain GetCurrentVersion()
 {
     if (!RuntimeInformation.IsWindows())
     {
         return(Net46); // we return .NET 4.6 which during validaiton will tell the user about lack of support
     }
     return(GetCurrentVersionBasedOnWindowsRegistry());
 }
コード例 #11
0
        protected static string GetPortableRuntimeIdentifier()
        {
            // Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.GetRuntimeIdentifier()
            // returns win10-x64, we want the simpler form win-x64
            // the values taken from https://docs.microsoft.com/en-us/dotnet/core/rid-catalog#macos-rids
            string osPart = RuntimeInformation.IsWindows() ? "win" : (RuntimeInformation.IsMacOSX() ? "osx" : "linux");

            return($"{osPart}-{RuntimeEnvironment.RuntimeArchitecture}");
        }
コード例 #12
0
 private static CpuInfo Load()
 {
     if (RuntimeInformation.IsWindows())
     {
         string content = ProcessHelper.RunAndReadOutput("wmic", "cpu get Name, NumberOfCores, NumberOfLogicalProcessors, CurrentClockSpeed /Format:List");
         return(WmicCpuInfoParser.ParseOutput(content));
     }
     return(null);
 }
コード例 #13
0
 private static CpuInfo Load()
 {
     if (RuntimeInformation.IsWindows())
     {
         string argList = $"{WmicCpuInfoKeyNames.Name}, {WmicCpuInfoKeyNames.NumberOfCores}, {WmicCpuInfoKeyNames.NumberOfLogicalProcessors}, {WmicCpuInfoKeyNames.MaxClockSpeed}";
         string content = ProcessHelper.RunAndReadOutput("wmic", $"cpu get {argList} /Format:List");
         return(WmicCpuInfoParser.ParseOutput(content));
     }
     return(null);
 }
コード例 #14
0
        public IEnumerable <string> ExportToFiles(Summary summary, ILogger consoleLogger)
        {
            const string scriptFileName = "BuildPlots.R";

            yield return(scriptFileName);

            string fileNamePrefix = Path.Combine(summary.ResultsDirectoryPath, summary.Title);
            string scriptFullPath = Path.Combine(summary.ResultsDirectoryPath, scriptFileName);
            string script         = ResourceHelper.
                                    LoadTemplate(scriptFileName).
                                    Replace("$BenchmarkDotNetVersion$", BenchmarkDotNetInfo.FullTitle).
                                    Replace("$CsvSeparator$", CsvMeasurementsExporter.Default.Separator);

            lock (buildScriptLock)
                File.WriteAllText(scriptFullPath, script);

            string rscriptExecutable = RuntimeInformation.IsWindows() ? "Rscript.exe" : "Rscript";
            string rscriptPath;
            string rHome = Environment.GetEnvironmentVariable("R_HOME");

            if (rHome != null)
            {
                rscriptPath = Path.Combine(rHome, "bin", rscriptExecutable);
                if (!File.Exists(rscriptPath))
                {
                    consoleLogger.WriteLineError($"RPlotExporter requires R_HOME to point to the directory containing bin{Path.DirectorySeparatorChar}{rscriptExecutable} (currently points to {rHome})");
                    yield break;
                }
            }
            else // No R_HOME, try the path
            {
                rscriptPath = FindInPath(rscriptExecutable);
                if (rscriptPath == null)
                {
                    consoleLogger.WriteLineError($"RPlotExporter couldn't find {rscriptExecutable} in your PATH and no R_HOME environment variable is defined");
                    yield break;
                }
            }

            var start = new ProcessStartInfo
            {
                UseShellExecute        = false,
                RedirectStandardOutput = false,
                CreateNoWindow         = true,
                FileName         = rscriptPath,
                WorkingDirectory = summary.ResultsDirectoryPath,
                Arguments        = $"\"{scriptFullPath}\" \"{fileNamePrefix}-measurements.csv\""
            };

            using (var process = Process.Start(start))
                process?.WaitForExit();
            yield return(fileNamePrefix + "-boxplot.png");

            yield return(fileNamePrefix + "-barplot.png");
        }
コード例 #15
0
ファイル: Chronometer.cs プロジェクト: aritryakumar/dotnet
 static Chronometer()
 {
     if (RuntimeInformation.IsWindows() && WindowsClock.IsAvailable)
     {
         BestClock = WindowsClock;
     }
     else
     {
         BestClock = Stopwatch;
     }
 }
コード例 #16
0
        private static IToolchain GetCurrentVersion()
        {
            if (!RuntimeInformation.IsWindows())
            {
                return(Net46); // we return .NET 4.6 which during validation will tell the user about lack of support
            }
            // this logic is put to a separate method to avoid any assembly loading issues on non Windows systems
            string version = FrameworkVersionHelper.GetLatestNetDeveloperPackVersion();

            return(Toolchains.TryGetValue(version, out var toolchain) ? toolchain : Default);
        }
コード例 #17
0
 internal void ApplyPerformancePlan(Guid?guid)
 {
     if (RuntimeInformation.IsWindows())
     {
         if (guid != null && powerPlanChanged == false)
         {
             ApplyPlanByGuid(guid.Value);
         }
         else if (guid == null)
         {
             ApplyUserPowerPlan();
         }
     }
 }
コード例 #18
0
 internal void ApplyPerformancePlan(string guid)
 {
     if (RuntimeInformation.IsWindows())
     {
         if (string.IsNullOrEmpty(guid) == false && powerPlanChanged == false)
         {
             ApplyPlanByGuid(guid);
         }
         else if (string.IsNullOrEmpty(guid))
         {
             ApplyUserPowerPlan();
         }
     }
 }
コード例 #19
0
        public IEnumerable <ValidationError> Validate(ValidationParameters validationParameters)
        {
            foreach (var benchmark in validationParameters.Benchmarks)
            {
                if (!RuntimeInformation.IsWindows() && !ShouldUseMonoDisassembler(benchmark))
                {
                    yield return(new ValidationError(false, "No Disassembler support, only Mono is supported for non-Windows OS", benchmark));
                }

                if (benchmark.Job.Infrastructure.HasValue(InfrastructureMode.ToolchainCharacteristic) &&
                    benchmark.Job.Infrastructure.Toolchain is InProcessToolchain)
                {
                    yield return(new ValidationError(true, "InProcessToolchain has no DisassemblyDiagnoser support", benchmark));
                }
            }
        }
コード例 #20
0
        internal static string GetPortableRuntimeIdentifier()
        {
            // Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.GetRuntimeIdentifier()
            // returns win10-x64, we want the simpler form win-x64
            // the values taken from https://docs.microsoft.com/en-us/dotnet/core/rid-catalog#macos-rids
            string osPart = RuntimeInformation.IsWindows() ? "win" : (RuntimeInformation.IsMacOSX() ? "osx" : "linux");

            string architecture =
#if NETSTANDARD
                RuntimeEnvironment.RuntimeArchitecture;
#else
                System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant();
#endif

            return($"{osPart}-{architecture}");
        }
コード例 #21
0
        private const int CommonSenseLimit    = 1024; // for benchmarks that use args like "new string('a', 200_000)"

        internal static string GetTraceFilePath(DiagnoserActionParameters details, DateTime creationTime, string fileExtension)
        {
            string nameNoLimit = GetFilePathNoLimits(details, creationTime, fileExtension);

            // long paths can be enabled on Windows but it does not mean that ETW is going to work fine..
            // so we always use 260 as limit on Windows
            int limit = RuntimeInformation.IsWindows()
                ? WindowsOldPathLimit - "userheap.etl".Length // the session files get merged, they need to have same name (without extension)
                : CommonSenseLimit;

            if (nameNoLimit.Length <= limit)
            {
                return(nameNoLimit);
            }

            return(GetLimitedFilePath(details, creationTime, fileExtension, limit));
        }
コード例 #22
0
 public static void KillTree(this Process process, TimeSpan timeout)
 {
     if (RuntimeInformation.IsWindows())
     {
         RunProcessAndIgnoreOutput("taskkill", $"/T /F /PID {process.Id}", timeout);
     }
     else
     {
         var children = new HashSet <int>();
         GetAllChildIdsUnix(process.Id, children, timeout);
         foreach (var childId in children)
         {
             KillProcessUnix(childId, timeout);
         }
         KillProcessUnix(process.Id, timeout);
     }
 }
コード例 #23
0
        public static IEnumerable <ValidationError> Validate(ValidationParameters validationParameters, bool mandatory)
        {
            if (!RuntimeInformation.IsWindows())
            {
                yield return(new ValidationError(true, "Hardware Counters and EtwProfiler are supported only on Windows"));

                yield break;
            }

            if (!validationParameters.Config.GetHardwareCounters().Any() && mandatory)
            {
                yield return(new ValidationError(true, "No Hardware Counters defined, probably a bug"));

                yield break;
            }

            if (TraceEventSession.IsElevated() != true)
            {
                yield return(new ValidationError(true, "Must be elevated (Admin) to use ETW Kernel Session (required for Hardware Counters and EtwProfiler)."));
            }

            var availableCpuCounters = TraceEventProfileSources.GetInfo();

            foreach (var hardwareCounter in validationParameters.Config.GetHardwareCounters())
            {
                if (!EtwTranslations.TryGetValue(hardwareCounter, out var counterName))
                {
                    yield return(new ValidationError(true, $"Counter {hardwareCounter} not recognized. Please make sure that you are using counter available on your machine. You can get the list of available counters by running `tracelog.exe -profilesources Help`"));
                }

                if (!availableCpuCounters.ContainsKey(counterName))
                {
                    yield return(new ValidationError(true, $"The counter {counterName} is not available. Please make sure you are Windows 8+ without Hyper-V"));
                }
            }

            foreach (var benchmark in validationParameters.Benchmarks)
            {
                if (benchmark.Job.Infrastructure.HasValue(InfrastructureMode.ToolchainCharacteristic) &&
                    (benchmark.Job.Infrastructure.Toolchain is InProcessToolchain || benchmark.Job.Infrastructure.Toolchain is InProcessEmitToolchain))
                {
                    yield return(new ValidationError(true, "Hardware Counters are not supported for InProcessToolchain.", benchmark));
                }
            }
        }
コード例 #24
0
 internal void ApplyUserPowerPlan()
 {
     if (powerPlanChanged && RuntimeInformation.IsWindows())
     {
         try
         {
             if (userCurrentPowerPlan != null && PowerManagementHelper.Set(userCurrentPowerPlan.Value))
             {
                 powerPlanChanged = false;
                 var powerPlanFriendlyName = PowerManagementHelper.CurrentPlanFriendlyName;
                 logger.WriteLineInfo($"Successfully reverted power plan (GUID: {userCurrentPowerPlan.Value} FriendlyName: {powerPlanFriendlyName})");
             }
         }
         catch (Exception ex)
         {
             logger.WriteLineError($"Cannot revert power plan (error message: {ex.Message})");
         }
     }
 }
コード例 #25
0
        private static IDiagnoser[] LoadDiagnosers()
        {
            if (RuntimeInformation.IsMono)
            {
                return(LoadMono());
            }
            if (RuntimeInformation.IsFullFramework)
            {
                return(LoadClassic());
            }

            // we can try to load `BenchmarkDotNet.Diagnostics.Windows` on Windows because it's using a .NET Standard compatibile EventTrace lib now
            if (RuntimeInformation.IsWindows())
            {
                return(LoadClassic());
            }

            return(LoadCore());
        }
コード例 #26
0
        public override bool IsSupported(BenchmarkCase benchmarkCase, ILogger logger, IResolver resolver)
        {
            if (!base.IsSupported(benchmarkCase, logger, resolver))
            {
                return(false);
            }

            if (InvalidCliPath(CustomDotNetCliPath, benchmarkCase, logger))
            {
                return(false);
            }

            if (RuntimeInformation.IsWindows())
            {
                logger.WriteLineError($"{nameof(WasmToolChain)} is supported only on Unix, benchmark '{benchmarkCase.DisplayInfo}' will not be executed");
                return(false);
            }
            return(true);
        }
コード例 #27
0
        public override bool IsSupported(BenchmarkCase benchmarkCase, ILogger logger, IResolver resolver)
        {
            if (!base.IsSupported(benchmarkCase, logger, resolver))
            {
                return(false);
            }

            if (!RuntimeInformation.IsWindows())
            {
                logger.WriteLineError($"Classic .NET toolchain is supported only for Windows, benchmark '{benchmarkCase.DisplayInfo}' will not be executed");
                return(false);
            }

            if (InvalidCliPath(customDotNetCliPath: null, benchmarkCase, logger))
            {
                return(false);
            }

            return(true);
        }
コード例 #28
0
        public static IntPtr?TryGetAffinity([NotNull] this Process process)
        {
            if (process == null)
            {
                throw new ArgumentNullException(nameof(process));
            }

            if (!RuntimeInformation.IsWindows() && !RuntimeInformation.IsLinux())
            {
                return(null);
            }

            try
            {
                return(process.ProcessorAffinity);
            }
            catch (PlatformNotSupportedException)
            {
                return(null);
            }
        }
コード例 #29
0
        public override bool IsSupported(BenchmarkCase benchmarkCase, ILogger logger, IResolver resolver)
        {
            if (!base.IsSupported(benchmarkCase, logger, resolver))
            {
                return(false);
            }

            if (!RuntimeInformation.IsWindows())
            {
                logger.WriteLineError($"Classic .NET toolchain is supported only for Windows, benchmark '{benchmarkCase.DisplayInfo}' will not be executed");
                return(false);
            }

            if (!HostEnvironmentInfo.GetCurrent().IsDotNetCliInstalled())
            {
                logger.WriteLineError($"BenchmarkDotNet requires dotnet cli toolchain to be installed, benchmark '{benchmarkCase.DisplayInfo}' will not be executed");
                return(false);
            }

            return(true);
        }
コード例 #30
0
        public void ExporterUsesFullyQualifiedTypeNameAsFileName()
        {
            string resultsDirectoryPath = Path.GetTempPath();
            var    exporter             = new MockExporter();
            var    mockSummary          = GetMockSummary(resultsDirectoryPath, typeof(Generic <int>));
            var    expectedFilePath     = RuntimeInformation.IsWindows()
                ? $"{Path.Combine(mockSummary.ResultsDirectoryPath, "BenchmarkDotNet.IntegrationTests.Generic_Int32_")}-report.txt"
                : $"{Path.Combine(mockSummary.ResultsDirectoryPath, "BenchmarkDotNet.IntegrationTests.Generic<Int32>")}-report.txt"; // "<" is OK for non-Windows OSes ;)
            string actualFilePath = null;

            try
            {
                actualFilePath = exporter.ExportToFiles(mockSummary, NullLogger.Instance).First();

                Assert.Equal(expectedFilePath, actualFilePath);
            }
            finally
            {
                if (File.Exists(actualFilePath))
                {
                    File.Delete(actualFilePath);
                }
            }
        }