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/Task.h | |
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/Task.h')
-rw-r--r-- | rts/Task.h | 30 |
1 files changed, 7 insertions, 23 deletions
diff --git a/rts/Task.h b/rts/Task.h index 59a316bd81..ab47a07fc3 100644 --- a/rts/Task.h +++ b/rts/Task.h @@ -143,25 +143,13 @@ typedef struct Task_ { // So that we can detect when a finalizer illegally calls back into Haskell rtsBool running_finalizers; - // Stats that we collect about this task - // ToDo: we probably want to put this in a separate TaskStats - // structure, so we can share it between multiple Tasks. We don't - // really want separate stats for each call in a nested chain of - // foreign->haskell->foreign->haskell calls, but we'll get a - // separate Task for each of the haskell calls. - Time elapsedtimestart; - Time muttimestart; - Time mut_time; - Time mut_etime; - Time gc_time; - Time gc_etime; - // Links tasks on the returning_tasks queue of a Capability, and // on spare_workers. struct Task_ *next; // Links tasks on the all_tasks list - struct Task_ *all_link; + struct Task_ *all_next; + struct Task_ *all_prev; } Task; @@ -201,15 +189,6 @@ void boundTaskExiting (Task *task); void workerTaskStop (Task *task); #endif -// Record the time spent in this Task. -// This is called by workerTaskStop() but not by boundTaskExiting(), -// because it would impose an extra overhead on call-in. -// -void taskTimeStamp (Task *task); - -// The current Task has finished a GC, record the amount of time spent. -void taskDoneGC (Task *task, Time cpu_time, Time elapsed_time); - // Put the task back on the free list, mark it stopped. Used by // forkProcess(). // @@ -240,6 +219,11 @@ void interruptWorkerTask (Task *task); // void updateCapabilityRefs (void); +// For stats +extern nat taskCount; +extern nat workerCount; +extern nat peakWorkerCount; + // ----------------------------------------------------------------------------- // INLINE functions... private from here on down: |