summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsimonmar@microsoft.com <unknown>2008-02-28 15:23:32 +0000
committersimonmar@microsoft.com <unknown>2008-02-28 15:23:32 +0000
commit65bb9b5ae78ee29100ea6bf5617b0fdbc0a100bd (patch)
tree83ee93ebf3227e25714f353fb073a8789f28d666
parent9b0be04d7d23a4ccce0275f3a7c519d9b614f3a2 (diff)
downloadhaskell-65bb9b5ae78ee29100ea6bf5617b0fdbc0a100bd.tar.gz
Updating a thunk in raiseAsync might encounter an IND; cope
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.
-rw-r--r--rts/RaiseAsync.c21
-rw-r--r--rts/Updates.h5
2 files changed, 9 insertions, 17 deletions
diff --git a/rts/RaiseAsync.c b/rts/RaiseAsync.c
index ee53e0d0a6..21bc78ec75 100644
--- a/rts/RaiseAsync.c
+++ b/rts/RaiseAsync.c
@@ -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;
diff --git a/rts/Updates.h b/rts/Updates.h
index 3461c91144..c04005b49b 100644
--- a/rts/Updates.h
+++ b/rts/Updates.h
@@ -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; \