Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable finalizer events for EventPipe #88604

Merged
merged 2 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ internal static extern unsafe IntPtr RhpCallPropagateExceptionCallback(
// Indicate that the current round of finalizations is complete.
[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
internal static extern void RhpSignalFinalizationComplete();
internal static extern void RhpSignalFinalizationComplete(uint fCount);

[DllImport(Redhawk.BaseName)]
[UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ public static void ProcessFinalizers()
// otherwise memory is low and we should initiate a collection.
if (InternalCalls.RhpWaitForFinalizerRequest() != 0)
{
DrainQueue();
uint fCount = DrainQueue();

// Tell anybody that's interested that the finalization pass is complete (there is a race condition here
// where we might immediately signal a new request as complete, but this is acceptable).
InternalCalls.RhpSignalFinalizationComplete();
InternalCalls.RhpSignalFinalizationComplete(fCount);
}
else
{
Expand All @@ -48,14 +48,16 @@ public static void ProcessFinalizers()
// objects that came off of the finalizer queue. If such temps were reported across the duration of the
// finalizer thread wait operation, it could cause unpredictable behavior with weak handles.
[MethodImpl(MethodImplOptions.NoInlining)]
private static unsafe void DrainQueue()
private static unsafe uint DrainQueue()
{
uint fCount = 0;
LakshanF marked this conversation as resolved.
Show resolved Hide resolved
// Drain the queue of finalizable objects.
while (true)
{
object target = InternalCalls.RhpGetNextFinalizableObject();
if (target == null)
return;
return fCount;
fCount++;
LakshanF marked this conversation as resolved.
Show resolved Hide resolved

// Call the finalizer on the current target object. If the finalizer throws we'll fail
// fast via normal Redhawk exception semantics (since we don't attempt to catch
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/nativeaot/Runtime/FinalizerHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhpWaitForFinalizerRequest()
pWork = pNext;
}
}
FireEtwGCFinalizersBegin_V1(GetClrInstanceId());
return TRUE;

case WAIT_OBJECT_0 + 1:
Expand All @@ -182,8 +183,9 @@ EXTERN_C NATIVEAOT_API UInt32_BOOL __cdecl RhpWaitForFinalizerRequest()
}

// Indicate that the current round of finalizations is complete.
EXTERN_C NATIVEAOT_API void __cdecl RhpSignalFinalizationComplete()
EXTERN_C NATIVEAOT_API void __cdecl RhpSignalFinalizationComplete(uint32_t fcount)
{
FireEtwGCFinalizersEnd_V1(fcount, GetClrInstanceId());
g_FinalizerDoneEvent.Set();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ public static int Main()
//ExceptionKeyword (0x8000): 0b1000_0000_0000_0000
new List<EventPipeProvider>(){new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Warning, 0b1000_0000_0000_0000)},
1024, _DoesTraceContainExceptionEvents, enableRundownProvider:false);

if(ret == 100)
{
ret = IpcTraceTest.RunAndValidateEventCounts(
new Dictionary<string, ExpectedEventCount>(){{ "Microsoft-Windows-DotNETRuntime", -1}},
_eventGeneratingActionForFinalizers,
new List<EventPipeProvider>(){new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Informational, 0b1)},
1024, _DoesTraceContainFinazlierEvents, enableRundownProvider:false);
}
}

if (ret < 0)
Expand Down Expand Up @@ -73,6 +82,21 @@ public static int Main()
}
};

private static Action _eventGeneratingActionForFinalizers = () =>
{
for (int i = 0; i < 50; i++)
{
if (i % 10 == 0)
Logger.logger.Log($"Called GC.WaitForPendingFinalizers() {i} times...");
RuntimeEventValidation providerValidation = new RuntimeEventValidation();
providerValidation = null;
LakshanF marked this conversation as resolved.
Show resolved Hide resolved
GC.WaitForPendingFinalizers();
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
};

private static Func<EventPipeEventSource, Func<int>> _DoesTraceContainGCEvents = (source) =>
{
int GCStartEvents = 0;
Expand Down Expand Up @@ -129,5 +153,19 @@ public static int Main()
return ExStartResult ? 100 : -1;
};
};

private static Func<EventPipeEventSource, Func<int>> _DoesTraceContainFinazlierEvents = (source) =>
LakshanF marked this conversation as resolved.
Show resolved Hide resolved
{
int GCFinalizersEndEvents = 0;
source.Clr.GCFinalizersStop += (eventData) => GCFinalizersEndEvents += 1;
int GCFinalizersStartEvents = 0;
source.Clr.GCFinalizersStart += (eventData) => GCFinalizersStartEvents += 1;
return () => {
Logger.logger.Log("Event counts validation");
Logger.logger.Log("GCFinalizersEndEvents: " + GCFinalizersEndEvents);
Logger.logger.Log("GCFinalizersStartEvents: " + GCFinalizersStartEvents);
return GCFinalizersEndEvents >= 50 && GCFinalizersStartEvents >= 50 ? 100 : -1;
};
};
}
}
Loading