summaryrefslogtreecommitdiff
path: root/rts/Stats.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2013-02-14 10:06:44 +0000
committerSimon Marlow <marlowsd@gmail.com>2013-02-14 10:06:53 +0000
commit65a0e1eb88fb48d085f8da498a7acc2fd345c2a8 (patch)
tree3d5c6489c1b51d085a9f8b313aae5daa3330bcf2 /rts/Stats.c
parente5085db5d16f904f9307445fbafc206283f630c7 (diff)
downloadhaskell-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.c71
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++)