summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
Diffstat (limited to 'rts/sm')
-rw-r--r--rts/sm/Storage.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c
index b5f3202887..755b3d9f00 100644
--- a/rts/sm/Storage.c
+++ b/rts/sm/Storage.c
@@ -333,9 +333,12 @@ freeStorage (rtsBool free_heap)
-------------------------------------------------------------------------- */
-STATIC_INLINE StgWord lockCAF (StgIndStatic *caf, StgClosure *bh)
+STATIC_INLINE StgInd *
+lockCAF (StgRegTable *reg, StgIndStatic *caf)
{
const StgInfoTable *orig_info;
+ Capability *cap = regTableToCapability(reg);
+ StgInd *bh;
orig_info = caf->header.info;
@@ -345,7 +348,7 @@ STATIC_INLINE StgWord lockCAF (StgIndStatic *caf, StgClosure *bh)
if (orig_info == &stg_IND_STATIC_info ||
orig_info == &stg_WHITEHOLE_info) {
// already claimed by another thread; re-enter the CAF
- return 0;
+ return NULL;
}
cur_info = (const StgInfoTable *)
@@ -355,7 +358,7 @@ STATIC_INLINE StgWord lockCAF (StgIndStatic *caf, StgClosure *bh)
if (cur_info != orig_info) {
// already claimed by another thread; re-enter the CAF
- return 0;
+ return NULL;
}
// successfully claimed by us; overwrite with IND_STATIC
@@ -364,17 +367,25 @@ STATIC_INLINE StgWord lockCAF (StgIndStatic *caf, StgClosure *bh)
// For the benefit of revertCAFs(), save the original info pointer
caf->saved_info = orig_info;
- caf->indirectee = bh;
+ // Allocate the blackhole indirection closure
+ bh = (StgInd *)allocate(cap, sizeofW(*bh));
+ SET_HDR(bh, &stg_CAF_BLACKHOLE_info, caf->header.prof.ccs);
+ bh->indirectee = (StgClosure *)cap->r.rCurrentTSO;
+
+ caf->indirectee = (StgClosure *)bh;
write_barrier();
SET_INFO((StgClosure*)caf,&stg_IND_STATIC_info);
- return 1;
+ return bh;
}
-StgWord
-newCAF(StgRegTable *reg, StgIndStatic *caf, StgClosure *bh)
+StgInd *
+newCAF(StgRegTable *reg, StgIndStatic *caf)
{
- if (lockCAF(caf,bh) == 0) return 0;
+ StgInd *bh;
+
+ bh = lockCAF(reg, caf);
+ if (!bh) return NULL;
if(keepCAFs)
{
@@ -418,7 +429,7 @@ newCAF(StgRegTable *reg, StgIndStatic *caf, StgClosure *bh)
#endif
}
- return 1;
+ return bh;
}
// External API for setting the keepCAFs flag. see #3900.
@@ -437,10 +448,13 @@ setKeepCAFs (void)
//
// The linker hackily arranges that references to newCaf from dynamic
// code end up pointing to newDynCAF.
-StgWord
-newDynCAF (StgRegTable *reg STG_UNUSED, StgIndStatic *caf, StgClosure *bh)
+StgInd *
+newDynCAF (StgRegTable *reg, StgIndStatic *caf)
{
- if (lockCAF(caf,bh) == 0) return 0;
+ StgInd *bh;
+
+ bh = lockCAF(reg, caf);
+ if (!bh) return NULL;
ACQUIRE_SM_LOCK;
@@ -449,7 +463,7 @@ newDynCAF (StgRegTable *reg STG_UNUSED, StgIndStatic *caf, StgClosure *bh)
RELEASE_SM_LOCK;
- return 1;
+ return bh;
}
/* -----------------------------------------------------------------------------