[project @ 2005-06-06 08:49:07 by tharris]
[ghc-hetmet.git] / ghc / rts / Task.h
index b5a4dd2..b1add2f 100644 (file)
 /* -----------------------------------------------------------------------------
  *
- * (c) The GHC Team 2001-2003
+ * (c) The GHC Team 2001-2005
  *
- * Types + prototypes for functions in Task.c
- * (RTS subsystem for handling tasks, agents thay may execute STG code).
+ * Tasks
  *
  * -------------------------------------------------------------------------*/
+
 #ifndef __TASK_H__
 #define __TASK_H__
-#if defined(RTS_SUPPORTS_THREADS) /* to the end */
 
+/* Definition of a Task:
+ *
+ * A task is an OSThread that runs Haskell code.  Every OSThread
+ * created by the RTS for the purposes of running Haskell code is a
+ * Task.  We maintain information about Tasks mainly for the purposes
+ * of stats gathering.
+ *
+ * There may exist OSThreads that run Haskell code, but which aren't
+ * tasks (they don't have an associated TaskInfo structure).  This
+ * happens when a thread makes an in-call to Haskell: we don't want to
+ * create a Task for every in-call and register stats for all these
+ * threads, so it is not therefore mandatory to have a Task for every
+ * thread running Haskell code.
+ *
+ * The SMP build lets multiple tasks concurrently execute STG code,
+ * all sharing vital internal RTS data structures in a controlled manner.
+ *
+ * The 'threaded' build has at any one time only one task executing STG
+ * code, other tasks are either busy executing code outside the RTS
+ * (e.g., a C call) or waiting for their turn to (again) evaluate some
+ * STG code. A task relinquishes its RTS token when it is asked to
+ * evaluate an external (C) call.
+ */
+
+#if defined(RTS_SUPPORTS_THREADS) /* to the end */
 /* 
- * Tasks evaluate STG code; the TaskInfo structure collects together
+ * Tasks evaluate Haskell code; the TaskInfo structure collects together
  * misc metadata about a task.
- * 
  */
 typedef struct _TaskInfo {
   OSThreadId id;
-  double     elapsedtimestart;
-  double     mut_time;
-  double     mut_etime;
-  double     gc_time;
-  double     gc_etime;
+  rtsBool    is_worker;                /* rtsFalse <=> is a bound thread */
+  rtsBool    stopped;           /* this task has stopped or exited Haskell */
+  long       elapsedtimestart;
+  long       muttimestart;
+  long       mut_time;
+  long       mut_etime;
+  long       gc_time;
+  long       gc_etime;
 } TaskInfo;
 
-extern TaskInfo *taskIds;
+extern TaskInfo *taskTable;
+extern nat taskCount;
 
-extern void startTaskManager ( nat maxTasks, void (*taskStart)(void) );
-extern void stopTaskManager ( void );
-extern void resetTaskManagerAfterFork ( void );
+/*
+ * Start and stop the task manager.
+ * Requires: sched_mutex.
+ */
+extern void initTaskManager (void);
+extern void stopTaskManager (void);
 
-extern rtsBool startTask ( void (*taskStart)(void) );
+/*
+ * Two ways to start tasks: either singly or in a batch
+ * Requires: sched_mutex.
+ */
+extern rtsBool startTasks (nat num, void (*taskStart)(void));
+extern rtsBool startTask  (void (*taskStart)(void));
+
+/*
+ * Notify the task manager that a task has stopped.  This is used
+ * mainly for stats-gathering purposes.
+ * Requires: sched_mutex.
+ */
+extern void taskStop (void);
+
+/*
+ * After a fork, the tasks are not carried into the child process, so
+ * we must tell the task manager.
+ * Requires: sched_mutex.
+ */
+extern void resetTaskManagerAfterFork (void);
+
+/*
+ * Tell the task manager that the current OS thread is now a task,
+ * because it has entered Haskell as a bound thread.
+ * Requires: sched_mutex.
+ */
+extern TaskInfo* threadIsTask (OSThreadId id);
+
+/*
+ * Get the TaskInfo structure corresponding to an OSThread.  Returns
+ * NULL if the thread is not a task.
+ * Requires: sched_mutex.
+ */
+extern TaskInfo* taskOfId (OSThreadId id);
+
+/*
+ * Decides whether to call startTask() or not, based on how many
+ * workers are already running and waiting for work.  Returns
+ * rtsTrue if a worker was created.
+ * Requires: sched_mutex.
+ */
+extern rtsBool maybeStartNewWorker (void (*taskStart)(void));
 
 #endif /* RTS_SUPPORTS_THREADS */
 #endif /* __TASK_H__ */