Skip to content

Instantly share code, notes, and snippets.

@seansaville
Created December 5, 2019 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seansaville/cdb4740e99d5ee3274d450259e3f0e42 to your computer and use it in GitHub Desktop.
Save seansaville/cdb4740e99d5ee3274d450259e3f0e42 to your computer and use it in GitHub Desktop.
Net48Tester - standalone program to reproduce https://github.com/dotnet/coreclr/issues/26990
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tester", "Tester/Tester.csproj", "{84C8A065-2217-4B26-B3F4-2E74743B7BD4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{84C8A065-2217-4B26-B3F4-2E74743B7BD4}.Debug|x64.ActiveCfg = Debug|x64
{84C8A065-2217-4B26-B3F4-2E74743B7BD4}.Debug|x64.Build.0 = Debug|x64
{84C8A065-2217-4B26-B3F4-2E74743B7BD4}.Release|x64.ActiveCfg = Release|x64
{84C8A065-2217-4B26-B3F4-2E74743B7BD4}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C40E391F-3C09-4FD4-8A55-F45198B5A21D}
EndGlobalSection
EndGlobal
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
namespace Net48Tester
{
internal class Program
{
public static int Main(string[] args)
{
try
{
using (var current = Process.GetCurrentProcess())
{
if (args.Contains("--child"))
{
Child(current);
}
else
{
Launcher(current);
}
}
return 0;
}
catch (Exception exception)
{
var color = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("ERROR: " + exception);
Console.ForegroundColor = color;
return 1;
}
}
/// <summary>
/// Launcher process: set CPU affinity to 1 core, then run sub-processes in a loop.
/// </summary>
private static void Launcher(Process current)
{
// Environment and runtime information.
var system = typeof(int).Assembly;
Console.WriteLine("Framework: Location: " + system.Location);
Console.WriteLine("Framework: ImageRuntimeVersion: " + system.ImageRuntimeVersion);
Console.WriteLine("Framework: full version: " + system.GetName().Version);
FileVersionInfo myFileVersionInfo = FileVersionInfo.GetVersionInfo(Assembly.GetAssembly(typeof(int)).GetFiles()[0].Name);
Console.WriteLine("Framework: ProductVersion: " + myFileVersionInfo.ProductVersion);
foreach (var module in current.Modules.Cast<ProcessModule>().Where(m => m.ModuleName.Contains("jit")))
{
Console.WriteLine("JIT Compiler: '{0}' {1}", module.ModuleName, module.FileVersionInfo.FileVersion);
}
// Change affinity mask.
Console.WriteLine($"Environment.ProcessorCount: {Environment.ProcessorCount}");
Console.WriteLine($"CPU affinity: {current.ProcessorAffinity.ToInt64():X16}");
current.ProcessorAffinity = new IntPtr(0x0000_0000_0000_0002);
Console.WriteLine($"New affinity: {current.ProcessorAffinity.ToInt64():X16}");
Console.WriteLine();
// Launch sub-processes.
for (var i = 0; i != 50; ++i)
{
var color = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Launching subprocess...");
Console.ForegroundColor = color;
using (var process = new Process
{
StartInfo =
{
#if NETCOREAPP2_1
FileName = "dotnet",
Arguments = "Net48Tester.dll --child",
#else
FileName = "Net48Tester.exe",
Arguments = "--child",
#endif
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
}
})
{
process.OutputDataReceived += ProcessOnOutputDataReceived;
process.ErrorDataReceived += ProcessOnOutputDataReceived;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
}
Console.WriteLine();
}
Console.WriteLine("Launcher completed");
}
private static void ProcessOnOutputDataReceived(object sender, DataReceivedEventArgs dataReceivedEventArgs)
{
if (dataReceivedEventArgs.Data != null)
{
Console.WriteLine(dataReceivedEventArgs.Data);
}
}
/// <summary>
/// Child process: set CPU affinity to N cores (from 1 core) and launch some Tasks.
/// </summary>
/// <param name="current"></param>
private static void Child(Process current)
{
Console.WriteLine($"CPU affinity: {current.ProcessorAffinity.ToInt64():X16}");
current.ProcessorAffinity = new IntPtr(0x0000_0000_0000_0FFF);
Console.WriteLine($"New affinity: {current.ProcessorAffinity.ToInt64():X16}");
Parallel.For(0, 10, i => Thread.Sleep(500));
Console.WriteLine("Child completed.");
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;netcoreapp3.0;netcoreapp2.1</TargetFrameworks>
<LangVersion>7.3</LangVersion>
<AssemblyName>Net48Tester</AssemblyName>
<RootNamespace>Net48Tester</RootNamespace>
<Platforms>x64</Platforms>
<PlatformTarget>x64</PlatformTarget>
<OutputType>Exe</OutputType>
</PropertyGroup>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment