diff --git a/src/tests/baseservices/critical_finalization/critical_finalization.cs b/src/tests/baseservices/critical_finalization/critical_finalization.cs deleted file mode 100644 index 553ccfc5a1b954..00000000000000 --- a/src/tests/baseservices/critical_finalization/critical_finalization.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Runtime.ConstrainedExecution; - -class P { - - static public int count = 0; - - ~P () { - count++; - } -} - -class Q : CriticalFinalizerObject { - static public int count = 0; - static public int first_p_count = -1; - static public int last_p_count = 0; - ~Q () { - count++; - if (first_p_count < 0) - first_p_count = P.count; - last_p_count = P.count; - } -} - -class T : P { - - static void makeP () { - P p = new P (); - Q q = new Q (); - p = null; - q = null; - } - - static void callMakeP () { - makeP (); - } - - static int Main () { - for (int i = 0; i < 100; ++i) - callMakeP (); - GC.Collect (); - GC.WaitForPendingFinalizers (); - Console.WriteLine (P.count); - Console.WriteLine (Q.count); - Console.WriteLine (Q.first_p_count); - Console.WriteLine (Q.last_p_count); - if (P.count == 0) - return 1; - if (Q.first_p_count < P.count) - return 1; - return 100; - } -} diff --git a/src/tests/baseservices/finalization/CriticalFinalizer.cs b/src/tests/baseservices/finalization/CriticalFinalizer.cs new file mode 100644 index 00000000000000..9ea7d56d881a87 --- /dev/null +++ b/src/tests/baseservices/finalization/CriticalFinalizer.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Tests the weak ordering among normal and critical finalizers: for objects reclaimed by garbage collection +// at the same time, all the noncritical finalizers must be called before any of the critical finalizers. + +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.ConstrainedExecution; +using System.Threading.Tasks; + +class Normal +{ + public static int Finalized; + + ~Normal() => Finalized++; +} + +class Critical : CriticalFinalizerObject +{ + public static int Finalized; + public static int NormalFinalizedBeforeFirstCritical; + + ~Critical() + { + if (++Finalized == 1) + NormalFinalizedBeforeFirstCritical = Normal.Finalized; + } +} + +static class CriticalFinalizerTest +{ + [MethodImpl(MethodImplOptions.NoInlining)] + static void AllocateObjects(int count) + { + var arr = new object[checked(count * 2)]; + + Parallel.For(0, count, i => + { + arr[i * 2] = new Normal(); + arr[i * 2 + 1] = new Critical(); + }); + + GC.KeepAlive(arr); + } + + static int Main() + { + const int Count = 100; + + // Allocate a bunch of Normal and Critical objects, then unroot them + AllocateObjects(Count); + + // Force a garbage collection and wait until all finalizers are executed + GC.Collect(); + GC.WaitForPendingFinalizers(); + + // Check that all Normal objects were finalized before all Critical objects + int normalFinalized = Normal.Finalized; + int criticalFinalized = Critical.Finalized; + int normalFinalizedBeforeFirstCritical = Critical.NormalFinalizedBeforeFirstCritical; + + if (normalFinalized != Count || criticalFinalized != Count || normalFinalizedBeforeFirstCritical != Count) + { + Console.WriteLine($"Finalized {normalFinalized} {nameof(Normal)} and {criticalFinalized} {nameof(Critical)} objects."); + Console.WriteLine($"The first {nameof(Critical)} object was finalized after {normalFinalizedBeforeFirstCritical} {nameof(Normal)} objects."); + return 101; + } + + return 100; + } +} diff --git a/src/tests/baseservices/critical_finalization/critical_finalization.csproj b/src/tests/baseservices/finalization/CriticalFinalizer.csproj similarity index 73% rename from src/tests/baseservices/critical_finalization/critical_finalization.csproj rename to src/tests/baseservices/finalization/CriticalFinalizer.csproj index 295bb31a5f70ce..d83ad37e49f1d7 100644 --- a/src/tests/baseservices/critical_finalization/critical_finalization.csproj +++ b/src/tests/baseservices/finalization/CriticalFinalizer.csproj @@ -3,6 +3,6 @@ Exe - + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 8653f6e609172b..e6de4c3c83f152 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -3345,7 +3345,7 @@ - + https://github.com/dotnet/runtime/issues/75756