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); }
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 }
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); }
// ReSharper disable once VirtualMemberCallInConstructor public TheoryWindowsOnlyAttribute(string nonWindowsSkipReason) { if (!RuntimeInformation.IsWindows()) { Skip = nonWindowsSkipReason; } }
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}")); } }
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); }
public IEnumerable <ValidationError> Validate(ValidationParameters validationParameters) { if (!RuntimeInformation.IsWindows()) { yield return(new ValidationError(true, $"{GetType().Name} is supported only on Windows")); } }
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); }
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)); }
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()); }
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}"); }
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); }
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); }
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"); }
static Chronometer() { if (RuntimeInformation.IsWindows() && WindowsClock.IsAvailable) { BestClock = WindowsClock; } else { BestClock = Stopwatch; } }
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); }
internal void ApplyPerformancePlan(Guid?guid) { if (RuntimeInformation.IsWindows()) { if (guid != null && powerPlanChanged == false) { ApplyPlanByGuid(guid.Value); } else if (guid == null) { ApplyUserPowerPlan(); } } }
internal void ApplyPerformancePlan(string guid) { if (RuntimeInformation.IsWindows()) { if (string.IsNullOrEmpty(guid) == false && powerPlanChanged == false) { ApplyPlanByGuid(guid); } else if (string.IsNullOrEmpty(guid)) { ApplyUserPowerPlan(); } } }
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)); } } }
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}"); }
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)); }
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); } }
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)); } } }
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})"); } } }
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()); }
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); }
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); }
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); } }
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); }
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); } } }