struct TRACE_FLAGS {
rtsBool sched; /* trace scheduler events for profiling */
+ rtsBool gc; /* trace GC events */
rtsBool timestamp; /* add timestamps to traces */
};
RtsFlags.TraceFlags.timestamp = rtsFalse;
RtsFlags.TraceFlags.sched = rtsFalse;
+ RtsFlags.TraceFlags.gc = rtsFalse;
#ifdef USE_PAPI
/* By default no special measurements taken */
case 's':
RtsFlags.TraceFlags.sched = rtsTrue;
break;
+ case 'g':
+ RtsFlags.TraceFlags.gc = rtsTrue;
+ break;
default:
errorBelch("unknown RTS option: %s",rts_argv[arg]);
error = rtsTrue;
Produce some detailed info on the state of the generational GC.
-------------------------------------------------------------------------- */
-#ifdef DEBUG
void
statDescribeGens(void)
{
}
debugBelch("\n");
}
-#endif
/* -----------------------------------------------------------------------------
Stats available via a programmatic interface, so eg. GHCi can time
GRAN_FLAG(blockedOnFetch_sanity, GRAN_DEBUG_BOF_sanity);
TRACE_FLAG(sched, TRACE_sched);
+ TRACE_FLAG(gc, TRACE_gc);
}
static void tracePreface (void)
#define DEBUG_par (1<<11)
#define DEBUG_linker (1<<12)
#define DEBUG_squeeze (1<<13)
+#define DEBUG_hpc (1<<14)
-
-
-// Profiling flags
-#define TRACE_sched (1<<29)
-
-// Coverge flags
-#define DEBUG_hpc (1<<30)
+// Tracing flags
+#define TRACE_sched (1<<20)
+#define TRACE_gc (1<<21)
// -----------------------------------------------------------------------------
// PRIVATE below here
inc_running();
wakeup_gc_threads(n_gc_threads);
- // Initialise stats
- copied = 0;
-
// this is the main thread
gct = gc_threads[0];
/* run through all the generations/steps and tidy up
*/
+ copied = 0;
+ {
+ nat i;
+ for (i=0; i < n_gc_threads; i++) {
+ if (major_gc) {
+ trace(TRACE_gc,"thread %d:", i);
+ trace(TRACE_gc," copied %ld", gc_threads[i]->copied * sizeof(W_));
+ trace(TRACE_gc," any_work %ld", gc_threads[i]->any_work);
+ trace(TRACE_gc," scav_global_work %ld", gc_threads[i]->scav_global_work);
+ trace(TRACE_gc," scav_local_work %ld", gc_threads[i]->scav_local_work);
+ }
+ copied += gc_threads[i]->copied;
+ }
+ }
+
for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
if (g <= N) {
IF_DEBUG(sanity, checkSanity());
// extra GC trace info
- IF_DEBUG(gc, statDescribeGens());
+ if (traceClass(TRACE_gc)) statDescribeGens();
#ifdef DEBUG
// symbol-table based profiling
t->failed_to_evac = rtsFalse;
t->eager_promotion = rtsTrue;
t->thunk_selector_depth = 0;
+ t->copied = 0;
+ t->any_work = 0;
+ t->scav_global_work = 0;
+ t->scav_local_work = 0;
}
/* -----------------------------------------------------------------------------
#endif
// -------------------
+ // stats
+
+ lnat copied;
+ lnat any_work;
+ lnat scav_global_work;
+ lnat scav_local_work;
+
+ // -------------------
// workspaces
// array of workspaces, indexed by stp->abs_no. This is placed
ASSERT(bd->link == NULL);
// update stats: this is a block that has been copied & scavenged
- copied += bd->free - bd->start;
+ gct->copied += bd->free - bd->start;
// put the scan block on the ws->scavd_list.
bd->link = ws->scavd_list;
rtsBool flag;
step_workspace *ws;
+ gct->scav_global_work++;
+
flag = rtsFalse;
for (s = total_steps-1; s>=0; s--)
{
step_workspace *ws;
rtsBool flag;
+ gct->scav_local_work++;
+
flag = rtsFalse;
for (s = total_steps-1; s >= 0; s--) {
if (s == 0 && RtsFlags.GcFlags.generations > 1) {
int s;
step_workspace *ws;
+ gct->any_work++;
+
write_barrier();
// scavenge static objects