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.cs
Original file line number Diff line number Diff line change
Expand Up @@ -719,5 +719,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 @@ -45045,6 +45045,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
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 @@ -143,6 +143,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 @@ -706,6 +706,7 @@ FCFuncStart(gGCInterfaceFuncs)
FCFuncElement("_WaitForFullGCComplete", GCInterface::WaitForFullGCComplete)
FCFuncElement("_CollectionCount", GCInterface::CollectionCount)
FCFuncElement("GetMemoryInfo", GCInterface::GetMemoryInfo)
FCFuncElement("_GetTotalPauseDuration", GCInterface::GetTotalPauseDuration)
FCFuncElement("GetMemoryLoad", GCInterface::GetMemoryLoad)
QCFuncElement("_StartNoGCRegion", GCInterface::StartNoGCRegion)
QCFuncElement("_EndNoGCRegion", GCInterface::EndNoGCRegion)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ CannotMakeMemberAbstract : Member 'public System.Boolean System.IO.FileSystemInf
CannotMakeMemberAbstract : Member 'public System.String System.IO.FileSystemInfo.Name.get()' is abstract in the reference but is not abstract in the implementation.
# C# generates backing fields for fixed buffers as public.
TypesMustExist : Type 'System.IO.Enumeration.FileSystemEntry.<_fileNameBuffer>e__FixedBuffer' does not exist in the reference but it does exist in the implementation.

# This API only exists on servicing builds after the commit that introduce it
MembersMustExist : Member 'public System.TimeSpan System.GC.GetTotalPauseDuration()' does not exist in the reference but it does exist in the implementation.
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 @@ -313,5 +313,10 @@ internal static int GetLastGCPercentTimeInGC()
{
return (int)EventPipeInternal.GetRuntimeCounterValue(EventPipeInternal.RuntimeCounters.GC_LAST_PERCENT_TIME_IN_GC);
}

public static TimeSpan GetTotalPauseDuration()
{
return TimeSpan.Zero;
}
}
}
36 changes: 36 additions & 0 deletions src/tests/GC/API/GC/GetTotalPauseDuration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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;
using System.Reflection;

public class Test_Collect
{
public static int Main()
{
Stopwatch sw = Stopwatch.StartNew();
GC.Collect();
sw.Stop();
TimeSpan elapsed = sw.Elapsed;
TimeSpan totalPauseDuration = (TimeSpan)typeof(GC).GetMethod("GetTotalPauseDuration", BindingFlags.Public | BindingFlags.Static).Invoke(null, null);
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>