[project @ 2005-10-27 15:26:06 by simonmar]
[ghc-hetmet.git] / ghc / rts / Capability.c
index d30d5bc..7aacc24 100644 (file)
@@ -142,6 +142,10 @@ initCapability( Capability *cap, nat i )
 
     cap->f.stgGCEnter1     = (F_)__stg_gc_enter_1;
     cap->f.stgGCFun        = (F_)__stg_gc_fun;
+
+    cap->mut_lists  = stgMallocBytes(sizeof(bdescr *) * 
+                                    RtsFlags.GcFlags.generations,
+                                    "initCapability");
 }
 
 /* ---------------------------------------------------------------------------
@@ -227,12 +231,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 +401,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 +468,9 @@ yieldCapability (Capability** pCap, Task *task)
     }
 
     *pCap = cap;
+
+    ASSERT_CAPABILITY_INVARIANTS(cap,task);
+
     return;
 }
 
@@ -570,6 +576,29 @@ shutdownCapability (Capability *cap, Task *task)
     // list are both empty.
 }
 
+/* ----------------------------------------------------------------------------
+ * tryGrabCapability
+ *
+ * Attempt to gain control of a Capability if it is free.
+ * 
+ * ------------------------------------------------------------------------- */
+
+rtsBool
+tryGrabCapability (Capability *cap, Task *task)
+{
+    if (cap->running_task != NULL) return rtsFalse;
+    ACQUIRE_LOCK(&cap->lock);
+    if (cap->running_task != NULL) {
+       RELEASE_LOCK(&cap->lock);
+       return rtsFalse;
+    }
+    task->cap = cap;
+    cap->running_task = task;
+    RELEASE_LOCK(&cap->lock);
+    return rtsTrue;
+}
+
+
 #endif /* THREADED_RTS */