Skip to content

Commit

Permalink
target .NET Core 2.0 to take full advantage of the new API, fixes #539
Browse files Browse the repository at this point in the history
  • Loading branch information
adamsitnik committed Sep 5, 2017
1 parent cc8d074 commit 97ab49c
Show file tree
Hide file tree
Showing 27 changed files with 82 additions and 46 deletions.
2 changes: 1 addition & 1 deletion build/common.props
Expand Up @@ -19,7 +19,7 @@
<PropertyGroup Condition=" '$(TargetFramework)' == 'net46' ">
<DefineConstants>$(DefineConstants);CLASSIC</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' ">
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' Or '$(TargetFramework)' == 'netcoreapp2.0' ">
<DefineConstants>$(DefineConstants);CORE</DefineConstants>
</PropertyGroup>

Expand Down
Expand Up @@ -2,7 +2,7 @@
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<AssemblyTitle>BenchmarkDotNet.Samples</AssemblyTitle>
<TargetFrameworks>netcoreapp1.1;net46</TargetFrameworks>
<TargetFrameworks>netcoreapp1.1;net46;netcoreapp2.0</TargetFrameworks>
<RuntimeIdentifiers>win7-x64;win7-x86;osx.10.10-x64;osx.10.11-x64;ubuntu.14.04-x64;ubuntu.16.04-x64;centos.7-x64;rhel.7.2-x64;debian.8-x64;fedora.23-x64;opensuse.13.2-x64</RuntimeIdentifiers>
<RuntimeIdentifier Condition=" '$(TargetFramework)' == 'net46' ">win7-x86</RuntimeIdentifier>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand All @@ -21,7 +21,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\BenchmarkDotNet\BenchmarkDotNet.csproj" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' Or '$(TargetFramework)' == 'netcoreapp2.0' ">
<PackageReference Include="System.ComponentModel.EventBasedAsync" Version="4.0.11" />
</ItemGroup>
</Project>
@@ -1,4 +1,4 @@
#if !CORE
#if !NETCOREAPP1_1
using System.Collections.Generic;
using System.Linq;
using BenchmarkDotNet.Attributes;
Expand Down
@@ -1,4 +1,4 @@
#if !CORE
#if !NETCOREAPP1_1
using System.Diagnostics;
using BenchmarkDotNet.Attributes;

Expand Down
4 changes: 2 additions & 2 deletions src/BenchmarkDotNet.Core/BenchmarkDotNet.Core.csproj
Expand Up @@ -2,7 +2,7 @@
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<AssemblyTitle>BenchmarkDotNet.Core</AssemblyTitle>
<TargetFrameworks>net46;netcoreapp1.1</TargetFrameworks>
<TargetFrameworks>net46;netcoreapp1.1;netcoreapp2.0</TargetFrameworks>
<NoWarn>$(NoWarn);1591</NoWarn>
<AssemblyName>BenchmarkDotNet.Core</AssemblyName>
<PackageId>BenchmarkDotNet.Core</PackageId>
Expand All @@ -23,7 +23,7 @@
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' Or '$(TargetFramework)' == 'netcoreapp1.1' ">
<PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet.Core/Code/CodeGenerator.cs
Expand Up @@ -146,7 +146,7 @@ private static string GetParamsContent(Benchmark benchmark)

private static string GetExtraAttributes(Target target)
{
#if !CORE
#if !NETCOREAPP1_1
if (target.Method.GetCustomAttributes(false).OfType<System.STAThreadAttribute>().Any())
{
return "[System.STAThreadAttribute]";
Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet.Core/Diagnosers/WindowsDisassembler.cs
Expand Up @@ -141,7 +141,7 @@ public static bool Is64Bit(Process process)
if (Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") == "x86")
return false;

#if !CORE
#if !NETCOREAPP1_1
bool isWow64;
if (!IsWow64Process(process.Handle, out isWow64))
throw new Exception("Not Windows");
Expand Down
4 changes: 3 additions & 1 deletion src/BenchmarkDotNet.Core/Engines/GcStats.cs
Expand Up @@ -128,8 +128,10 @@ private static long GetAllocatedBytes(bool isDiagnosticsEnabled)
// AppDomain. The number is accurate as of the last garbage collection." - CLR via C#
// so we enforce GC.Collect here just to make sure we get accurate results
GC.Collect();
#if CORE
#if NETCOREAPP1_1
return GetAllocatedBytesForCurrentThreadDelegate.Invoke();
#elif NETCOREAPP2_0
return GC.GetAllocatedBytesForCurrentThread();
#elif CLASSIC
return AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/BenchmarkDotNet.Core/Extensions/CommonExtensions.cs
Expand Up @@ -88,8 +88,10 @@ public static string GetColumnTitle(this IColumn column, ISummaryStyle style)

public static bool IsOneOf<T>(this T value, params T[] values) => values.Contains(value);

#if !NETCOREAPP2_0 // this method was added to the .NET Core 2.0 framework itself ;)
public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
=> dictionary.TryGetValue(key, out TValue value) ? value : default(TValue);
#endif

public static double Sqr(this double x) => x * x;
public static double Pow(this double x, double k) => Math.Pow(x, k);
Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet.Core/Extensions/ProcessExtensions.cs
Expand Up @@ -100,7 +100,7 @@ private static IntPtr FixAffinity(IntPtr processorAffinity)

internal static void SetEnvironmentVariables(this ProcessStartInfo start, Benchmark benchmark, IResolver resolver)
{
#if !CORE // ProcessStartInfo.EnvironmentVariables is avaialable for .NET Core 2.0+
#if !NETCOREAPP1_1 // ProcessStartInfo.EnvironmentVariables is avaialable for .NET Core 2.0+
if (!benchmark.Job.HasValue(InfrastructureMode.EnvironmentVariablesCharacteristic))
return;

Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet.Core/Extensions/ThreadExtensions.cs
@@ -1,4 +1,4 @@
#if CLASSIC
#if !NETCOREAPP1_1

using System;
using System.Threading;
Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet.Core/Portability/StreamWriter.cs
Expand Up @@ -4,7 +4,7 @@ internal static class StreamWriter
{
internal static System.IO.StreamWriter FromPath(string path, bool append = false)
{
#if !CORE
#if !NETCOREAPP1_1
return new System.IO.StreamWriter(path, append);
#else
return new System.IO.StreamWriter(System.IO.File.OpenWrite(path));
Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet.Core/Portability/StringExtensions.cs
Expand Up @@ -18,7 +18,7 @@ private static StringComparison IgnoreCaseStringComparison
{
get
{
#if !CORE
#if !NETCOREAPP1_1
return StringComparison.InvariantCultureIgnoreCase;
#else
// http://stackoverflow.com/questions/14600694/where-has-stringcomparison-invariantcultureignorecase-gone
Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet.Core/Reports/Summary.cs
Expand Up @@ -28,7 +28,7 @@ public class Summary

private readonly Dictionary<Job, string> shortInfos;
private readonly Lazy<Job[]> jobs;
private readonly IDictionary<Benchmark, BenchmarkReport> reportMap = new Dictionary<Benchmark, BenchmarkReport>();
private readonly Dictionary<Benchmark, BenchmarkReport> reportMap = new Dictionary<Benchmark, BenchmarkReport>();

public bool HasReport(Benchmark benchmark) => reportMap.ContainsKey(benchmark);

Expand Down
2 changes: 0 additions & 2 deletions src/BenchmarkDotNet.Core/Reports/SummaryTableExtensions.cs
Expand Up @@ -108,9 +108,7 @@ private static StringBuilder GetClearBuffer()
return __buffer;
}

#if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private static void PadLeft(SummaryTable table, string[] line, string leftDel, string rightDel, int columnIndex, StringBuilder buffer)
{
const char space = ' ';
Expand Down
Expand Up @@ -65,11 +65,13 @@ public override bool IsSupported(Benchmark benchmark, ILogger logger, IResolver
return false;
}

if (!RuntimeInformation.IsClassic() && benchmark.Job.HasValue(InfrastructureMode.EnvironmentVariablesCharacteristic))
#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;
}
Expand Down
Expand Up @@ -68,11 +68,14 @@ public override bool IsSupported(Benchmark benchmark, ILogger logger, IResolver
logger.WriteLineError($"Currently project.json does not support gcAllowVeryLargeObjects (app.config does), benchmark '{benchmark.DisplayInfo}' will not be executed");
return false;
}
if (!RuntimeInformation.IsClassic() && benchmark.Job.HasValue(InfrastructureMode.EnvironmentVariablesCharacteristic))

#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;
}
Expand Down
Expand Up @@ -13,7 +13,12 @@ public class NetCoreAppSettings
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp12 = new NetCoreAppSettings("netcoreapp1.2", null, ".NET Core 1.0");
[PublicAPI] public static readonly NetCoreAppSettings NetCoreApp20 = new NetCoreAppSettings("netcoreapp2.0", null, ".NET Core 2.0");

private static NetCoreAppSettings Default => NetCoreApp11;
private static NetCoreAppSettings Default =>
#if NETCOREAPP2_0
NetCoreApp20;
#else
NetCoreApp11;
#endif

/// <summary>
/// <param name="targetFrameworkMoniker">
Expand All @@ -37,7 +42,7 @@ public class NetCoreAppSettings
}

/// <summary>
/// sample values: netcoreapp1.1, netcoreapp1.2, netcoreapp2.0
/// sample values: netcoreapp1.1, netcoreapp2.0, netcoreapp2.1
/// </summary>
public string TargetFrameworkMoniker { get; }

Expand Down
Expand Up @@ -67,7 +67,7 @@ public ExecuteResult Execute(ExecuteParameters executeParameters)
int exitCode = -1;
var runThread = new Thread(() => exitCode = ExecuteCore(host, executeParameters.Benchmark, executeParameters.Logger));

#if CLASSIC
#if !NETCOREAPP1_1
if (executeParameters.Benchmark.Target.Method.GetCustomAttributes<STAThreadAttribute>(false).Any())
{
runThread.SetApartmentState(ApartmentState.STA);
Expand All @@ -93,7 +93,7 @@ private int ExecuteCore(IHost host, Benchmark benchmark, ILogger logger)
var process = Process.GetCurrentProcess();
var oldPriority = process.PriorityClass;
var oldAffinity = process.TryGetAffinity();
#if CLASSIC
#if !NETCOREAPP1_1
var thread = Thread.CurrentThread;
var oldThreadPriority = thread.Priority;
#endif
Expand All @@ -102,7 +102,7 @@ private int ExecuteCore(IHost host, Benchmark benchmark, ILogger logger)
try
{
process.TrySetPriority(ProcessPriorityClass.High, logger);
#if CLASSIC
#if !NETCOREAPP1_1
thread.TrySetPriority(ThreadPriority.Highest, logger);
#endif
if (affinity != null)
Expand All @@ -119,7 +119,7 @@ private int ExecuteCore(IHost host, Benchmark benchmark, ILogger logger)
finally
{
process.TrySetPriority(oldPriority, logger);
#if CLASSIC
#if !NETCOREAPP1_1
thread.TrySetPriority(oldThreadPriority, logger);
#endif
if (affinity != null && oldAffinity != null)
Expand Down
3 changes: 3 additions & 0 deletions src/BenchmarkDotNet.Disassembler.x64/Program.cs
Expand Up @@ -287,6 +287,9 @@ static string ReadSourceLine(string file, int line)
string[] contents;
if (!SourceFileCache.TryGetValue(file, out contents))
{
if (!File.Exists(file)) // sometimes the symbols report some disk location from MS CI machine like "E:\A\_work\308\s\src\mscorlib\shared\System\Random.cs" for .NET Core 2.0
return null;

contents = File.ReadAllLines(file);
SourceFileCache.Add(file, contents);
}
Expand Down
2 changes: 1 addition & 1 deletion src/BenchmarkDotNet/BenchmarkDotNet.csproj
Expand Up @@ -2,7 +2,7 @@
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<AssemblyTitle>BenchmarkDotNet</AssemblyTitle>
<TargetFrameworks>net46;netcoreapp1.1</TargetFrameworks>
<TargetFrameworks>net46;netcoreapp1.1;netcoreapp2.0</TargetFrameworks>
<NoWarn>$(NoWarn);1591</NoWarn>
<AssemblyName>BenchmarkDotNet</AssemblyName>
<PackageId>BenchmarkDotNet</PackageId>
Expand Down
Expand Up @@ -2,7 +2,7 @@
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<AssemblyTitle>BenchmarkDotNet.IntegrationTests</AssemblyTitle>
<TargetFrameworks>netcoreapp1.1;net46</TargetFrameworks>
<TargetFrameworks>netcoreapp1.1;net46;netcoreapp2.0</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyName>BenchmarkDotNet.IntegrationTests</AssemblyName>
<PackageId>BenchmarkDotNet.IntegrationTests</PackageId>
Expand Down Expand Up @@ -31,7 +31,7 @@
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.2.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' Or '$(TargetFramework)' == 'netcoreapp2.0' ">
<PackageReference Include="System.ComponentModel.EventBasedAsync" Version="4.3.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
Expand Down
@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.IntegrationTests.Xunit;
using BenchmarkDotNet.Jobs;
using Xunit;
using Xunit.Abstractions;

namespace BenchmarkDotNet.IntegrationTests
Expand All @@ -16,7 +16,9 @@ public EnvironmentVariablesTests(ITestOutputHelper output) : base(output)
{
}

[FactClassicDotNetOnly("ProcessStartInfo.EnvironmentVariables is avaialable for .NET Core 2.0+")]
#if !NETCOREAPP1_1 // ProcessStartInfo.EnvironmentVariables is avaialable for .NET Core 2.0+
[Fact]
#endif
public void UserCanSpecifyEnvironmentVariables()
{
var variables = new [] { new EnvironmentVariable(Key, Value) };
Expand Down
@@ -1,6 +1,7 @@
using System.Threading;
#if !NETCOREAPP1_1
using System.Threading;
using BenchmarkDotNet.Attributes;
#if !CORE
using BenchmarkDotNet.IntegrationTests.Xunit;
using Xunit;
using Xunit.Abstractions;

Expand All @@ -12,11 +13,8 @@ public ExtraAttributesForEntryMethodTests(ITestOutputHelper output) : base(outpu
{
}

[Fact]
public void UserCanMarkBenchmarkAsRequiringSTA()
{
CanExecute<RequiresSTA>();
}
[FactClassicDotNetOnly("STAThread attribute is not respected in netcoreapp https://github.com/dotnet/coreclr/issues/13688")]
public void UserCanMarkBenchmarkAsRequiringSTA() => CanExecute<RequiresSTA>();

public class RequiresSTA
{
Expand Down
4 changes: 2 additions & 2 deletions tests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj
Expand Up @@ -2,7 +2,7 @@
<Import Project="..\..\build\common.props" />
<PropertyGroup>
<AssemblyTitle>BenchmarkDotNet.Tests</AssemblyTitle>
<TargetFrameworks>netcoreapp1.1;net46</TargetFrameworks>
<TargetFrameworks>netcoreapp1.1;net46;netcoreapp2.0</TargetFrameworks>
<AssemblyName>BenchmarkDotNet.Tests</AssemblyName>
<PackageId>BenchmarkDotNet.Tests</PackageId>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
Expand All @@ -19,7 +19,7 @@
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.2.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' ">
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.1' Or '$(TargetFramework)' == 'netcoreapp2.0' ">
<PackageReference Include="System.ComponentModel.EventBasedAsync" Version="4.3.0" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
Expand Down
@@ -1,10 +1,9 @@
#if CLASSIC
#if !NETCOREAPP1_1
using System;
using System.Linq;
using System.Reflection.Emit;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Parameters;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Validators;
using Xunit;
Expand All @@ -19,7 +18,7 @@ public void BenchmarkedMethodNameMustNotContainWhitespaces()
Delegate method = BuildDummyMethod<int>("Has Some Whitespaces");

var parameters = new ValidationParameters(
new Benchmark[1]
new[]
{
new Benchmark(
new Target(
Expand Down

0 comments on commit 97ab49c

Please sign in to comment.