diff options
author | Simon Marlow <marlowsd@gmail.com> | 2013-02-14 10:06:44 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2013-02-14 10:06:53 +0000 |
commit | 65a0e1eb88fb48d085f8da498a7acc2fd345c2a8 (patch) | |
tree | 3d5c6489c1b51d085a9f8b313aae5daa3330bcf2 /rts/Stats.c | |
parent | e5085db5d16f904f9307445fbafc206283f630c7 (diff) | |
download | haskell-65a0e1eb88fb48d085f8da498a7acc2fd345c2a8.tar.gz |
Simplify the allocation stats accounting
We were doing it in two different ways and asserting that the results
were the same. In most cases they were, but I found one case where
they weren't: the GC itself allocates some memory for running
finalizers, and this memory was accounted for one way but not the
other.
It was simpler to remove the old way of counting allocation that to
try to fix it up, so I did that.
Diffstat (limited to 'rts/Stats.c')
-rw-r--r-- | rts/Stats.c | 71 |
1 files changed, 44 insertions, 27 deletions
diff --git a/rts/Stats.c b/rts/Stats.c index 6c8efd638d..3dc1ebe0fb 100644 --- a/rts/Stats.c +++ b/rts/Stats.c @@ -335,14 +335,38 @@ stat_gcWorkerThreadDone (gc_thread *gct STG_UNUSED) } /* ----------------------------------------------------------------------------- + * Calculate the total allocated memory since the start of the + * program. Also emits events reporting the per-cap allocation + * totals. + * -------------------------------------------------------------------------- */ + +static StgWord +calcTotalAllocated(void) +{ + W_ tot_alloc = 0; + W_ n; + for (n = 0; n < n_capabilities; n++) { + tot_alloc += capabilities[n].total_allocated; + traceEventHeapAllocated(&capabilities[n], + CAPSET_HEAP_DEFAULT, + capabilities[n].total_allocated * sizeof(W_)); + } + + return tot_alloc; +} + +/* ----------------------------------------------------------------------------- Called at the end of each GC -------------------------------------------------------------------------- */ void stat_endGC (Capability *cap, gc_thread *gct, - W_ alloc, W_ live, W_ copied, W_ slop, nat gen, + W_ live, W_ copied, W_ slop, nat gen, nat par_n_threads, W_ par_max_copied, W_ par_tot_copied) { + W_ tot_alloc; + W_ alloc; + if (RtsFlags.GcFlags.giveStats != NO_GC_STATS || RtsFlags.ProfFlags.doHeapProfile) // heap profiling needs GC_tot_time @@ -380,6 +404,17 @@ stat_endGC (Capability *cap, gc_thread *gct, gc_elapsed = elapsed - gct->gc_start_elapsed; gc_cpu = cpu - gct->gc_start_cpu; + /* For the moment we calculate both per-HEC and total allocation. + * There is thus redundancy here, but for the moment we will calculate + * it both the old and new way and assert they're the same. + * When we're sure it's working OK then we can simplify things. + */ + tot_alloc = calcTotalAllocated(); + + // allocated since the last GC + alloc = tot_alloc - GC_tot_alloc; + GC_tot_alloc = tot_alloc; + if (RtsFlags.GcFlags.giveStats == VERBOSE_GC_STATS) { W_ faults = getPageFaults(); @@ -406,29 +441,10 @@ stat_endGC (Capability *cap, gc_thread *gct, } GC_tot_copied += (StgWord64) copied; - GC_tot_alloc += (StgWord64) alloc; GC_par_max_copied += (StgWord64) par_max_copied; GC_par_tot_copied += (StgWord64) par_tot_copied; GC_tot_cpu += gc_cpu; - /* For the moment we calculate both per-HEC and total allocation. - * There is thus redundancy here, but for the moment we will calculate - * it both the old and new way and assert they're the same. - * When we're sure it's working OK then we can simplify things. - * TODO: simplify calcAllocated and clearNurseries so they don't have - * to calculate the total - */ - { - W_ tot_alloc = 0; - W_ n; - for (n = 0; n < n_capabilities; n++) { - tot_alloc += capabilities[n].total_allocated; - traceEventHeapAllocated(&capabilities[n], - CAPSET_HEAP_DEFAULT, - capabilities[n].total_allocated * sizeof(W_)); - } - ASSERT(GC_tot_alloc == tot_alloc); - } traceEventHeapSize(cap, CAPSET_HEAP_DEFAULT, mblocks_allocated * MBLOCK_SIZE_W * sizeof(W_)); @@ -587,8 +603,9 @@ StgInt TOTAL_CALLS=1; static inline Time get_init_cpu(void) { return end_init_cpu - start_init_cpu; } static inline Time get_init_elapsed(void) { return end_init_elapsed - start_init_elapsed; } + void -stat_exit(int alloc) +stat_exit (void) { generation *gen; Time gc_cpu = 0; @@ -599,6 +616,8 @@ stat_exit(int alloc) Time mut_elapsed = 0; Time exit_cpu = 0; Time exit_elapsed = 0; + W_ tot_alloc; + W_ alloc; if (RtsFlags.GcFlags.giveStats != NO_GC_STATS) { @@ -610,13 +629,11 @@ stat_exit(int alloc) getProcessTimes( &tot_cpu, &tot_elapsed ); tot_elapsed -= start_init_elapsed; - GC_tot_alloc += alloc; + tot_alloc = calcTotalAllocated(); - for (i = 0; i < n_capabilities; i++) { - traceEventHeapAllocated(&capabilities[i], - CAPSET_HEAP_DEFAULT, - capabilities[i].total_allocated * sizeof(W_)); - } + // allocated since the last GC + alloc = tot_alloc - GC_tot_alloc; + GC_tot_alloc = tot_alloc; /* Count total garbage collections */ for (g = 0; g < RtsFlags.GcFlags.generations; g++) |