summaryrefslogtreecommitdiff
path: root/rts/ThreadPaused.c
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2007-03-06 14:27:32 +0000
committerSimon Marlow <simonmar@microsoft.com>2007-03-06 14:27:32 +0000
commita1e3066e066f0f75da361f881b2f3198e0aada5f (patch)
treee2ca414a40012511a0f72a83aafe4593cf127907 /rts/ThreadPaused.c
parentd5b20065218f2650a60cafd179a318e98c080f05 (diff)
downloadhaskell-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.c22
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);