[project @ 2005-11-04 12:02:04 by simonmar]
[ghc-hetmet.git] / ghc / rts / Schedule.c
index 2bc7472..d3851eb 100644 (file)
@@ -47,6 +47,9 @@
 #include "Capability.h"
 #include "Task.h"
 #include "AwaitEvent.h"
+#if defined(mingw32_HOST_OS)
+#include "win32/IOManager.h"
+#endif
 
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
@@ -189,7 +192,7 @@ rtsBool shutting_down_scheduler = rtsFalse;
  * the THREADED_RTS and (inc. SMP) runtime.
  */
 #if defined(THREADED_RTS)
-Mutex sched_mutex = INIT_MUTEX_VAR;
+Mutex sched_mutex;
 #endif
 
 #if defined(PARALLEL_HASKELL)
@@ -210,8 +213,10 @@ static Capability *schedule (Capability *initialCapability, Task *task);
 // scheduler clearer.
 //
 static void schedulePreLoop (void);
+#if defined(SMP)
 static void schedulePushWork(Capability *cap, Task *task);
-static void scheduleStartSignalHandlers (void);
+#endif
+static void scheduleStartSignalHandlers (Capability *cap);
 static void scheduleCheckBlockedThreads (Capability *cap);
 static void scheduleCheckBlackHoles (Capability *cap);
 static void scheduleDetectDeadlock (Capability *cap, Task *task);
@@ -340,7 +345,9 @@ schedule (Capability *initialCapability, Task *task)
 #endif
   nat prev_what_next;
   rtsBool ready_to_gc;
+#if defined(THREADED_RTS)
   rtsBool first = rtsTrue;
+#endif
   
   cap = initialCapability;
 
@@ -413,7 +420,7 @@ schedule (Capability *initialCapability, Task *task)
            // If we are a worker, just exit.  If we're a bound thread
            // then we will exit below when we've removed our TSO from
            // the run queue.
-           if (task->tso == NULL) {
+           if (task->tso == NULL && emptyRunQueue(cap)) {
                return cap;
            }
        } else {
@@ -443,7 +450,7 @@ schedule (Capability *initialCapability, Task *task)
     }
 #endif // SMP
 
-    scheduleStartSignalHandlers();
+    scheduleStartSignalHandlers(cap);
 
     // Only check the black holes here if we've nothing else to do.
     // During normal execution, the black hole list only gets checked
@@ -722,10 +729,11 @@ schedulePreLoop(void)
  * Push work to other Capabilities if we have some.
  * -------------------------------------------------------------------------- */
 
+#ifdef SMP
 static void
-schedulePushWork(Capability *cap, Task *task)
+schedulePushWork(Capability *cap USED_WHEN_SMP, 
+                Task *task      USED_WHEN_SMP)
 {
-#ifdef SMP
     Capability *free_caps[n_capabilities], *cap0;
     nat i, n_free_caps;
 
@@ -771,7 +779,8 @@ schedulePushWork(Capability *cap, Task *task)
        for (; t != END_TSO_QUEUE; t = next) {
            next = t->link;
            t->link = END_TSO_QUEUE;
-           if (t->what_next == ThreadRelocated) {
+           if (t->what_next == ThreadRelocated
+               || t->bound == task) { // don't move my bound thread
                prev->link = t;
                prev = t;
            } else if (i == n_free_caps) {
@@ -794,19 +803,19 @@ schedulePushWork(Capability *cap, Task *task)
        }
     }
     task->cap = cap; // reset to point to our Capability.
-#endif
 }
+#endif
 
 /* ----------------------------------------------------------------------------
  * Start any pending signal handlers
  * ------------------------------------------------------------------------- */
 
 static void
-scheduleStartSignalHandlers(void)
+scheduleStartSignalHandlers(Capability *cap)
 {
-#if defined(RTS_USER_SIGNALS) && !defined(THREADED_RTS)
+#if defined(RTS_USER_SIGNALS) && (!defined(THREADED_RTS) || defined(mingw32_HOST_OS))
     if (signals_pending()) { // safe outside the lock
-       startSignalHandlers();
+       startSignalHandlers(cap);
     }
 #endif
 }
@@ -892,7 +901,7 @@ scheduleDetectDeadlock (Capability *cap, Task *task)
        
        if ( !emptyRunQueue(cap) ) return;
 
-#if defined(RTS_USER_SIGNALS) && !defined(THREADED_RTS)
+#if defined(RTS_USER_SIGNALS) && (!defined(THREADED_RTS) || defined(mingw32_HOST_OS))
        /* If we have user-installed signal handlers, then wait
         * for signals to arrive rather then bombing out with a
         * deadlock.
@@ -904,7 +913,7 @@ scheduleDetectDeadlock (Capability *cap, Task *task)
            awaitUserSignals();
 
            if (signals_pending()) {
-               startSignalHandlers();
+               startSignalHandlers(cap);
            }
 
            // either we have threads to run, or we were interrupted:
@@ -1554,11 +1563,10 @@ scheduleHandleStackOverflow (Capability *cap, Task *task, StgTSO *t)
        /* enlarge the stack */
        StgTSO *new_t = threadStackOverflow(cap, t);
        
-       /* This TSO has moved, so update any pointers to it from the
-        * main thread stack.  It better not be on any other queues...
-        * (it shouldn't be).
+       /* The TSO attached to this Task may have moved, so update the
+        * pointer to it.
         */
-       if (task->tso != NULL) {
+       if (task->tso == t) {
            task->tso = new_t;
        }
        pushOnRunQueue(cap,new_t);
@@ -2863,7 +2871,7 @@ threadStackOverflow(Capability *cap, StgTSO *tso)
   new_tso_size = round_to_mblocks(new_tso_size);  /* Be MBLOCK-friendly */
   new_stack_size = new_tso_size - TSO_STRUCT_SIZEW;
 
-  IF_DEBUG(scheduler, sched_belch("increasing stack size from %ld words to %d.\n", tso->stack_size, new_stack_size));
+  IF_DEBUG(scheduler, sched_belch("increasing stack size from %ld words to %d.\n", (long)tso->stack_size, new_stack_size));
 
   dest = (StgTSO *)allocate(new_tso_size);
   TICK_ALLOC_TSO(new_stack_size,0);