Skip to content

Commit

Permalink
Modify the test case Runtime_40444.cs (#40951) (#45431)
Browse files Browse the repository at this point in the history
* Modify the test case Runtime_40444.cs
1) Increase the maximum loop count for failure to 1000 million
2) Added additional computation inside of loop
3) Add addition message when the loop executes to the limit and the test case fails

Updated test case and insured that it fails on JITS without the fix
Test now checks it the other thread set t2_finished

* Re-enable the Runtime_40444 test

* Fix typos
  • Loading branch information
briansull authored Dec 3, 2020
1 parent b02e13a commit 2ee13ec
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 17 deletions.
3 changes: 0 additions & 3 deletions src/coreclr/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@
<ExcludeList Include="$(XunitTestBinBase)/GC/Scenarios/muldimjagary/muldimjagary/*">
<Issue>https://github.com/dotnet/runtime/issues/5933</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/Runtime_40444/*">
<Issue>https://github.com/dotnet/runtime/issues/40885</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/Loader/classloader/generics/Variance/Methods/Method002/*">
<Issue>https://github.com/dotnet/runtime/issues/3893</Issue>
</ExcludeList>
Expand Down
116 changes: 102 additions & 14 deletions src/tests/JIT/Regression/JitBlue/Runtime_40444/Runtime_40444.cs
Original file line number Diff line number Diff line change
@@ -1,66 +1,154 @@

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

class Runtime_40444
{

public static int t2_result = 0;
public static int t2_result;

public static int t2_finished;

public static int s_divisor;

static void Thread2()
{
t2_result++;
t2_finished = 1;
}

// [MethodImpl(MethodImplOptions.NoInlining)]
static int TestVolatileRead(ref int address)
{
int ret = address;
Thread.MemoryBarrier(); // Call MemoryBarrier to ensure the proper semantic in a portable way.
return ret;
}

static bool Test()
static bool Test(ref bool result)
{
bool result = false;
int loc_finished;
t2_finished = 0;

// Run Thread2() in a new thread
new Thread(new ThreadStart(Thread2)).Start();

// Wait for Thread2 to signal that it has a result by setting
//
//Wait for Thread2 to signal that it has a result by setting
// t2_finished to 1.
for (int i=0; i<10000000; i++)
//
// We wait by performing this loop 1000 million times
//
// It is important that we have no calls in the loop
// and that the JIT inlines the method TestVolatileRead
//
//
int i = 0;
int divisor = s_divisor;
for (; ; )
{
if (TestVolatileRead(ref t2_finished)==1)
{
Console.WriteLine("{1}: result = {0}", t2_result, i);
// The value was changed by Thread2
// We print out how many iterations we looped for and
// return true
Console.WriteLine("{0}: t2_result = {1}", i, t2_result);
result = true;

// The other thread has run and we just saw the value of
// t2_finished change so we return true and pass the test
//
return true;
}

i++;

// Integer division is somewhat expensive and will add additional
// time for this loop to execute
//
// Chain the two divides so the processor can't hide the latency
//
if (((i / divisor) / divisor) == 1)
{
divisor++;
}

if (i == 1000000000) // 1000 million
{
loc_finished = t2_finished;
break;
}
}
if (result == false)

// If loc_finished is still zero then the other thread has never run
// then we need to retry this test.
//
if (loc_finished == 0)
{
// We will return false,
// this means that we couldn't tell if the test failed
//
return false;
}
else
{
Console.WriteLine("FAILED");
// If we count up to 1000 million and we complete the loop
// then we fail this test.
//
// Without the fix to the JIT we hoisted the read out of
// the loop and we would always reach here.
//
Console.WriteLine("{0}: FAILED, t2_result = {1}, t2_finished is {2}", i, t2_result, t2_finished);

// The other thread has run and we never saw the value of t2_finsihed change
// so we return true and fail the test
//
result = false;
return true;
}
return result;
}

static int Main()
{
bool passes_test = false;
bool test_result = false;

for (int i=0; i<100; i++)
{
if (!Test())
t2_result = 0;
s_divisor = 1000000;

// Test returns true when it is able to determine pass or fail
// and it sets passes_test to true when it passes
//

test_result = Test(ref passes_test);
if (test_result)
{
break;
}
}

if (passes_test)
{
Console.WriteLine("Passed");
return 100;
}
else
{
if (test_result)
{
Console.WriteLine("FAILED");
return -1;
}
else
{
Console.WriteLine("Unable to determine");
return 101;
}
}
Console.WriteLine("Passed");
return t2_result;
}
}

0 comments on commit 2ee13ec

Please sign in to comment.