summaryrefslogtreecommitdiff
path: root/rts/Stats.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2012-03-02 10:53:34 +0000
committerSimon Marlow <marlowsd@gmail.com>2012-03-02 11:44:17 +0000
commit085c7fe5d4ea6e7b59f944d46ecfeba3755a315b (patch)
tree3de7e3e6306dbf9a8869862266a35a2d0d75d11f /rts/Stats.c
parent27d7d930ff8741f980245da1b895ceaa5294e257 (diff)
downloadhaskell-085c7fe5d4ea6e7b59f944d46ecfeba3755a315b.tar.gz
Drop the per-task timing stats, give a summary only (#5897)
We were keeping around the Task struct (216 bytes) for every worker we ever created, even though we only keep a maximum of 6 workers per Capability. These Task structs accumulate and cause a space leak in programs that do lots of safe FFI calls; this patch frees the Task struct as soon as a worker exits. One reason we were keeping the Task structs around is because we print out per-Task timing stats in +RTS -s, but that isn't terribly useful. What is sometimes useful is knowing how *many* Tasks there were. So now I'm printing a single-line summary, this is for the program in TASKS: 2001 (1 bound, 31 peak workers (2000 total), using -N1) So although we created 2k tasks overall, there were only 31 workers active at any one time (which is exactly what we expect: the program makes 30 safe FFI calls concurrently). This also gives an indication of how many capabilities were being used, which is handy if you use +RTS -N without an explicit number.
Diffstat (limited to 'rts/Stats.c')
-rw-r--r--rts/Stats.c42
1 files changed, 19 insertions, 23 deletions
diff --git a/rts/Stats.c b/rts/Stats.c
index 83c43f0bdd..2c7c35d533 100644
--- a/rts/Stats.c
+++ b/rts/Stats.c
@@ -287,18 +287,29 @@ stat_startGC (gc_thread *gct)
}
void
-stat_gcWorkerThreadStart (gc_thread *gct)
+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)
+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)
@@ -311,6 +322,7 @@ stat_gcWorkerThreadDone (gc_thread *gct)
taskDoneGC(gct->cap->running_task, gc_cpu, gc_elapsed);
}
+#endif
}
/* -----------------------------------------------------------------------------
@@ -326,17 +338,13 @@ stat_endGC (gc_thread *gct,
RtsFlags.ProfFlags.doHeapProfile)
// heap profiling needs GC_tot_time
{
- Time cpu, elapsed, thread_gc_cpu, gc_cpu, gc_elapsed;
+ Time cpu, elapsed, 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();
@@ -629,22 +637,10 @@ stat_exit(int alloc)
statsPrintf("\n");
#if defined(THREADED_RTS)
- {
- nat i;
- Task *task;
- statsPrintf(" MUT time (elapsed) GC time (elapsed)\n");
- for (i = 0, task = all_tasks;
- task != NULL;
- i++, task = task->all_link) {
- statsPrintf(" Task %2d %-8s : %6.2fs (%6.2fs) %6.2fs (%6.2fs)\n",
- i,
- (task->worker) ? "(worker)" : "(bound)",
- TimeToSecondsDbl(task->mut_time),
- TimeToSecondsDbl(task->mut_etime),
- TimeToSecondsDbl(task->gc_time),
- TimeToSecondsDbl(task->gc_etime));
- }
- }
+ statsPrintf(" TASKS: %d (%d bound, %d peak workers (%d total), using -N%d)\n",
+ taskCount, taskCount - workerCount,
+ peakWorkerCount, workerCount,
+ n_capabilities);
statsPrintf("\n");