Updating a thunk in raiseAsync might encounter an IND; cope
authorsimonmar@microsoft.com <unknown>
Thu, 28 Feb 2008 15:23:32 +0000 (15:23 +0000)
committersimonmar@microsoft.com <unknown>
Thu, 28 Feb 2008 15:23:32 +0000 (15:23 +0000)
There was already a check to avoid updating an IND, but it was
originally there to avoid a bug which doesn't exist now.  Furthermore
the test and update are not atomic, so another thread could be
updating this thunk while we are.  We have to just go ahead and update
anyway - it might waste a little work, but this is a very rare case.

rts/RaiseAsync.c
rts/Updates.h

index ee53e0d..21bc78e 100644 (file)
@@ -944,21 +944,12 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception,
            //       printObj((StgClosure *)ap);
            //  );
 
-           // Replace the updatee with an indirection
-           //
-           // Warning: if we're in a loop, more than one update frame on
-           // the stack may point to the same object.  Be careful not to
-           // overwrite an IND_OLDGEN in this case, because we'll screw
-           // up the mutable lists.  To be on the safe side, don't
-           // overwrite any kind of indirection at all.  See also
-           // threadSqueezeStack in GC.c, where we have to make a similar
-           // check.
-           //
-           if (!closure_IND(((StgUpdateFrame *)frame)->updatee)) {
-               // revert the black hole
-               UPD_IND_NOLOCK(((StgUpdateFrame *)frame)->updatee,
-                              (StgClosure *)ap);
-           }
+            // Perform the update
+            // TODO: this may waste some work, if the thunk has
+            // already been updated by another thread.
+            UPD_IND_NOLOCK(((StgUpdateFrame *)frame)->updatee,
+                           (StgClosure *)ap);
+
            sp += sizeofW(StgUpdateFrame) - 1;
            sp[0] = (W_)ap; // push onto stack
            frame = sp + 1;
index 3461c91..c04005b 100644 (file)
@@ -280,8 +280,9 @@ no_slop:
   {                                                            \
     bdescr *bd;                                                        \
                                                                \
-    /* cas(p1, 0, &stg_WHITEHOLE_info); */                     \
-    ASSERT( (P_)p1 != (P_)p2 && !closure_IND(p1) );            \
+    ASSERT( (P_)p1 != (P_)p2 );                                 \
+    /* not necessarily true: ASSERT( !closure_IND(p1) ); */     \
+    /* occurs in RaiseAsync.c:raiseAsync() */                   \
     DEBUG_FILL_SLOP(p1);                                       \
     LDV_RECORD_DEAD_FILL_SLOP_DYNAMIC(p1);                     \
     ((StgInd *)p1)->indirectee = p2;                           \