#include "RtsFlags.h"
#include "RtsUtils.h"
#include "MBlock.h"
+#include "Storage.h"
#include "Schedule.h"
#include "Stats.h"
#include "ParTicky.h" /* ToDo: move into Rts.h */
#include "Profiling.h"
-#include "Storage.h"
#include "GetTime.h"
+#if USE_PAPI
+#include "Papi.h"
+#endif
+
/* huh? */
#define BIG_STRING_LEN 512
static Ticks *GC_coll_times;
-static void statsPrintf( char *s, ... )
- GNUC3_ATTRIBUTE(format (printf, 1, 2));
-
static void statsFlush( void );
static void statsClose( void );
return GCe_tot_time;
}
+Ticks stat_getElapsedTime(void)
+{
+ return getProcessElapsedTime() - ElapsedTimeStart;
+}
+
/* mut_user_time_during_GC() and mut_user_time()
*
* The former function can be used to get the current mutator time
} else {
InitElapsedTime = elapsed - ElapsedTimeStart;
}
+#if USE_PAPI
+ papi_init_eventsets();
+
+ /* We start counting events for the mutator
+ * when garbage collection starts
+ * we switch to the GC event set. */
+ papi_start_mutator_count();
+
+ /* This flag is needed to avoid counting the last GC */
+ papi_is_reporting = 1;
+
+#endif
}
/* -----------------------------------------------------------------------------
MutUserTime = user - GC_tot_time - PROF_VAL(RP_tot_time + HC_tot_time) - InitUserTime;
if (MutUserTime < 0) { MutUserTime = 0; }
+
+#if USE_PAPI
+ /* We stop counting mutator events
+ * GC events are not being counted at this point */
+ papi_stop_mutator_count();
+
+ /* This flag is needed, because GC is run once more after this function */
+ papi_is_reporting = 0;
+
+#endif
}
void
GC_start_faults = getPageFaults();
}
}
+
+#if USE_PAPI
+ if(papi_is_reporting) {
+ /* Switch to counting GC events */
+ papi_stop_mutator_count();
+ papi_start_gc_count();
+ }
+#endif
+
}
/* -----------------------------------------------------------------------------
debugBelch("\b\b\b \b\b\b");
rub_bell = 0;
}
+
+#if USE_PAPI
+ if(papi_is_reporting) {
+ /* Switch to counting mutator events */
+ papi_stop_gc_count();
+ papi_start_mutator_count();
+ }
+#endif
}
/* -----------------------------------------------------------------------------
TICK_TO_DBL(time - GC_tot_time -
PROF_VAL(RP_tot_time + HC_tot_time) - InitUserTime) * 100
/ TICK_TO_DBL(etime));
+#if USE_PAPI
+ /* PAPI reporting, should put somewhere else?
+ * Note that the cycles are counted _after_ the initialization of the RTS -- AR */
+
+ statsPrintf(" -- CPU Mutator counters --\n");
+ papi_mut_cycles();
+ papi_report(MutatorCounters);
+
+ statsPrintf("\n -- CPU GC counters --\n");
+ papi_gc_cycles();
+ papi_report(GCCounters);
+#endif
}
if (RtsFlags.GcFlags.giveStats == ONELINE_GC_STATS) {
statsFlush();
statsClose();
}
+ if (GC_coll_times)
+ stgFree(GC_coll_times);
+ GC_coll_times = NULL;
}
/* -----------------------------------------------------------------------------
step *step;
debugBelch(
-" Gen Steps Max Mutable Step Blocks Live Large\n"
-" Blocks Closures Objects\n");
+" Gen Steps Max Mut-list Step Blocks Live Large\n"
+" Blocks Bytes Objects\n");
mut = 0;
for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
for (bd = generations[g].mut_list; bd != NULL; bd = bd->link) {
- mut += bd->free - bd->start;
+ mut += (bd->free - bd->start) * sizeof(W_);
}
debugBelch("%8d %8d %8d %9d", g, generations[g].n_steps,
if (s != 0) {
debugBelch("%36s","");
}
- debugBelch("%6d %8d %8d %8d\n", s, step->n_blocks,
+ debugBelch("%6d %8d %8ld %8d\n", s, step->n_blocks,
live, lge);
}
}
Dumping stuff in the stats file, or via the debug message interface
-------------------------------------------------------------------------- */
-static void
+void
statsPrintf( char *s, ... )
{
FILE *sf = RtsFlags.GcFlags.statsFile;