diff options
author | Simon Marlow <marlowsd@gmail.com> | 2012-03-02 10:53:34 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2012-03-02 11:44:17 +0000 |
commit | 085c7fe5d4ea6e7b59f944d46ecfeba3755a315b (patch) | |
tree | 3de7e3e6306dbf9a8869862266a35a2d0d75d11f /rts/Stats.c | |
parent | 27d7d930ff8741f980245da1b895ceaa5294e257 (diff) | |
download | haskell-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.c | 42 |
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"); |