void stat_startGC (gc_thread *gct) { nat bell = RtsFlags.GcFlags.ringBell; if (bell) { if (bell > 1) { debugBelch(" GC "); rub_bell = 1; } else { debugBelch("\007"); } } #if USE_PAPI if(papi_is_reporting) { /* Switch to counting GC events */ papi_stop_mutator_count(); papi_start_gc_count(); } #endif getProcessTimes(&gct->gc_start_cpu, &gct->gc_start_elapsed); gct->gc_start_thread_cpu = getThreadCPUTime(); if (RtsFlags.GcFlags.giveStats != NO_GC_STATS) { gct->gc_start_faults = getPageFaults(); } }
void stat_gcWorkerThreadStart (gc_thread *gct) { if (RtsFlags.GcFlags.giveStats != NO_GC_STATS) { getProcessTimes(&gct->gc_start_cpu, &gct->gc_start_elapsed); gct->gc_start_thread_cpu = getThreadCPUTime(); } }
void stat_gcWorkerThreadDone (gc_thread *gct) { Ticks thread_cpu, elapsed, gc_cpu, gc_elapsed; if (RtsFlags.GcFlags.giveStats != NO_GC_STATS) { elapsed = getProcessElapsedTime(); thread_cpu = getThreadCPUTime(); gc_cpu = thread_cpu - gct->gc_start_thread_cpu; gc_elapsed = elapsed - gct->gc_start_elapsed; taskDoneGC(gct->cap->running_task, gc_cpu, gc_elapsed); } }
void stat_startGC (Capability *cap, gc_thread *gct) { nat bell = RtsFlags.GcFlags.ringBell; if (bell) { if (bell > 1) { debugBelch(" GC "); rub_bell = 1; } else { debugBelch("\007"); } } #if USE_PAPI if(papi_is_reporting) { /* Switch to counting GC events */ papi_stop_mutator_count(); papi_start_gc_count(); } #endif getProcessTimes(&gct->gc_start_cpu, &gct->gc_start_elapsed); // Post EVENT_GC_START with the same timestamp as used for stats // (though converted from Time=StgInt64 to EventTimestamp=StgWord64). // Here, as opposed to other places, the event is emitted on the cap // that initiates the GC and external tools expect it to have the same // timestamp as used in +RTS -s calculcations. traceEventGcStartAtT(cap, TimeToNS(gct->gc_start_elapsed - start_init_elapsed)); gct->gc_start_thread_cpu = getThreadCPUTime(); if (RtsFlags.GcFlags.giveStats != NO_GC_STATS) { gct->gc_start_faults = getPageFaults(); } }
void stat_endGC (gc_thread *gct, lnat alloc, lnat live, lnat copied, nat gen, lnat max_copied, lnat avg_copied, lnat slop) { if (RtsFlags.GcFlags.giveStats != NO_GC_STATS || RtsFlags.ProfFlags.doHeapProfile) // heap profiling needs GC_tot_time { Ticks cpu, elapsed, thread_gc_cpu, gc_cpu, gc_elapsed; getProcessTimes(&cpu, &elapsed); gc_elapsed = elapsed - gct->gc_start_elapsed; thread_gc_cpu = getThreadCPUTime() - gct->gc_start_thread_cpu; gc_cpu = cpu - gct->gc_start_cpu; taskDoneGC(gct->cap->running_task, thread_gc_cpu, gc_elapsed); if (RtsFlags.GcFlags.giveStats == VERBOSE_GC_STATS) { nat faults = getPageFaults(); statsPrintf("%9ld %9ld %9ld", alloc*sizeof(W_), copied*sizeof(W_), live*sizeof(W_)); statsPrintf(" %5.2f %5.2f %7.2f %7.2f %4ld %4ld (Gen: %2d)\n", TICK_TO_DBL(gc_cpu), TICK_TO_DBL(gc_elapsed), TICK_TO_DBL(cpu), TICK_TO_DBL(elapsed - start_init_elapsed), faults - gct->gc_start_faults, gct->gc_start_faults - GC_end_faults, gen); GC_end_faults = faults; statsFlush(); } GC_coll_cpu[gen] += gc_cpu; GC_coll_elapsed[gen] += gc_elapsed; if (GC_coll_max_pause[gen] < gc_elapsed) { GC_coll_max_pause[gen] = gc_elapsed; } GC_tot_copied += (StgWord64) copied; GC_tot_alloc += (StgWord64) alloc; GC_par_max_copied += (StgWord64) max_copied; GC_par_avg_copied += (StgWord64) avg_copied; GC_tot_cpu += gc_cpu; if (gen == RtsFlags.GcFlags.generations-1) { /* major GC? */ if (live > max_residency) { max_residency = live; } current_residency = live; residency_samples++; cumulative_residency += live; } if (slop > max_slop) max_slop = slop; } if (rub_bell) { debugBelch("\b\b\b \b\b\b"); rub_bell = 0; } #if USE_PAPI if(papi_is_reporting) { /* Switch to counting mutator events */ if (gen == 0) { papi_stop_gc0_count(); } else { papi_stop_gc1_count(); } papi_start_mutator_count(); } #endif }
gct->gc_start_faults = getPageFaults(); } } void stat_gcWorkerThreadStart (gc_thread *gct STG_UNUSED) { #if 0 /* * We dont' collect per-thread GC stats any more, but this code * could be used to do that if we want to in the future: */ if (RtsFlags.GcFlags.giveStats != NO_GC_STATS) { getProcessTimes(&gct->gc_start_cpu, &gct->gc_start_elapsed); gct->gc_start_thread_cpu = getThreadCPUTime(); } #endif } void stat_gcWorkerThreadDone (gc_thread *gct STG_UNUSED) { #if 0 /* * We dont' collect per-thread GC stats any more, but this code * could be used to do that if we want to in the future: */ Time thread_cpu, elapsed, gc_cpu, gc_elapsed; if (RtsFlags.GcFlags.giveStats != NO_GC_STATS)