提交 15a167bd 编写于 作者: V Vladimir Sadov 提交者: GitHub

Merge pull request dotnet/coreclr#23325 from VSadov/CmpExchA64

Resolve 22303   (interlocked failures on ARM64)

Commit migrated from https://github.com/dotnet/coreclr/commit/e5bfd7d89ad0704a23545ac1e6d6a80918e2dbe5
......@@ -571,24 +571,6 @@
<ExcludeList Include="$(XunitTestBinBase)/GC/Scenarios/Dynamo/dynamo/*">
<Issue>17129</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/baseservices/threading/interlocked/compareexchange/CompareExchangeTClass/*">
<Issue>22303</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/baseservices/threading/interlocked/compareexchange/CompareExchangeTClass_1/*">
<Issue>22303</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/baseservices/threading/interlocked/exchange/ExchangeTClass/*">
<Issue>22303</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/baseservices/threading/interlocked/exchange/ExchangeTString/*">
<Issue>22303</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/baseservices/threading/interlocked/exchange/ExchangeTString_1/*">
<Issue>22303</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/baseservices/threading/interlocked/exchange/ExchangeTString_2/*">
<Issue>22303</Issue>
</ExcludeList>
</ItemGroup>
<!-- Unix arm32 specific -->
......
......@@ -10,7 +10,7 @@
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CLRTestExecutionArguments>null</CLRTestExecutionArguments>
<CLRTestExecutionArguments>""</CLRTestExecutionArguments>
<CLRTestPriority>1</CLRTestPriority>
<GCStressIncompatible>true</GCStressIncompatible>
</PropertyGroup>
......
......@@ -12,7 +12,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CLRTestKind>BuildAndRun</CLRTestKind>
<CLRTestPriority>1</CLRTestPriority>
<CLRTestExecutionArguments>empty</CLRTestExecutionArguments>
<CLRTestExecutionArguments>"hello"</CLRTestExecutionArguments>
</PropertyGroup>
<!-- Default configurations to help VS understand the configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
......
......@@ -25,15 +25,15 @@ static int Main(string[] args)
tsi.Signal();
Console.WriteLine("Joining threads");
for(int i=0;i<threads.Length;i++)
for (int i = 0; i < threads.Length; i++)
threads[i].Join();
// Build the expected string
KrisClass kcExpected = new KrisClass("hello world! ");
for(int i=0;i<threads.Length * 100;i++)
for (int i = 0; i < threads.Length * 100; i++)
kcExpected = kcExpected + kcIn;
if(kcExpected == tsi.GetValue)
if (kcExpected == tsi.GetValue)
rValue = 100;
Console.WriteLine("Test Expected {0}, but found {1}", kcExpected, tsi.GetValue);
Console.WriteLine("Test {0}", rValue == 100 ? "Passed" : "Failed");
......@@ -46,7 +46,7 @@ public class ThreadSafe
ManualResetEvent signal;
public KrisClass Val = new KrisClass("hello world! ");
private int numberOfIterations;
public ThreadSafe(): this(100) { }
public ThreadSafe() : this(100) { }
public ThreadSafe(int loops)
{
signal = new ManualResetEvent(false);
......@@ -62,21 +62,23 @@ public void ThreadWorker(Object objIn)
{
KrisClass kcIn = (KrisClass)objIn;
signal.WaitOne();
for(int i=0;i<numberOfIterations;i++)
for (int i = 0; i < numberOfIterations; i++)
AddToTotal(kcIn);
}
private KrisClass AddToTotal(KrisClass addend)
{
KrisClass initialValue = new KrisClass(string.Empty);
KrisClass newValue = new KrisClass(string.Empty);
KrisClass initialValue;
KrisClass newValue;
do
{
initialValue = Val;
newValue = initialValue + addend;
}
while (initialValue != Interlocked.CompareExchange<KrisClass>(
while ((object)initialValue != Interlocked.CompareExchange<KrisClass>(
ref Val, newValue, initialValue));
return newValue;
}
......@@ -112,7 +114,7 @@ public string ClassVal
public static bool operator ==(KrisClass kc1, KrisClass kc2)
{
if(kc1.ClassVal == kc2.ClassVal)
if (kc1.ClassVal == kc2.ClassVal)
return true;
else
return false;
......@@ -120,7 +122,7 @@ public string ClassVal
public static bool operator !=(KrisClass kc1, KrisClass kc2)
{
if(kc1.ClassVal != kc2.ClassVal)
if (kc1.ClassVal != kc2.ClassVal)
return true;
else
return false;
......@@ -130,7 +132,7 @@ public override bool Equals(object o)
{
try
{
return (bool) (this == (KrisClass) o);
return (bool)(this == (KrisClass)o);
}
catch
{
......
......@@ -95,8 +95,9 @@ private string AddToTotal(string addend)
initialValue = Val;
newValue = initialValue + addend;
}
while (initialValue != Interlocked.CompareExchange<string>(
while ((object)initialValue != Interlocked.CompareExchange<string>(
ref Val, newValue, initialValue));
return newValue;
}
}
......@@ -30,12 +30,6 @@ static int Main(string[] args)
threads[threads.Length - 1] = new Thread(new ThreadStart(tsi.ThreadChecker));
threads[threads.Length - 1].Start();
//Added to prevent races where Checker does not get to Wait before ManualEvent is Set
while(tsi.ThreadCount < 100)
{
Thread.Sleep(100);
}
Thread.Sleep(100);
tsi.Signal();
Console.WriteLine("Joining threads");
......@@ -57,11 +51,8 @@ public class ThreadSafe
private string newValueA = "hello";
private string newValueB = "world";
private bool success;
public volatile int ThreadCount = 0;
private volatile static object syncroot = new object();
public ThreadSafe(): this(10000) { }
public ThreadSafe() : this(10000) { }
public ThreadSafe(int loops)
{
......@@ -81,28 +72,23 @@ public void ThreadWorkerA(object obj)
string ret = null;
// get the value
if(0 < str.Length)
if (0 < str.Length)
{
if("null" == str[0])
if ("null" == str[0])
newValueA = null;
else if("empty" == str[0])
else if ("empty" == str[0])
newValueA = string.Empty;
else
newValueA = str[0];
}
lock(syncroot)
{
ThreadCount++;
}
signal.WaitOne();
for (int i = 0; i < numberOfIterations; i++)
{
ret = Interlocked.Exchange<string>(ref curVal, newValueA);
// Check return value
if(ret != newValueB && ret != newValueA && ret != "start string")
if (ret != newValueB && ret != newValueA && ret != "start string")
{
Console.WriteLine(ret + "," + newValueB + "," + newValueA);
success = false;
......@@ -117,28 +103,24 @@ public void ThreadWorkerB(object obj)
string ret = null;
// get the value
if(2 == str.Length)
if (2 == str.Length)
{
if("null" == str[1])
if ("null" == str[1])
newValueB = null;
else if("empty" == str[1])
else if ("empty" == str[1])
newValueB = string.Empty;
else
newValueB = str[1];
}
lock(syncroot)
{
ThreadCount++;
}
signal.WaitOne();
for (int i = 0; i < numberOfIterations; i++)
{
ret = Interlocked.Exchange<string>(ref curVal, newValueB);
// Check return value
if(ret != newValueB && ret != newValueA && ret != "start string")
if (ret != newValueB && ret != newValueA && ret != "start string")
{
Console.WriteLine(ret + "," + newValueB + "," + newValueA);
success = false;
......@@ -148,17 +130,18 @@ public void ThreadWorkerB(object obj)
public void ThreadChecker()
{
lock(syncroot)
signal.WaitOne();
while(curVal == "start string")
{
ThreadCount++;
Thread.Sleep(0);
}
signal.WaitOne();
string tmpVal;
for (int i = 0; i < numberOfIterations; i++)
{
tmpVal = curVal;
if (tmpVal != newValueB && tmpVal != newValueA && tmpVal != "start string")
if (tmpVal != newValueB && tmpVal != newValueA)
{
Console.WriteLine(tmpVal + "," + newValueB + "," + newValueA);
success = false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册