Imported Upstream version 5.2.0.175

Former-commit-id: bb0468d0f257ff100aa895eb5fe583fb5dfbf900
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-06-07 13:16:24 +00:00
parent 4bdbaf4a88
commit 966bba02bb
8776 changed files with 346420 additions and 149650 deletions

View File

@@ -1,23 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
using System;
using System.Runtime.CompilerServices;
public class BringUpTest
{
const int Pass = 100;
const int Fail = -1;
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static int Add1(int x) { return x+1; }
public static int Main()
{
int y = Add1(1);
if (y == 2) return Pass;
else return Fail;
}
}

View File

@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
echo %~n0: pass
EXIT /b 0
) ELSE (
echo %~n0: fail
echo %~n0: fail - %ErrorCode%
EXIT /b 1
)
endlocal

View File

@@ -3,15 +3,70 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
class Program
{
public const int Pass = 100;
public const int Fail = -1;
static int Main()
{
SimpleReadWriteThreadStaticTest.Run(42, "SimpleReadWriteThreadStatic");
// TODO: After issue https://github.com/dotnet/corert/issues/2695 is fixed, move FinalizeTest to run at the end
if (FinalizeTest.Run() != Pass)
return Fail;
ThreadStaticsTestWithTasks.Run();
return 100;
if (ThreadTest.Run() != Pass)
return Fail;
return Pass;
}
public static bool IsRunnningOnWindows()
{
// Note: Environment.OSVersion is not yet available.
// This is a temporary hack that allows to skip Task related tests on Unix.
return System.IO.Path.DirectorySeparatorChar == '\\';
}
}
class FinalizeTest
{
public static bool visited = false;
public class Dummy
{
~Dummy()
{
FinalizeTest.visited = true;
}
}
public static int Run()
{
int iterationCount = 0;
while (!visited && iterationCount++ < 10000)
{
GC.KeepAlive(new Dummy());
GC.Collect();
}
if (visited)
{
Console.WriteLine("FinalizeTest passed");
return Program.Pass;
}
else
{
Console.WriteLine("FinalizeTest failed");
return Program.Fail;
}
}
}
@@ -108,6 +163,12 @@ class ThreadStaticsTestWithTasks
public static void Run()
{
if (!Program.IsRunnningOnWindows())
{
// Tasks are not supported on Unix yet
return;
}
Task[] tasks = new Task[TotalTaskCount];
for (int i = 0; i < tasks.Length; ++i)
{
@@ -137,3 +198,381 @@ class ThreadStaticsTestWithTasks
}
}
}
class ThreadTest
{
private static readonly List<Thread> s_startedThreads = new List<Thread>();
private static int s_passed;
private static int s_failed;
private static void Expect(bool condition, string message)
{
if (condition)
{
Interlocked.Increment(ref s_passed);
}
else
{
Interlocked.Increment(ref s_failed);
Console.WriteLine("ERROR: " + message);
}
}
private static void ExpectException<T>(Action action, string message)
{
Exception ex = null;
try
{
action();
}
catch (Exception e)
{
ex = e;
}
if (!(ex is T))
{
message += string.Format(" (caught {0})", (ex == null) ? "no exception" : ex.GetType().Name);
}
Expect(ex is T, message);
}
private static void ExpectPassed(string testName, int expectedPassed)
{
// Wait for all started threads to finish execution
foreach (Thread t in s_startedThreads)
{
t.Join();
}
s_startedThreads.Clear();
Expect(s_passed == expectedPassed, string.Format("{0}: Expected s_passed == {1}, got {2}", testName, expectedPassed, s_passed));
s_passed = 0;
}
private static void TestStartMethod()
{
// Case 1: new Thread(ThreadStart).Start()
var t1 = new Thread(() => Expect(true, "Expected t1 to start"));
t1.Start();
s_startedThreads.Add(t1);
// Case 2: new Thread(ThreadStart).Start(parameter)
var t2 = new Thread(() => Expect(false, "This thread must not be started"));
// InvalidOperationException: The thread was created with a ThreadStart delegate that does not accept a parameter.
ExpectException<InvalidOperationException>(() => t2.Start(null), "Expected InvalidOperationException for t2.Start()");
// Case 3: new Thread(ParameterizedThreadStart).Start()
var t3 = new Thread(obj => Expect(obj == null, "Expected obj == null"));
t3.Start();
s_startedThreads.Add(t3);
// Case 4: new Thread(ParameterizedThreadStart).Start(parameter)
var t4 = new Thread(obj => Expect((int)obj == 42, "Expected (int)obj == 42"));
t4.Start(42);
s_startedThreads.Add(t4);
// Start an unstarted resurrected thread.
// CoreCLR: ThreadStateException, CoreRT: no exception.
Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();
unstartedResurrected.Start();
s_startedThreads.Add(unstartedResurrected);
// Threads cannot started more than once
t1.Join();
ExpectException<ThreadStateException>(() => t1.Start(), "Expected ThreadStateException for t1.Start()");
ExpectException<ThreadStateException>(() => Thread.CurrentThread.Start(),
"Expected ThreadStateException for CurrentThread.Start()");
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
ExpectException<ThreadStateException>(() => stoppedResurrected.Start(),
"Expected ThreadStateException for stoppedResurrected.Start()");
ExpectPassed(nameof(TestStartMethod), 7);
}
private static void TestJoinMethod()
{
var t = new Thread(() => { });
ExpectException<InvalidOperationException>(() => t.Start(null), "Expected InvalidOperationException for t.Start()");
ExpectException<ThreadStateException>(() => t.Join(), "Expected ThreadStateException for t.Join()");
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
Expect(stoppedResurrected.Join(1), "Expected stoppedResurrected.Join(1) to return true");
Expect(!Thread.CurrentThread.Join(1), "Expected CurrentThread.Join(1) to return false");
ExpectPassed(nameof(TestJoinMethod), 4);
}
private static void TestCurrentThreadProperty()
{
Thread t = null;
t = new Thread(() => Expect(Thread.CurrentThread == t, "Expected CurrentThread == t on thread t"));
t.Start();
s_startedThreads.Add(t);
Expect(Thread.CurrentThread != t, "Expected CurrentThread != t on main thread");
ExpectPassed(nameof(TestCurrentThreadProperty), 2);
}
private static void TestNameProperty()
{
var t = new Thread(() => { });
t.Name = null;
// It is OK to set the null Name multiple times
t.Name = null;
Expect(t.Name == null, "Expected t.Name == null");
const string ThreadName = "My thread";
t.Name = ThreadName;
Expect(t.Name == ThreadName, string.Format("Expected t.Name == \"{0}\"", ThreadName));
ExpectException<InvalidOperationException>(() => { t.Name = null; },
"Expected InvalidOperationException setting Thread.Name back to null");
ExpectPassed(nameof(TestNameProperty), 3);
}
private static void TestIsBackgroundProperty()
{
if (!Program.IsRunnningOnWindows())
{
// This test uses tasks which are not supported on Unix yet
return;
}
// Thread created using Thread.Start
var t_event = new AutoResetEvent(false);
var t = new Thread(() => t_event.WaitOne());
t.Start();
s_startedThreads.Add(t);
Expect(!t.IsBackground, "Expected t.IsBackground == false");
t_event.Set();
t.Join();
ExpectException<ThreadStateException>(() => Console.WriteLine(t.IsBackground),
"Expected ThreadStateException for t.IsBackground");
// Thread pool thread
Task.Factory.StartNew(() => Expect(Thread.CurrentThread.IsBackground, "Expected IsBackground == true")).Wait();
// Resurrected threads
Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();
Expect(unstartedResurrected.IsBackground == false, "Expected unstartedResurrected.IsBackground == false");
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
ExpectException<ThreadStateException>(() => Console.WriteLine(stoppedResurrected.IsBackground),
"Expected ThreadStateException for stoppedResurrected.IsBackground");
// Main thread
Expect(!Thread.CurrentThread.IsBackground, "Expected CurrentThread.IsBackground == false");
ExpectPassed(nameof(TestIsBackgroundProperty), 6);
}
private static void TestIsThreadPoolThreadProperty()
{
#if false // The IsThreadPoolThread property is not in the contract version we compile against at present
var t = new Thread(() => { });
Expect(!t.IsThreadPoolThread, "Expected t.IsThreadPoolThread == false");
Task.Factory.StartNew(() => Expect(Thread.CurrentThread.IsThreadPoolThread, "Expected IsThreadPoolThread == true")).Wait();
Expect(!Thread.CurrentThread.IsThreadPoolThread, "Expected CurrentThread.IsThreadPoolThread == false");
ExpectPassed(nameof(TestIsThreadPoolThreadProperty), 3);
#endif
}
private static void TestManagedThreadIdProperty()
{
int t_id = 0;
var t = new Thread(() => {
Expect(Thread.CurrentThread.ManagedThreadId == t_id, "Expected CurrentTread.ManagedThreadId == t_id on thread t");
Expect(Environment.CurrentManagedThreadId == t_id, "Expected Environment.CurrentManagedThreadId == t_id on thread t");
});
t_id = t.ManagedThreadId;
Expect(t_id != 0, "Expected t_id != 0");
Expect(Thread.CurrentThread.ManagedThreadId != t_id, "Expected CurrentTread.ManagedThreadId != t_id on main thread");
Expect(Environment.CurrentManagedThreadId != t_id, "Expected Environment.CurrentManagedThreadId != t_id on main thread");
t.Start();
s_startedThreads.Add(t);
// Resurrected threads
Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();
Expect(unstartedResurrected.ManagedThreadId != 0, "Expected unstartedResurrected.ManagedThreadId != 0");
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
Expect(stoppedResurrected.ManagedThreadId != 0, "Expected stoppedResurrected.ManagedThreadId != 0");
ExpectPassed(nameof(TestManagedThreadIdProperty), 7);
}
private static void TestThreadStateProperty()
{
var t_event = new AutoResetEvent(false);
var t = new Thread(() => t_event.WaitOne());
Expect(t.ThreadState == ThreadState.Unstarted, "Expected t.ThreadState == ThreadState.Unstarted");
t.Start();
s_startedThreads.Add(t);
Expect(t.ThreadState == ThreadState.Running || t.ThreadState == ThreadState.WaitSleepJoin,
"Expected t.ThreadState is either ThreadState.Running or ThreadState.WaitSleepJoin");
t_event.Set();
t.Join();
Expect(t.ThreadState == ThreadState.Stopped, "Expected t.ThreadState == ThreadState.Stopped");
// Resurrected threads
Thread unstartedResurrected = Resurrector.CreateUnstartedResurrected();
Expect(unstartedResurrected.ThreadState == ThreadState.Unstarted,
"Expected unstartedResurrected.ThreadState == ThreadState.Unstarted");
Thread stoppedResurrected = Resurrector.CreateStoppedResurrected();
Expect(stoppedResurrected.ThreadState == ThreadState.Stopped,
"Expected stoppedResurrected.ThreadState == ThreadState.Stopped");
ExpectPassed(nameof(TestThreadStateProperty), 5);
}
private static unsafe void DoStackAlloc(int size)
{
byte* buffer = stackalloc byte[size];
Volatile.Write(ref buffer[0], 0);
}
private static void TestMaxStackSize()
{
#if false // The constructors with maxStackSize are not in the contract version we compile against at present
// Allocate a 3 MiB buffer on the 4 MiB stack
var t = new Thread(() => DoStackAlloc(3 << 20), 4 << 20);
t.Start();
s_startedThreads.Add(t);
#endif
ExpectPassed(nameof(TestMaxStackSize), 0);
}
static int s_startedThreadCount = 0;
private static void TestStartShutdown()
{
Thread[] threads = new Thread[2048];
// Creating a large number of threads
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(() => { Interlocked.Increment(ref s_startedThreadCount); });
threads[i].Start();
}
// Wait for all threads to shutdown;
for (int i = 0; i < threads.Length; i++)
{
threads[i].Join();
}
Expect(s_startedThreadCount == threads.Length,
String.Format("Not all threads completed. Expected: {0}, Actual: {1}", threads.Length, s_startedThreadCount));
}
public static int Run()
{
TestStartMethod();
TestJoinMethod();
TestCurrentThreadProperty();
TestNameProperty();
TestIsBackgroundProperty();
TestIsThreadPoolThreadProperty();
TestManagedThreadIdProperty();
TestThreadStateProperty();
TestMaxStackSize();
TestStartShutdown();
return (s_failed == 0) ? Program.Pass : Program.Fail;
}
/// <summary>
/// Creates resurrected Thread objects.
/// </summary>
class Resurrector
{
static Thread s_unstartedResurrected;
static Thread s_stoppedResurrected;
bool _unstarted;
Thread _thread = new Thread(() => { });
Resurrector(bool unstarted)
{
_unstarted = unstarted;
if (!unstarted)
{
_thread.Start();
_thread.Join();
}
}
~Resurrector()
{
if (_unstarted && (s_unstartedResurrected == null))
{
s_unstartedResurrected = _thread;
}
else if(!_unstarted && (s_stoppedResurrected == null))
{
s_stoppedResurrected = _thread;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void CreateInstance(bool unstarted)
{
GC.KeepAlive(new Resurrector(unstarted));
}
static Thread CreateResurrectedThread(ref Thread trap, bool unstarted)
{
trap = null;
while (trap == null)
{
// Call twice to override the address of the first allocation on the stack (for conservative GC)
CreateInstance(unstarted);
CreateInstance(unstarted);
GC.Collect();
GC.WaitForPendingFinalizers();
}
// We would like to get a Thread object with its internal SafeHandle member disposed.
// The current implementation of SafeHandle postpones disposing until the next garbage
// collection. For this reason we do a couple more collections.
for (int i = 0; i < 2; i++)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
return trap;
}
public static Thread CreateUnstartedResurrected()
{
return CreateResurrectedThread(ref s_unstartedResurrected, unstarted: true);
}
public static Thread CreateStoppedResurrected()
{
return CreateResurrectedThread(ref s_stoppedResurrected, unstarted: false);
}
}
}

0
external/corert/tests/src/Simple/BasicThreading/BasicThreading.sh vendored Normal file → Executable file
View File

View File

@@ -1,9 +1,5 @@
<Project ToolsVersion="14.0" DefaultTargets="BuildAllFrameworkLibraries" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<NativeIntermediateOutputPath>$(MSBuildProjectDirectory)\obj\$(Configuration)\native\</NativeIntermediateOutputPath>
</PropertyGroup>
<Import Project="..\..\..\..\src\BuildIntegration\BuildFrameworkNativeObjects.proj" />
</Project>

View File

@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
echo %~n0: pass
EXIT /b 0
) ELSE (
echo %~n0: fail
echo %~n0: fail - %ErrorCode%
EXIT /b 1
)
endlocal

View File

@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
echo %~n0: pass
EXIT /b 0
) ELSE (
echo %~n0: fail
echo %~n0: fail - %ErrorCode%
EXIT /b 1
)
endlocal

View File

@@ -1,29 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
internal class Program
{
private static int Main(string[] args)
{
string s123 = 123.ToString();
if (s123 != "123")
{
Console.WriteLine("Unexpected: " + s123);
return 1;
}
string s123dot5 = (123.5).ToString(CultureInfo.InvariantCulture);
if (s123dot5 != "123.5")
{
Console.WriteLine("Unexpected: " + s123dot5);
return 1;
}
Console.WriteLine("{0}", "Hi");
return 100;
}
}

View File

@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
echo %~n0: pass
EXIT /b 0
) ELSE (
echo %~n0: fail
echo %~n0: fail - %ErrorCode%
EXIT /b 1
)
endlocal

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ IF "%ErrorCode%"=="0" (
echo %~n0: pass
EXIT /b 0
) ELSE (
echo %~n0: fail
echo %~n0: fail - %ErrorCode%
EXIT /b 1
)
endlocal

View File

@@ -6,7 +6,7 @@ IF "%ErrorCode%"=="100" (
echo %~n0: pass
EXIT /b 0
) ELSE (
echo %~n0: fail
echo %~n0: fail - %ErrorCode%
EXIT /b 1
)
endlocal

View File

@@ -25,6 +25,9 @@ public class BringUpTest
if (TestVariantInterfaces() == Fail)
return Fail;
if (TestSpecialArrayInterfaces() == Fail)
return Fail;
return Pass;
}
@@ -337,5 +340,23 @@ public class BringUpTest
return Pass;
}
class SpecialArrayBase { }
class SpecialArrayDerived : SpecialArrayBase { }
// NOTE: ICollection is not a variant interface, but arrays can cast with it as if it was
static ICollection<SpecialArrayBase> s_specialDerived = new SpecialArrayDerived[42];
static ICollection<uint> s_specialInt = (ICollection<uint>)(object)new int[85];
private static int TestSpecialArrayInterfaces()
{
if (s_specialDerived.Count != 42)
return Fail;
if (s_specialInt.Count != 85)
return Fail;
return Pass;
}
#endregion
}

View File

@@ -0,0 +1,67 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
public class MultiModuleLibrary
{
// Do not reference these three (3) statics in this assembly.
// We're testing that statics in library code are rooted for use by consuming application code.
public static int ReturnValue;
public static string StaticString;
[ThreadStatic]
public static int ThreadStaticInt;
public static bool MethodThatUsesGenerics()
{
// Force the existence of a generic dictionary for GenericClass<string>
// It's important we only use one canonical method and that method is not used from the consumption EXE.
if (GenericClass<string>.IsArrayOfT(null))
return false;
if (!GenericClass<string>.IsArrayOfT(new string[0]))
return false;
// Force the existence of a generic dictionary for GenericClass<GenericStruct<string>>
// Here we test a canonical method that will be used from the consumption EXE too.
if (!GenericClass<GenericStruct<string>>.IsT(new GenericStruct<string>()))
return false;
return true;
}
public class GenericClass<T>
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static bool IsT(object o) => o is T;
[MethodImpl(MethodImplOptions.NoInlining)]
public static bool IsArrayOfT(object o) => o is T[];
[MethodImpl(MethodImplOptions.NoInlining)]
public static bool IsMdArrayOfT(object o) => o is T[,];
}
public struct GenericStruct<T>
{
public T Value;
}
public class GenericClassWithTLS<T>
{
[ThreadStatic]
public static int ThreadStaticInt;
}
public static bool MethodThatUsesGenericWithTLS()
{
GenericClassWithTLS<int>.ThreadStaticInt += 1;
return GenericClassWithTLS<int>.ThreadStaticInt == 1;
}
public enum MyEnum
{
One, Two
}
}

View File

@@ -0,0 +1,10 @@
<Project DefaultTargets="Build;IlcCompile" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>Library</OutputType>
<IlcMultiModule>true</IlcMultiModule>
</PropertyGroup>
<ItemGroup>
<Compile Include="Library.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), SimpleTest.targets))\SimpleTest.targets" />
</Project>

View File

@@ -0,0 +1,91 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
public class ReflectionTest
{
const int Pass = 100;
const int Fail = -1;
public static int Main()
{
if (TestStaticBases() == Fail)
return Fail;
if (TestSharedGenerics() == Fail)
return Fail;
if (TestGenericTLS() == Fail)
return Fail;
if (TestInjectedEnumMethods() == Fail)
return Fail;
return Pass;
}
public static int TestStaticBases()
{
Console.WriteLine("Testing static bases in library code are available..");
MultiModuleLibrary.ReturnValue = 50;
MultiModuleLibrary.ThreadStaticInt = 50;
MultiModuleLibrary.StaticString = MultiModuleLibrary.ReturnValue.ToString() + MultiModuleLibrary.ThreadStaticInt.ToString();
if (MultiModuleLibrary.StaticString != "5050")
return Fail;
if (MultiModuleLibrary.ReturnValue + MultiModuleLibrary.ThreadStaticInt != 100)
return Fail;
return Pass;
}
public static int TestSharedGenerics()
{
Console.WriteLine("Testing generic dictionaries can be folded properly..");
// Use a generic dictionary that also exists in the library
if (!MultiModuleLibrary.GenericClass<string>.IsT("Hello"))
return Fail;
if (!MultiModuleLibrary.GenericClass<string>.IsMdArrayOfT(new string[0, 0]))
return Fail;
if (!MultiModuleLibrary.GenericClass<MultiModuleLibrary.GenericStruct<string>>.IsArrayOfT(new MultiModuleLibrary.GenericStruct<string>[0]))
return Fail;
if (!MultiModuleLibrary.GenericClass<MultiModuleLibrary.GenericStruct<string>>.IsT(new MultiModuleLibrary.GenericStruct<string>()))
return Fail;
if (!MultiModuleLibrary.MethodThatUsesGenerics())
return Fail;
return Pass;
}
public static int TestGenericTLS()
{
Console.WriteLine("Testing thread statics on generic types shared between modules are shared properly..");
if (!MultiModuleLibrary.MethodThatUsesGenericWithTLS())
return Fail;
MultiModuleLibrary.GenericClassWithTLS<int>.ThreadStaticInt += 1;
if (MultiModuleLibrary.GenericClassWithTLS<int>.ThreadStaticInt != 2)
return Fail;
return Pass;
}
public static int TestInjectedEnumMethods()
{
Console.WriteLine("Testing context-injected methods on enums..");
if (!MultiModuleLibrary.MyEnum.One.Equals(MultiModuleLibrary.MyEnum.One))
return Fail;
return Pass;
}
}

View File

@@ -1,7 +1,16 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<IlcMultiModule>true</IlcMultiModule>
</PropertyGroup>
<ItemGroup>
<Compile Include="*.cs" />
<Compile Include="MultiModule.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="Library.csproj" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), SimpleTest.targets))\SimpleTest.targets" />
</Project>

Some files were not shown because too many files have changed in this diff Show More