+/************ THREADS version *****************/
+
+void
+startTaskManager( nat maxCount, void (*taskStart)(void) )
+{
+ /* In the threaded case, maxCount is used to limit the
+ the creation of worker tasks. Tasks are created lazily, i.e.,
+ when the current task gives up the token on executing
+ STG code.
+ */
+ maxTasks = maxCount;
+ taskCount = 0;
+ tasksAvailable = 0;
+}
+
+void
+startTask ( void (*taskStart)(void) )
+{
+ int r;
+ OSThreadId tid;
+
+ /* Locks assumed: rts_mutex */
+
+ /* If there are threads known to be waiting to do
+ useful work, no need to create a new task. */
+ if (tasksAvailable > 0) {
+ IF_DEBUG(scheduler,fprintf(stderr,"scheduler: startTask: %d tasks available, not creating new one.\n",tasksAvailable););
+ return;
+ }
+
+ /* If the task limit has been reached, just return. */
+ if (maxTasks > 0 && taskCount == maxTasks) {
+ IF_DEBUG(scheduler,fprintf(stderr,"scheduler: startTask: task limit (%d) reached, not creating new one.\n",maxTasks));
+ return;
+ }
+
+
+ r = createOSThread(&tid,taskStart);
+ if (r != 0) {
+ barf("startTask: Can't create new task");
+ }
+ taskCount++;
+ tasksAvailable++;
+
+ IF_DEBUG(scheduler,fprintf(stderr,"scheduler: Started task (%d): %ld\n", taskCount, tid););
+ return;
+}
+
+/*
+ * When the RTS thread ends up performing a call-out,
+ * we need to know whether there'll be other tasks/threads
+ * to take over RTS responsibilities. The 'tasksAvailable'
+ * variable holds the number of threads that are _blocked
+ * waiting to enter the RTS_ (or soon will be). Equipped
+ * with that count, startTask() is able to make an informed
+ * decision on whether or not to create a new thread.
+ *
+ * Two functions control increments / decrements of
+ * 'tasksAvailable':
+ *
+ * - taskNotAvailable() : called whenever a task/thread
+ * has acquired the RTS lock, i.e., always called by
+ * a thread that holds the rts_mutex lock.
+ *
+ * - taskAvailable(): called whenever a task/thread
+ * is about to try to grab the RTS lock. The task manager
+ * and scheduler will only call this whenever it is
+ * in possession of the rts_mutex lock, i.e.,
+ * - when a new task is created in startTask().
+ * - when the scheduler gives up the RTS token to
+ * let threads waiting to return from an external
+ * call continue.
+ *
+ */
+void
+taskNotAvailable()
+{
+ if (tasksAvailable > 0) {
+ tasksAvailable--;
+ }
+ return;
+}
+
+void
+taskAvailable()
+{
+ tasksAvailable++;
+ return;
+}
+
+
+