Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 8 additions & 0 deletions src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -711,5 +711,13 @@ public static T[] AllocateArray<T>(int length, bool pinned = false) // T[] rathe

return Unsafe.As<T[]>(AllocateNewArray(typeof(T[]).TypeHandle.Value, length, flags));
}

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern long _GetTotalPauseDuration();

public static TimeSpan GetTotalPauseDuration()
{
return new TimeSpan(_GetTotalPauseDuration());
}
}
}
5 changes: 5 additions & 0 deletions src/coreclr/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46323,6 +46323,11 @@ void GCHeap::GetMemoryInfo(uint64_t* highMemLoadThresholdBytes,
#endif //_DEBUG
}

int64_t GCHeap::GetTotalPauseDuration()
{
return (int64_t)(gc_heap::total_suspended_time * 10);
}

uint32_t GCHeap::GetMemoryLoad()
{
uint32_t memory_load = 0;
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/gc/gcimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ class GCHeap : public IGCHeapInternal
bool* isConcurrent,
uint64_t* genInfoRaw,
uint64_t* pauseInfoRaw,
int kind);;
int kind);

int64_t GetTotalPauseDuration();

uint32_t GetMemoryLoad();

Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/gc/gcinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,9 @@ class IGCHeap {

IGCHeap() {}
virtual ~IGCHeap() {}

// Get the total paused duration
virtual int64_t GetTotalPauseDuration() = 0;
};

#ifdef WRITE_BARRIER_CHECK
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/nativeaot/Runtime/GCHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,3 +339,8 @@ EXTERN_C REDHAWK_API void RhAllocateNewObject(MethodTable* pEEType, uint32_t fla

pThread->EnablePreemptiveMode();
}

COOP_PINVOKE_HELPER(int64_t, RhGetTotalPauseDuration, ())
{
return GCHeapUtilities::GetGCHeap()->GetTotalPauseDuration();
}
Original file line number Diff line number Diff line change
Expand Up @@ -759,5 +759,10 @@ public static unsafe T[] AllocateArray<T>(int length, bool pinned = false)

return array;
}

public static TimeSpan GetTotalPauseDuration()
{
return new TimeSpan(RuntimeImports.RhGetTotalPauseDuration());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/vm/comutilnative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,16 @@ 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();

return GCHeapUtilities::GetGCHeap()->GetTotalPauseDuration();
}
FCIMPLEND

FCIMPL2(void, GCInterface::GetMemoryInfo, Object* objUNSAFE, int kind)
{
FCALL_CONTRACT;
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/comutilnative.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +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 FCDECL2(void, GetMemoryInfo, Object* objUNSAFE, int kind);
static FCDECL0(UINT32, GetMemoryLoad);
static FCDECL0(int, GetGcLatencyMode);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions src/libraries/System.Runtime/ref/System.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2519,6 +2519,12 @@ 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() { }

/// <summary>
/// Gets the total amount of time paused in GC since the beginning of the process.
/// </summary>
/// <returns> The total amount of time paused in GC since the beginning of the process.</returns>
public static TimeSpan GetTotalPauseDuration() { return TimeSpan.Zero; }
}
public enum GCCollectionMode
{
Expand Down
5 changes: 5 additions & 0 deletions src/mono/System.Private.CoreLib/src/System/GC.Mono.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
35 changes: 35 additions & 0 deletions src/tests/GC/API/GC/GetTotalPauseDuration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// 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();
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;
}
}
}
16 changes: 16 additions & 0 deletions src/tests/GC/API/GC/GetTotalPauseDuration.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<!-- Consider enable it for Mono whenever the implementation is ready -->
<CLRTestTargetUnsupported Condition="'$(RuntimeFlavor)' != 'coreclr'">true</CLRTestTargetUnsupported>
<!-- Temporaily set to P0 so that it runs on CI for initial testing -->
<CLRTestPriority>0</CLRTestPriority>
</PropertyGroup>
<PropertyGroup>
<!-- Set to 'Full' if the Debug? column is marked in the spreadsheet. Leave blank otherwise. -->
<DebugType>PdbOnly</DebugType>
</PropertyGroup>
<ItemGroup>
<Compile Include="GetTotalPauseDuration.cs" />
</ItemGroup>
</Project>