@@ -152,14 +152,15 @@ void SatoriRecycler::Initialize(SatoriHeap* heap)
152152
153153 m_isLowLatencyMode = SatoriUtil::IsLowLatencyMode ();
154154
155- for (int i = 0 ; i < 2 ; i++)
155+ for (int i = 0 ; i < 3 ; i++)
156156 {
157- m_gcStartMillis[i] = m_gcDurationMillis [i] = 0 ;
157+ m_gcStartMillis[i] = m_gcDurationUsecs[i] = m_gcAccmulatingDurationUsecs [i] = 0 ;
158158 }
159159
160160 m_lastEphemeralGcInfo = { 0 };
161161 m_lastTenuredGcInfo = { 0 };
162162 m_CurrentGcInfo = nullptr ;
163+ m_startMillis = GetNowMillis ();
163164}
164165
165166void SatoriRecycler::ShutDown ()
@@ -896,6 +897,8 @@ void SatoriRecycler::BlockingMarkForConcurrent()
896897
897898 size_t blockingDuration = (GCToOSInterface::QueryPerformanceCounter () - blockingStart);
898899 m_CurrentGcInfo->m_pauseDurations [1 ] = blockingDuration / m_perfCounterTicksPerMicro;
900+ m_gcAccmulatingDurationUsecs[m_condemnedGeneration] += blockingDuration / m_perfCounterTicksPerMicro;
901+ UpdateGcCounters (blockingStart);
899902
900903 GCToEEInterface::RestartEE (false );
901904 }
@@ -1146,8 +1149,14 @@ void SatoriRecycler::BlockingCollect1()
11461149
11471150 size_t blockingDuration = (GCToOSInterface::QueryPerformanceCounter () - blockingStart);
11481151 m_CurrentGcInfo->m_pauseDurations [0 ] = blockingDuration / m_perfCounterTicksPerMicro;
1149- m_gcDurationMillis[1 ] = blockingDuration / m_perfCounterTicksPerMicro;
1152+ m_gcDurationUsecs[1 ] = blockingDuration / m_perfCounterTicksPerMicro;
1153+ m_gcAccmulatingDurationUsecs[1 ] += blockingDuration / m_perfCounterTicksPerMicro;
1154+
1155+ size_t fromStartMillis = GetNowMillis () - m_startMillis;
1156+ m_CurrentGcInfo->m_pausePercentage = (uint32_t )(m_gcAccmulatingDurationUsecs[1 ] / (int64_t )fromStartMillis / 10 );
1157+
11501158 m_CurrentGcInfo = nullptr ;
1159+ UpdateGcCounters (blockingStart);
11511160
11521161 // restart VM
11531162 GCToEEInterface::RestartEE (true );
@@ -1165,8 +1174,14 @@ void SatoriRecycler::BlockingCollect2()
11651174
11661175 size_t blockingDuration = (GCToOSInterface::QueryPerformanceCounter () - blockingStart);
11671176 m_CurrentGcInfo->m_pauseDurations [0 ] = blockingDuration / m_perfCounterTicksPerMicro;
1168- m_gcDurationMillis[2 ] = blockingDuration / m_perfCounterTicksPerMicro;
1177+ m_gcDurationUsecs[2 ] = blockingDuration / m_perfCounterTicksPerMicro;
1178+ m_gcAccmulatingDurationUsecs[2 ] += blockingDuration / m_perfCounterTicksPerMicro;
1179+
1180+ size_t fromStartMillis = GetNowMillis () - m_startMillis;
1181+ m_CurrentGcInfo->m_pausePercentage = (uint32_t )( m_gcAccmulatingDurationUsecs[2 ] / (int64_t )fromStartMillis / 10 );
1182+
11691183 m_CurrentGcInfo = nullptr ;
1184+ UpdateGcCounters (blockingStart);
11701185
11711186 // restart VM
11721187 GCToEEInterface::RestartEE (true );
@@ -4406,11 +4421,30 @@ size_t SatoriRecycler::GetGcStartMillis(int generation)
44064421
44074422size_t SatoriRecycler::GetGcDurationMillis (int generation)
44084423{
4409- return m_gcDurationMillis[generation];
4424+ return m_gcDurationUsecs[generation] / 1000 ;
4425+ }
4426+
4427+ size_t SatoriRecycler::GetGcAccumulatingDurationMillis (int generation)
4428+ {
4429+ return m_gcAccmulatingDurationUsecs[generation];
44104430}
44114431
44124432bool & SatoriRecycler::IsLowLatencyMode ()
44134433{
44144434 return m_isLowLatencyMode;
44154435}
44164436
4437+ void SatoriRecycler::UpdateGcCounters (int64_t blockingStart)
4438+ {
4439+ // Compute Time in GC
4440+ int64_t currentPerfCounterTimer = GCToOSInterface::QueryPerformanceCounter ();
4441+
4442+ int64_t totalTimeInCurrentGc = currentPerfCounterTimer - blockingStart;
4443+ int64_t timeSinceLastGcEnded = currentPerfCounterTimer - m_totalTimeAtLastGcEnd;
4444+
4445+ // should always hold unless we switch to a nonmonotonic timer.
4446+ _ASSERTE (timeSinceLastGcEnded >= totalTimeInCurrentGc);
4447+
4448+ m_percentTimeInGcSinceLastGc = timeSinceLastGcEnded != 0 ? (int )(totalTimeInCurrentGc * 100 / timeSinceLastGcEnded) : 0 ;
4449+ m_totalTimeAtLastGcEnd = currentPerfCounterTimer;
4450+ }
0 commit comments