diff --git a/samples/BenchmarkDotNet.Samples/IntroInProcessWrongEnv.cs b/samples/BenchmarkDotNet.Samples/IntroInProcessWrongEnv.cs index ff44083ac8..6e54a1de73 100644 --- a/samples/BenchmarkDotNet.Samples/IntroInProcessWrongEnv.cs +++ b/samples/BenchmarkDotNet.Samples/IntroInProcessWrongEnv.cs @@ -18,7 +18,7 @@ private class Config : ManualConfig { public Config() { - var wrongPlatform = RuntimeInformation.GetCurrentPlatform() == Platform.X86 + var wrongPlatform = RuntimeInformation.Is64BitPlatform() ? Platform.X64 : Platform.X86; diff --git a/src/BenchmarkDotNet/Diagnosers/WindowsDisassembler.cs b/src/BenchmarkDotNet/Diagnosers/WindowsDisassembler.cs index 2278d3ab7f..2fe1032426 100644 --- a/src/BenchmarkDotNet/Diagnosers/WindowsDisassembler.cs +++ b/src/BenchmarkDotNet/Diagnosers/WindowsDisassembler.cs @@ -164,7 +164,7 @@ public static bool Is64Bit(Process process) return !isWow64; } - return RuntimeInformation.GetCurrentPlatform() == Platform.X64; // todo: find the way to cover all scenarios for .NET Core + return RuntimeInformation.Is64BitPlatform(); // todo: find the way to cover all scenarios for .NET Core } [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] diff --git a/src/BenchmarkDotNet/Environments/Platform.cs b/src/BenchmarkDotNet/Environments/Platform.cs index 462fc0c5a3..30a156b540 100644 --- a/src/BenchmarkDotNet/Environments/Platform.cs +++ b/src/BenchmarkDotNet/Environments/Platform.cs @@ -15,6 +15,16 @@ public enum Platform /// /// x64 /// - X64 + X64, + + /// + /// ARM + /// + Arm, + + /// + /// ARM64 + /// + Arm64 } } \ No newline at end of file diff --git a/src/BenchmarkDotNet/Environments/ProcessorBrandStringHelper.cs b/src/BenchmarkDotNet/Environments/ProcessorBrandStringHelper.cs index 2d4dfb34fd..17b912367e 100644 --- a/src/BenchmarkDotNet/Environments/ProcessorBrandStringHelper.cs +++ b/src/BenchmarkDotNet/Environments/ProcessorBrandStringHelper.cs @@ -19,16 +19,16 @@ public static class ProcessorBrandStringHelper [NotNull] public static string Prettify(CpuInfo cpuInfo, bool includeMaxFrequency = false) { - if (cpuInfo == null) + if (cpuInfo == null || string.IsNullOrEmpty(cpuInfo.ProcessorName)) { - return ""; + return "Unknown processor"; } // Remove parts which don't provide any useful information for user var processorName = cpuInfo.ProcessorName.Replace("@", "").Replace("(R)", "").Replace("(TM)", ""); // If we have found physical core(s), we can safely assume we can drop extra info from brand - if (cpuInfo.PhysicalCoreCount > 0) + if (cpuInfo.PhysicalCoreCount.HasValue && cpuInfo.PhysicalCoreCount.Value > 0) processorName = Regex.Replace(processorName, @"(\w+?-Core Processor)", "").Trim(); string frequencyString = GetBrandStyledActualFrequency(cpuInfo.NominalFrequency); diff --git a/src/BenchmarkDotNet/Extensions/ConfigurationExtensions.cs b/src/BenchmarkDotNet/Extensions/ConfigurationExtensions.cs index 6fab3ad4f2..a66bd069c7 100644 --- a/src/BenchmarkDotNet/Extensions/ConfigurationExtensions.cs +++ b/src/BenchmarkDotNet/Extensions/ConfigurationExtensions.cs @@ -16,6 +16,10 @@ public static string ToConfig(this Platform platform) return "x86"; case Platform.X64: return "x64"; + case Platform.Arm: + return "ARM"; + case Platform.Arm64: + return "ARM64"; default: return "AnyCPU"; } diff --git a/src/BenchmarkDotNet/Extensions/ProcessExtensions.cs b/src/BenchmarkDotNet/Extensions/ProcessExtensions.cs index d3cf9db5dd..815ff8fab1 100644 --- a/src/BenchmarkDotNet/Extensions/ProcessExtensions.cs +++ b/src/BenchmarkDotNet/Extensions/ProcessExtensions.cs @@ -34,7 +34,7 @@ public static void EnsureHighPriority(this Process process, ILogger logger) } internal static string ToPresentation(this IntPtr processorAffinity, int processorCount) - => (RuntimeInformation.GetCurrentPlatform() == Platform.X64 + => (RuntimeInformation.Is64BitPlatform() ? Convert.ToString(processorAffinity.ToInt64(), 2) : Convert.ToString(processorAffinity.ToInt32(), 2)) .PadLeft(processorCount, '0'); @@ -43,7 +43,7 @@ private static IntPtr FixAffinity(IntPtr processorAffinity) { int cpuMask = (1 << Environment.ProcessorCount) - 1; - return RuntimeInformation.GetCurrentPlatform() == Platform.X64 + return RuntimeInformation.Is64BitPlatform() ? new IntPtr(processorAffinity.ToInt64() & cpuMask) : new IntPtr(processorAffinity.ToInt32() & cpuMask); } diff --git a/src/BenchmarkDotNet/Portability/Cpu/CpuInfoFormatter.cs b/src/BenchmarkDotNet/Portability/Cpu/CpuInfoFormatter.cs index b29b1c5386..b9246397ed 100644 --- a/src/BenchmarkDotNet/Portability/Cpu/CpuInfoFormatter.cs +++ b/src/BenchmarkDotNet/Portability/Cpu/CpuInfoFormatter.cs @@ -14,9 +14,7 @@ public static string Format(CpuInfo cpuInfo) var parts = new List { - !string.IsNullOrWhiteSpace(cpuInfo.ProcessorName) - ? ProcessorBrandStringHelper.Prettify(cpuInfo, includeMaxFrequency: true) - : "Unknown processor" + ProcessorBrandStringHelper.Prettify(cpuInfo, includeMaxFrequency: true) }; if (cpuInfo.PhysicalProcessorCount > 0) diff --git a/src/BenchmarkDotNet/Portability/RuntimeInformation.cs b/src/BenchmarkDotNet/Portability/RuntimeInformation.cs index 9647102f4d..5baf80da64 100644 --- a/src/BenchmarkDotNet/Portability/RuntimeInformation.cs +++ b/src/BenchmarkDotNet/Portability/RuntimeInformation.cs @@ -65,7 +65,7 @@ internal static class RuntimeInformation internal static string ScriptFileExtension => IsWindows() ? ".bat" : ".sh"; - internal static string GetArchitecture() => GetCurrentPlatform() == Platform.X86 ? "32bit" : "64bit"; + internal static string GetArchitecture() => Is64BitPlatform() ? "64bit" : "32bit"; private static string DockerSdkVersion => Environment.GetEnvironmentVariable("DOTNET_VERSION"); private static string DockerAspnetSdkVersion => Environment.GetEnvironmentVariable("ASPNETCORE_VERSION"); @@ -238,7 +238,24 @@ internal static Runtime GetCurrentRuntime() throw new NotSupportedException("Unknown .NET Framework"); // todo: adam sitnik fix it } - public static Platform GetCurrentPlatform() => IntPtr.Size == 4 ? Platform.X86 : Platform.X64; + public static Platform GetCurrentPlatform() + { + switch (System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture) + { + case Architecture.Arm: + return Platform.Arm; + case Architecture.Arm64: + return Platform.Arm64; + case Architecture.X64: + return Platform.X64; + case Architecture.X86: + return Platform.X86; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public static bool Is64BitPlatform() => IntPtr.Size == 8; private static IEnumerable GetJitModules() { @@ -258,7 +275,7 @@ internal static bool HasRyuJit() if (IsNetCore) return true; - return GetCurrentPlatform() == Platform.X64 + return Is64BitPlatform() && GetConfiguration() != DebugConfigurationName && !new JitHelper().IsMsX64(); } @@ -420,4 +437,4 @@ internal static VirtualMachineHypervisor GetVirtualMachineHypervisor() return null; } } -} \ No newline at end of file +} diff --git a/src/BenchmarkDotNet/Toolchains/Roslyn/Builder.cs b/src/BenchmarkDotNet/Toolchains/Roslyn/Builder.cs index ed7b9da06d..9f406311b7 100644 --- a/src/BenchmarkDotNet/Toolchains/Roslyn/Builder.cs +++ b/src/BenchmarkDotNet/Toolchains/Roslyn/Builder.cs @@ -95,6 +95,10 @@ private Platform GetPlatform(OurPlatform platform) return Platform.X86; case OurPlatform.X64: return Platform.X64; + case OurPlatform.Arm: + return Platform.Arm; + case OurPlatform.Arm64: + return Platform.Arm64; default: throw new ArgumentOutOfRangeException(nameof(platform), platform, null); } diff --git a/tests/BenchmarkDotNet.IntegrationTests/BuildTimeoutTests.cs b/tests/BenchmarkDotNet.IntegrationTests/BuildTimeoutTests.cs index 57d75ebfb4..3e6cb9887d 100644 --- a/tests/BenchmarkDotNet.IntegrationTests/BuildTimeoutTests.cs +++ b/tests/BenchmarkDotNet.IntegrationTests/BuildTimeoutTests.cs @@ -17,7 +17,7 @@ public BuildTimeoutTests(ITestOutputHelper outputHelper) : base(outputHelper) { [Fact] public void WhenBuildTakesMoreTimeThanTheTimeoutTheBuildIsCancelled() { - if (RuntimeInformation.GetCurrentPlatform() == Platform.X86) // CoreRT does not support 32bit yet + if (!RuntimeInformation.Is64BitPlatform()) // CoreRT does not support 32bit yet return; // we use CoreRT on purpose because it takes a LOT of time to build it diff --git a/tests/BenchmarkDotNet.IntegrationTests/CoreRtTests.cs b/tests/BenchmarkDotNet.IntegrationTests/CoreRtTests.cs index 471c1ab82e..aa8cd39c45 100755 --- a/tests/BenchmarkDotNet.IntegrationTests/CoreRtTests.cs +++ b/tests/BenchmarkDotNet.IntegrationTests/CoreRtTests.cs @@ -17,7 +17,7 @@ public CoreRtTests(ITestOutputHelper outputHelper) : base(outputHelper) { } [Fact] public void CoreRtIsSupported() { - if (RuntimeInformation.GetCurrentPlatform() == Platform.X86) // CoreRT does not support 32bit yet + if (!RuntimeInformation.Is64BitPlatform()) // CoreRT does not support 32bit yet return; var config = ManualConfig.CreateEmpty() diff --git a/tests/BenchmarkDotNet.Tests/Environments/ProcessorBrandStringTests.cs b/tests/BenchmarkDotNet.Tests/Environments/ProcessorBrandStringTests.cs index b17c8f8fb1..ef152d7ccd 100644 --- a/tests/BenchmarkDotNet.Tests/Environments/ProcessorBrandStringTests.cs +++ b/tests/BenchmarkDotNet.Tests/Environments/ProcessorBrandStringTests.cs @@ -50,5 +50,15 @@ public void AmdIsPrettifiedWithDiffFrequencies(string originalName, string prett Assert.Equal(prettifiedName, ProcessorBrandStringHelper.Prettify(cpuInfo, includeMaxFrequency: true)); } + + [Theory] + [InlineData("", "Unknown processor")] + [InlineData(null, "Unknown processor")] + public void UnknownProcessorDoesNotThrow(string originalName, string prettifiedName) + { + var cpuInfo = new CpuInfo(originalName, nominalFrequency: null); + + Assert.Equal(prettifiedName, ProcessorBrandStringHelper.Prettify(cpuInfo, includeMaxFrequency: true)); + } } } \ No newline at end of file