[project @ 2005-10-26 15:36:06 by simonmar]
authorsimonmar <unknown>
Wed, 26 Oct 2005 15:36:06 +0000 (15:36 +0000)
committersimonmar <unknown>
Wed, 26 Oct 2005 15:36:06 +0000 (15:36 +0000)
Package up the various properties of Capabilities/Tasks that we were
asserting all over the place, and put them in a single macro
ASSERT_CAPABILITY_INVARIANTS().

ghc/rts/Capability.c
ghc/rts/Capability.h
ghc/rts/RtsAPI.c
ghc/rts/Schedule.c

index d30d5bc..cb921d1 100644 (file)
@@ -227,12 +227,11 @@ releaseCapability_ (Capability* cap)
 {
     Task *task;
 
-    ASSERT(cap->running_task != NULL && myTask() == cap->running_task);
-
     task = cap->running_task;
-    cap->running_task = NULL;
 
-    ASSERT(task->id == osThreadId());
+    ASSERT_CAPABILITY_INVARIANTS(cap,task);
+
+    cap->running_task = NULL;
 
     // Check to see whether a worker thread can be given
     // the go-ahead to return the result of an external call..
@@ -398,7 +397,7 @@ waitForReturnCapability (Capability **pCap,
 
     }
 
-    ASSERT(cap->running_task == task);
+    ASSERT_CAPABILITY_INVARIANTS(cap,task);
 
     IF_DEBUG(scheduler, 
             sched_belch("returning; got capability %d", cap->no));
@@ -465,6 +464,9 @@ yieldCapability (Capability** pCap, Task *task)
     }
 
     *pCap = cap;
+
+    ASSERT_CAPABILITY_INVARIANTS(cap,task);
+
     return;
 }
 
index 5b96019..b559dcd 100644 (file)
@@ -77,6 +77,17 @@ struct Capability_ {
 #endif
 }; // typedef Capability, defined in RtsAPI.h
 
+
+// These properties should be true when a Task is holding a Capability
+#define ASSERT_CAPABILITY_INVARIANTS(cap,task)                         \
+  ASSERT(cap->running_task != NULL && cap->running_task == task);      \
+  ASSERT(task->cap == cap);                                            \
+  ASSERT(cap->run_queue_hd == END_TSO_QUEUE ?                          \
+           cap->run_queue_tl == END_TSO_QUEUE : 1);                    \
+  ASSERT(myTask() == task);                                            \
+  ASSERT(task->id == osThreadId());
+
+
 // Converts a *StgRegTable into a *Capability.
 //
 INLINE_HEADER Capability *
index 45c09d8..dec0db1 100644 (file)
@@ -578,7 +578,7 @@ rts_unlock (Capability *cap)
     Task *task;
 
     task = cap->running_task;
-    ASSERT(task == myTask());
+    ASSERT_CAPABILITY_INVARIANTS(cap,task);
 
     // slightly delicate ordering of operations below, pay attention!
 
index 7af3ab5..0de7679 100644 (file)
@@ -379,16 +379,13 @@ schedule (Capability *initialCapability, Task *task)
          // thread for a bit, even if there are others banging at the
          // door.
          first = rtsFalse;
+         ASSERT_CAPABILITY_INVARIANTS(cap,task);
       } else {
          // Yield the capability to higher-priority tasks if necessary.
          yieldCapability(&cap, task);
       }
 #endif
       
-      ASSERT(cap->running_task == task);
-      ASSERT(task->cap == cap);
-      ASSERT(myTask() == task);
-
     // Check whether we have re-entered the RTS from Haskell without
     // going via suspendThread()/resumeThread (i.e. a 'safe' foreign
     // call).
@@ -612,9 +609,7 @@ run_thread:
     if (ret == ThreadBlocked) continue;
 #endif
 
-    ASSERT(cap->running_task == task);
-    ASSERT(task->cap == cap);
-    ASSERT(myTask() == task);
+    ASSERT_CAPABILITY_INVARIANTS(cap,task);
 
     // The TSO might have moved, eg. if it re-entered the RTS and a GC
     // happened.  So find the new location:
@@ -2463,8 +2458,7 @@ scheduleWaitThread (StgTSO* tso, /*[out]*/HaskellObj* ret, Capability *cap)
     cap = schedule(cap,task);
 
     ASSERT(task->stat != NoStatus);
-    ASSERT(cap->running_task == task);
-    ASSERT(task->cap == cap);
+    ASSERT_CAPABILITY_INVARIANTS(cap,task);
 
     IF_DEBUG(scheduler, sched_belch("bound thread (%d) finished", task->tso->id));
     return cap;