From 4eef872d025befa77d3d015c84111ec703ccb855 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Wed, 20 Apr 2022 09:44:16 -0700 Subject: [PATCH 1/7] GetTotalPauseDuration implementation --- .../src/System/GC.CoreCLR.cs | 8 ++++++++ src/coreclr/gc/gc.cpp | 5 +++++ src/coreclr/gc/gcimpl.h | 5 ++++- src/coreclr/gc/gcinterface.h | 4 ++++ src/coreclr/nativeaot/Runtime/GCHelpers.cpp | 5 +++++ .../src/System/GC.NativeAot.cs | 5 +++++ .../src/System/Runtime/RuntimeImports.cs | 4 ++++ .../src/System/Runtime/RuntimeImports.cs | 3 +++ src/coreclr/vm/comutilnative.cpp | 15 +++++++++++++++ src/coreclr/vm/comutilnative.h | 2 +- src/coreclr/vm/ecalllist.h | 1 + .../System.Runtime/ref/System.Runtime.cs | 1 + .../System.Private.CoreLib/src/System/GC.Mono.cs | 5 +++++ 13 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs index 382b5cc4d340e4..d6474dcc8c83d3 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs @@ -711,5 +711,13 @@ public static T[] AllocateArray(int length, bool pinned = false) // T[] rathe return Unsafe.As(AllocateNewArray(typeof(T[]).TypeHandle.Value, length, flags)); } + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern long _GetTotalPauseDuration(); + + public static TimeSpan GetTotalPauseDuration() + { + return new TimeSpan(_GetTotalPauseDuration()); + } } } diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index d291743679238a..30caa8be6609ba 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -46323,6 +46323,11 @@ void GCHeap::GetMemoryInfo(uint64_t* highMemLoadThresholdBytes, #endif //_DEBUG } +uint64_t GCHeap::GetTotalPauseDuration() +{ + return gc_heap::total_suspended_time; +} + uint32_t GCHeap::GetMemoryLoad() { uint32_t memory_load = 0; diff --git a/src/coreclr/gc/gcimpl.h b/src/coreclr/gc/gcimpl.h index 5f631642e11c76..2a587e21121ce8 100644 --- a/src/coreclr/gc/gcimpl.h +++ b/src/coreclr/gc/gcimpl.h @@ -180,7 +180,10 @@ class GCHeap : public IGCHeapInternal bool* isConcurrent, uint64_t* genInfoRaw, uint64_t* pauseInfoRaw, - int kind);; + int kind); + + // AndrewTodo: Does the order of methods in this interface matters? + uint64_t GetTotalPauseDuration(); uint32_t GetMemoryLoad(); diff --git a/src/coreclr/gc/gcinterface.h b/src/coreclr/gc/gcinterface.h index 8b6bf765aaad8b..d2c9923c8b078b 100644 --- a/src/coreclr/gc/gcinterface.h +++ b/src/coreclr/gc/gcinterface.h @@ -652,6 +652,10 @@ class IGCHeap { // Get the last memory load in percentage observed by the last GC. virtual uint32_t GetMemoryLoad() = 0; + // Get the total paused duration + // AndrewTodo: Does the order of methods in this interface matters? + virtual uint64_t GetTotalPauseDuration() = 0; + // Gets the current GC latency mode. virtual int GetGcLatencyMode() = 0; diff --git a/src/coreclr/nativeaot/Runtime/GCHelpers.cpp b/src/coreclr/nativeaot/Runtime/GCHelpers.cpp index 9457e46d6f7269..c91e2cbb72f264 100644 --- a/src/coreclr/nativeaot/Runtime/GCHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/GCHelpers.cpp @@ -339,3 +339,8 @@ EXTERN_C REDHAWK_API void RhAllocateNewObject(MethodTable* pEEType, uint32_t fla pThread->EnablePreemptiveMode(); } + +COOP_PINVOKE_HELPER(int64_t, RhGetTotalPauseDuration, ()) +{ + return (int64_t)(GCHeapUtilities::GetGCHeap()->GetTotalPauseDuration() * 10); +} diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs index dbf195b409daa2..b4d59af8f3655b 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/GC.NativeAot.cs @@ -759,5 +759,10 @@ public static unsafe T[] AllocateArray(int length, bool pinned = false) return array; } + + public static TimeSpan GetTotalPauseDuration() + { + return new TimeSpan(RuntimeImports.RhGetTotalPauseDuration()); + } } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs index b1666d1d7d3d97..6ab44352da6c93 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -201,6 +201,10 @@ internal static void RhWaitForPendingFinalizers(bool allowReentrantWait) [LibraryImport(RuntimeLibrary)] internal static unsafe partial void RhAllocateNewObject(IntPtr pEEType, uint flags, void* pResult); + [MethodImpl(MethodImplOptions.InternalCall)] + [RuntimeImport(RuntimeLibrary, "RhGetTotalPauseDuration")] + internal static extern long RhGetTotalPauseDuration(); + [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhCompareObjectContentsAndPadding")] internal static extern bool RhCompareObjectContentsAndPadding(object obj1, object obj2); diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs index b6901b1ce50c38..520e78b43ce130 100644 --- a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -88,6 +88,9 @@ internal static unsafe Array RhNewArray(EETypePtr pEEType, int length) [DllImport(RuntimeLibrary)] internal static unsafe extern void RhAllocateNewObject(IntPtr pEEType, uint flags, void* pResult); + [DllImport(RuntimeLibrary)] + internal static unsafe extern long RhGetTotalPauseDuration(); + [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhpFallbackFailFast")] internal static extern unsafe void RhpFallbackFailFast(); diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 732c6042ce8cb8..838e5b4e617823 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -674,6 +674,21 @@ UINT64 GCInterface::m_remPressure[MEM_PRESSURE_COUNT] = {0, 0, 0, 0}; // his // (m_iteration % MEM_PRESSURE_COUNT) is used as an index into m_addPressure and m_remPressure UINT GCInterface::m_iteration = 0; +FCIMPL0(INT64, GCInterface::_GetTotalPauseDuration) +{ + FCALL_CONTRACT; + + FC_GC_POLL_NOT_NEEDED(); + + // Unsigned to signed conversion happened here + + // GetTotalPauseDuration returned microseconds, but the TimeSpan constructor requires + // 100 nanosecond unit. + + return (int64_t)(GCHeapUtilities::GetGCHeap()->GetTotalPauseDuration() * 10); +} +FCIMPLEND + FCIMPL2(void, GCInterface::GetMemoryInfo, Object* objUNSAFE, int kind) { FCALL_CONTRACT; diff --git a/src/coreclr/vm/comutilnative.h b/src/coreclr/vm/comutilnative.h index 22bfc527184ad2..9ccc02ea93af99 100644 --- a/src/coreclr/vm/comutilnative.h +++ b/src/coreclr/vm/comutilnative.h @@ -121,7 +121,6 @@ typedef GCMemoryInfoData * GCMEMORYINFODATA; typedef GCMemoryInfoData * GCMEMORYINFODATAREF; #endif // USE_CHECKED_OBJECTREFS - class GCInterface { private: static INT32 m_gc_counts[3]; @@ -134,6 +133,7 @@ class GCInterface { static FORCEINLINE UINT64 InterlockedAdd(UINT64 *pAugend, UINT64 addend); static FORCEINLINE UINT64 InterlockedSub(UINT64 *pMinuend, UINT64 subtrahend); + static FCDECL0(INT64, _GetTotalPauseDuration); static FCDECL2(void, GetMemoryInfo, Object* objUNSAFE, int kind); static FCDECL0(UINT32, GetMemoryLoad); static FCDECL0(int, GetGcLatencyMode); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index ccb31d35cd8f78..b24d7608b0e1b0 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -475,6 +475,7 @@ FCFuncStart(gGCInterfaceFuncs) FCFuncElement("_WaitForFullGCComplete", GCInterface::WaitForFullGCComplete) FCFuncElement("_CollectionCount", GCInterface::CollectionCount) FCFuncElement("GetMemoryInfo", GCInterface::GetMemoryInfo) + FCFuncElement("_GetTotalPauseDuration", GCInterface::_GetTotalPauseDuration) FCFuncElement("GetMemoryLoad", GCInterface::GetMemoryLoad) FCFuncElement("GetSegmentSize", GCInterface::GetSegmentSize) FCFuncElement("GetLastGCPercentTimeInGC", GCInterface::GetLastGCPercentTimeInGC) diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index feb44b077a5971..5106bdc9abc64c 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2519,6 +2519,7 @@ public static void SuppressFinalize(object obj) { } public static System.GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout) { throw null; } public static System.GCNotificationStatus WaitForFullGCComplete(System.TimeSpan timeout) { throw null; } public static void WaitForPendingFinalizers() { } + public static TimeSpan GetTotalPauseDuration() { return TimeSpan.Zero; } } public enum GCCollectionMode { diff --git a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs index c08eec30fbebea..b5bc27542b5fef 100644 --- a/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/GC.Mono.cs @@ -310,5 +310,10 @@ internal static int GetLastGCPercentTimeInGC() { return (int)EventPipeInternal.GetRuntimeCounterValue(EventPipeInternal.RuntimeCounters.GC_LAST_PERCENT_TIME_IN_GC); } + + public static TimeSpan GetTotalPauseDuration() + { + return TimeSpan.Zero; + } } } From 376e34bb4fbd1b5ae2d182ae10dab7e6f4f3b2d6 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Wed, 4 May 2022 09:38:19 -0700 Subject: [PATCH 2/7] Remove Unnecessary import from Test.CoreLib --- .../Test.CoreLib/src/System/Runtime/RuntimeImports.cs | 3 --- src/coreclr/vm/comutilnative.h | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs index 520e78b43ce130..b6901b1ce50c38 100644 --- a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -88,9 +88,6 @@ internal static unsafe Array RhNewArray(EETypePtr pEEType, int length) [DllImport(RuntimeLibrary)] internal static unsafe extern void RhAllocateNewObject(IntPtr pEEType, uint flags, void* pResult); - [DllImport(RuntimeLibrary)] - internal static unsafe extern long RhGetTotalPauseDuration(); - [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhpFallbackFailFast")] internal static extern unsafe void RhpFallbackFailFast(); diff --git a/src/coreclr/vm/comutilnative.h b/src/coreclr/vm/comutilnative.h index 9ccc02ea93af99..1cfff44077e3ea 100644 --- a/src/coreclr/vm/comutilnative.h +++ b/src/coreclr/vm/comutilnative.h @@ -121,6 +121,7 @@ typedef GCMemoryInfoData * GCMEMORYINFODATA; typedef GCMemoryInfoData * GCMEMORYINFODATAREF; #endif // USE_CHECKED_OBJECTREFS + class GCInterface { private: static INT32 m_gc_counts[3]; From 7233dff6ec237480409a90b362faab3cee3dff91 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Mon, 9 May 2022 12:00:14 -0700 Subject: [PATCH 3/7] Code Review Feedback --- src/coreclr/gc/gc.cpp | 4 ++-- src/coreclr/gc/gcimpl.h | 3 +-- src/coreclr/gc/gcinterface.h | 7 +++---- src/coreclr/nativeaot/Runtime/GCHelpers.cpp | 2 +- src/coreclr/vm/comutilnative.cpp | 9 ++------- src/coreclr/vm/comutilnative.h | 2 +- src/coreclr/vm/ecalllist.h | 2 +- 7 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 30caa8be6609ba..e52fc373983e25 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -46323,9 +46323,9 @@ void GCHeap::GetMemoryInfo(uint64_t* highMemLoadThresholdBytes, #endif //_DEBUG } -uint64_t GCHeap::GetTotalPauseDuration() +int64_t GCHeap::GetTotalPauseDuration() { - return gc_heap::total_suspended_time; + return (int64_t)(gc_heap::total_suspended_time * 10); } uint32_t GCHeap::GetMemoryLoad() diff --git a/src/coreclr/gc/gcimpl.h b/src/coreclr/gc/gcimpl.h index 2a587e21121ce8..1d470a0c8ca124 100644 --- a/src/coreclr/gc/gcimpl.h +++ b/src/coreclr/gc/gcimpl.h @@ -182,8 +182,7 @@ class GCHeap : public IGCHeapInternal uint64_t* pauseInfoRaw, int kind); - // AndrewTodo: Does the order of methods in this interface matters? - uint64_t GetTotalPauseDuration(); + int64_t GetTotalPauseDuration(); uint32_t GetMemoryLoad(); diff --git a/src/coreclr/gc/gcinterface.h b/src/coreclr/gc/gcinterface.h index d2c9923c8b078b..c9df0dbd36d087 100644 --- a/src/coreclr/gc/gcinterface.h +++ b/src/coreclr/gc/gcinterface.h @@ -652,10 +652,6 @@ class IGCHeap { // Get the last memory load in percentage observed by the last GC. virtual uint32_t GetMemoryLoad() = 0; - // Get the total paused duration - // AndrewTodo: Does the order of methods in this interface matters? - virtual uint64_t GetTotalPauseDuration() = 0; - // Gets the current GC latency mode. virtual int GetGcLatencyMode() = 0; @@ -927,6 +923,9 @@ class IGCHeap { virtual unsigned int GetGenerationWithRange(Object* object, uint8_t** ppStart, uint8_t** ppAllocated, uint8_t** ppReserved) = 0; + // Get the total paused duration + virtual int64_t GetTotalPauseDuration() = 0; + IGCHeap() {} virtual ~IGCHeap() {} }; diff --git a/src/coreclr/nativeaot/Runtime/GCHelpers.cpp b/src/coreclr/nativeaot/Runtime/GCHelpers.cpp index c91e2cbb72f264..5819776ca10534 100644 --- a/src/coreclr/nativeaot/Runtime/GCHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/GCHelpers.cpp @@ -342,5 +342,5 @@ EXTERN_C REDHAWK_API void RhAllocateNewObject(MethodTable* pEEType, uint32_t fla COOP_PINVOKE_HELPER(int64_t, RhGetTotalPauseDuration, ()) { - return (int64_t)(GCHeapUtilities::GetGCHeap()->GetTotalPauseDuration() * 10); + return GCHeapUtilities::GetGCHeap()->GetTotalPauseDuration(); } diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 838e5b4e617823..7f92d23b8cce6f 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -674,18 +674,13 @@ UINT64 GCInterface::m_remPressure[MEM_PRESSURE_COUNT] = {0, 0, 0, 0}; // his // (m_iteration % MEM_PRESSURE_COUNT) is used as an index into m_addPressure and m_remPressure UINT GCInterface::m_iteration = 0; -FCIMPL0(INT64, GCInterface::_GetTotalPauseDuration) +FCIMPL0(INT64, GCInterface::GetTotalPauseDuration) { FCALL_CONTRACT; FC_GC_POLL_NOT_NEEDED(); - // Unsigned to signed conversion happened here - - // GetTotalPauseDuration returned microseconds, but the TimeSpan constructor requires - // 100 nanosecond unit. - - return (int64_t)(GCHeapUtilities::GetGCHeap()->GetTotalPauseDuration() * 10); + return GCHeapUtilities::GetGCHeap()->GetTotalPauseDuration(); } FCIMPLEND diff --git a/src/coreclr/vm/comutilnative.h b/src/coreclr/vm/comutilnative.h index 1cfff44077e3ea..42ec3b0663b915 100644 --- a/src/coreclr/vm/comutilnative.h +++ b/src/coreclr/vm/comutilnative.h @@ -134,7 +134,7 @@ class GCInterface { static FORCEINLINE UINT64 InterlockedAdd(UINT64 *pAugend, UINT64 addend); static FORCEINLINE UINT64 InterlockedSub(UINT64 *pMinuend, UINT64 subtrahend); - static FCDECL0(INT64, _GetTotalPauseDuration); + static FCDECL0(INT64, GetTotalPauseDuration); static FCDECL2(void, GetMemoryInfo, Object* objUNSAFE, int kind); static FCDECL0(UINT32, GetMemoryLoad); static FCDECL0(int, GetGcLatencyMode); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index b24d7608b0e1b0..05e9982a43fde4 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -475,7 +475,7 @@ FCFuncStart(gGCInterfaceFuncs) FCFuncElement("_WaitForFullGCComplete", GCInterface::WaitForFullGCComplete) FCFuncElement("_CollectionCount", GCInterface::CollectionCount) FCFuncElement("GetMemoryInfo", GCInterface::GetMemoryInfo) - FCFuncElement("_GetTotalPauseDuration", GCInterface::_GetTotalPauseDuration) + FCFuncElement("_GetTotalPauseDuration", GCInterface::GetTotalPauseDuration) FCFuncElement("GetMemoryLoad", GCInterface::GetMemoryLoad) FCFuncElement("GetSegmentSize", GCInterface::GetSegmentSize) FCFuncElement("GetLastGCPercentTimeInGC", GCInterface::GetLastGCPercentTimeInGC) From ea19ca6b6c237fc77905999b9483e20894662fd8 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Mon, 9 May 2022 13:10:00 -0700 Subject: [PATCH 4/7] public API documentation --- src/libraries/System.Runtime/ref/System.Runtime.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 5106bdc9abc64c..a32f7b36509a36 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2519,6 +2519,11 @@ public static void SuppressFinalize(object obj) { } public static System.GCNotificationStatus WaitForFullGCComplete(int millisecondsTimeout) { throw null; } public static System.GCNotificationStatus WaitForFullGCComplete(System.TimeSpan timeout) { throw null; } public static void WaitForPendingFinalizers() { } + + /// + /// Gets the total amount of time paused in GC since the beginning of the process. + /// + /// The total amount of time paused in GC since the beginning of the process. public static TimeSpan GetTotalPauseDuration() { return TimeSpan.Zero; } } public enum GCCollectionMode From df20f6b14502d832b8a7d8e301954ec3c4b2b52e Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Mon, 9 May 2022 13:50:21 -0700 Subject: [PATCH 5/7] Testing --- src/tests/GC/API/GC/GetTotalPauseDuration.cs | 26 +++++++++++++++++++ .../GC/API/GC/GetTotalPauseDuration.csproj | 16 ++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/tests/GC/API/GC/GetTotalPauseDuration.cs create mode 100644 src/tests/GC/API/GC/GetTotalPauseDuration.csproj diff --git a/src/tests/GC/API/GC/GetTotalPauseDuration.cs b/src/tests/GC/API/GC/GetTotalPauseDuration.cs new file mode 100644 index 00000000000000..c540c264f50392 --- /dev/null +++ b/src/tests/GC/API/GC/GetTotalPauseDuration.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// Tests GC.GetTotalPauseDuration() + +using System; +using System.Diagnostics; + +public class Test_Collect +{ + public static int Main() + { + Stopwatch sw = Stopwatch.StartNew(); + GC.Collect(); + sw.Stop(); + TimeSpan elapsed = sw.Elapsed; + TimeSpan totalPauseDuration = GC.GetTotalPauseDuration(); + if (TimeSpan.Zero < totalPauseDuration && totalPauseDuration <= elapsed) + { + return 100; + } + else + { + return 101; + } + } +} diff --git a/src/tests/GC/API/GC/GetTotalPauseDuration.csproj b/src/tests/GC/API/GC/GetTotalPauseDuration.csproj new file mode 100644 index 00000000000000..358a5cea38bb5e --- /dev/null +++ b/src/tests/GC/API/GC/GetTotalPauseDuration.csproj @@ -0,0 +1,16 @@ + + + Exe + + true + + 0 + + + + PdbOnly + + + + + From 4079a8e0bec710c54dc080ca802c0530e4fbfe7e Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Mon, 16 May 2022 12:38:10 -0700 Subject: [PATCH 6/7] Improve test --- src/tests/GC/API/GC/GetTotalPauseDuration.cs | 41 ++++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/tests/GC/API/GC/GetTotalPauseDuration.cs b/src/tests/GC/API/GC/GetTotalPauseDuration.cs index c540c264f50392..1435c3493aba92 100644 --- a/src/tests/GC/API/GC/GetTotalPauseDuration.cs +++ b/src/tests/GC/API/GC/GetTotalPauseDuration.cs @@ -7,20 +7,29 @@ public class Test_Collect { - public static int Main() - { - Stopwatch sw = Stopwatch.StartNew(); - GC.Collect(); - sw.Stop(); - TimeSpan elapsed = sw.Elapsed; - TimeSpan totalPauseDuration = GC.GetTotalPauseDuration(); - if (TimeSpan.Zero < totalPauseDuration && totalPauseDuration <= elapsed) - { - return 100; - } - else - { - return 101; - } - } + public static int Main() + { + Stopwatch sw = Stopwatch.StartNew(); + GC.Collect(); + sw.Stop(); + TimeSpan elapsed = sw.Elapsed; + TimeSpan totalPauseDuration = GC.GetTotalPauseDuration(); + GCMemoryInfo memoryInfo = GC.GetGCMemoryInfo(); + TimeSpan lastGcDuration = memoryInfo.PauseDurations[0]; + + // These conditions assume the only GC in the process + // is the one we just triggered. This makes the test incompatible + // with any changes that might introduce extra GCs. + + if (TimeSpan.Zero < totalPauseDuration && + totalPauseDuration <= elapsed && + lastGcDuration == totalPauseDuration) + { + return 100; + } + else + { + return 101; + } + } } From 5a637d2ada2c6db8985a26d53b27593c465b8811 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Mon, 16 May 2022 16:28:58 -0700 Subject: [PATCH 7/7] Move new method to the real end --- src/coreclr/gc/gcinterface.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/gc/gcinterface.h b/src/coreclr/gc/gcinterface.h index c9df0dbd36d087..a1edb39e59fcb3 100644 --- a/src/coreclr/gc/gcinterface.h +++ b/src/coreclr/gc/gcinterface.h @@ -923,11 +923,11 @@ class IGCHeap { virtual unsigned int GetGenerationWithRange(Object* object, uint8_t** ppStart, uint8_t** ppAllocated, uint8_t** ppReserved) = 0; - // Get the total paused duration - virtual int64_t GetTotalPauseDuration() = 0; - IGCHeap() {} virtual ~IGCHeap() {} + + // Get the total paused duration + virtual int64_t GetTotalPauseDuration() = 0; }; #ifdef WRITE_BARRIER_CHECK