Skip to content

Commit

Permalink
Fix critical finalization test (#75952)
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonLapounov authored Sep 22, 2022
1 parent e013f9d commit 82d76a4
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 55 deletions.

This file was deleted.

73 changes: 73 additions & 0 deletions src/tests/baseservices/finalization/CriticalFinalizer.cs
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
<OutputType>Exe</OutputType>
</PropertyGroup>
<ItemGroup>
<Compile Include="critical_finalization.cs" />
<Compile Include="CriticalFinalizer.cs" />
</ItemGroup>
</Project>
2 changes: 1 addition & 1 deletion src/tests/issues.targets
Original file line number Diff line number Diff line change
Expand Up @@ -3345,7 +3345,7 @@


<ItemGroup Condition=" '$(TargetArchitecture)' == 'wasm' " >
<ExcludeList Include="$(XunitTestBinBase)/baseservices/critical_finalization/critical_finalization/**">
<ExcludeList Include="$(XunitTestBinBase)/baseservices/finalization/CriticalFinalizer/**">
<Issue>https://github.com/dotnet/runtime/issues/75756</Issue>
</ExcludeList>
<ExcludeList Include="$(XunitTestBinBase)/JIT/Intrinsics/TypeIntrinsics_r/**">
Expand Down

0 comments on commit 82d76a4

Please sign in to comment.