summaryrefslogtreecommitdiff
path: root/rts/Task.h
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/Task.h
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/Task.h')
-rw-r--r--rts/Task.h30
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: