diff options
author | Simon Marlow <simonmar@microsoft.com> | 2007-03-06 14:27:32 +0000 |
---|---|---|
committer | Simon Marlow <simonmar@microsoft.com> | 2007-03-06 14:27:32 +0000 |
commit | a1e3066e066f0f75da361f881b2f3198e0aada5f (patch) | |
tree | e2ca414a40012511a0f72a83aafe4593cf127907 /rts/ThreadPaused.c | |
parent | d5b20065218f2650a60cafd179a318e98c080f05 (diff) | |
download | haskell-a1e3066e066f0f75da361f881b2f3198e0aada5f.tar.gz |
THREADED_RTS: use cas() when claiming thunks
I guess I forgot to do this the first time around; the upshot is that
there could be some uncaught duplication of work on a multiprocessor
(but unlikely).
Diffstat (limited to 'rts/ThreadPaused.c')
-rw-r--r-- | rts/ThreadPaused.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/rts/ThreadPaused.c b/rts/ThreadPaused.c index e76d70fbd5..5b64f76ff2 100644 --- a/rts/ThreadPaused.c +++ b/rts/ThreadPaused.c @@ -178,6 +178,8 @@ threadPaused(Capability *cap, StgTSO *tso) { StgClosure *frame; StgRetInfoTable *info; + const StgInfoTable *bh_info; + const StgInfoTable *cur_bh_info USED_IF_THREADS; StgClosure *bh; StgPtr stack_end; nat words_to_squeeze = 0; @@ -212,8 +214,13 @@ threadPaused(Capability *cap, StgTSO *tso) SET_INFO(frame, (StgInfoTable *)&stg_marked_upd_frame_info); bh = ((StgUpdateFrame *)frame)->updatee; + bh_info = bh->header.info; - if (closure_IND(bh) || bh->header.info == &stg_BLACKHOLE_info) { +#ifdef THREADED_RTS + retry: +#endif + if (closure_flags[INFO_PTR_TO_STRUCT(bh_info)->type] & _IND + || bh_info == &stg_BLACKHOLE_info) { debugTrace(DEBUG_squeeze, "suspending duplicate work: %ld words of stack", (long)((StgPtr)frame - tso->sp)); @@ -246,7 +253,20 @@ threadPaused(Capability *cap, StgTSO *tso) // We pretend that bh is now dead. LDV_recordDead_FILL_SLOP_DYNAMIC((StgClosure *)bh); #endif + +#ifdef THREADED_RTS + cur_bh_info = (const StgInfoTable *) + cas((StgVolatilePtr)&bh->header.info, + (StgWord)bh_info, + (StgWord)&stg_BLACKHOLE_info); + + if (cur_bh_info != bh_info) { + bh_info = cur_bh_info; + goto retry; + } +#else SET_INFO(bh,&stg_BLACKHOLE_info); +#endif // We pretend that bh has just been created. LDV_RECORD_CREATE(bh); |