summaryrefslogtreecommitdiff
path: root/rts
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2008-09-08 14:56:52 +0000
committerSimon Marlow <marlowsd@gmail.com>2008-09-08 14:56:52 +0000
commit3e7ebef1f18e2718dd37f47613694de9ebf80ae2 (patch)
tree0018183776e67b09d0fd0b28506cd546491f1089 /rts
parentfef454a0f84acdf9e4efbce6425a04fbbb577dbe (diff)
downloadhaskell-3e7ebef1f18e2718dd37f47613694de9ebf80ae2.tar.gz
Fix parallel GC bug (crash in concprog001(threaded2))
Two threads were trying to move the same TSO. I like this test, it has caught plenty of bugs in the past.
Diffstat (limited to 'rts')
-rw-r--r--rts/sm/Evac.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c
index 6bf0c56843..f537e2b9a3 100644
--- a/rts/sm/Evac.c
+++ b/rts/sm/Evac.c
@@ -165,7 +165,7 @@ copy_tag_nolock(StgClosure **p, const StgInfoTable *info,
* pointer of an object, but reserve some padding after it. This is
* used to optimise evacuation of BLACKHOLEs.
*/
-static void
+static rtsBool
copyPart(StgClosure **p, StgClosure *src, nat size_to_reserve, nat size_to_copy, step *stp)
{
StgPtr to, from;
@@ -184,7 +184,7 @@ spin:
if (IS_FORWARDING_PTR(info)) {
src->header.info = (const StgInfoTable *)info;
evacuate(p); // does the failed_to_evac stuff
- return ;
+ return rtsFalse;
}
#else
info = (W_)src->header.info;
@@ -214,6 +214,8 @@ spin:
if (size_to_reserve - size_to_copy > 0)
LDV_FILL_SLOP(to + size_to_copy - 1, (int)(size_to_reserve - size_to_copy));
#endif
+
+ return rtsTrue;
}
@@ -697,14 +699,18 @@ loop:
{
StgTSO *new_tso;
StgPtr r, s;
-
- copyPart(p,(StgClosure *)tso, tso_sizeW(tso), sizeofW(StgTSO), stp);
- new_tso = (StgTSO *)*p;
- move_TSO(tso, new_tso);
- for (r = tso->sp, s = new_tso->sp;
- r < tso->stack+tso->stack_size;) {
- *s++ = *r++;
- }
+ rtsBool mine;
+
+ mine = copyPart(p,(StgClosure *)tso, tso_sizeW(tso),
+ sizeofW(StgTSO), stp);
+ if (mine) {
+ new_tso = (StgTSO *)*p;
+ move_TSO(tso, new_tso);
+ for (r = tso->sp, s = new_tso->sp;
+ r < tso->stack+tso->stack_size;) {
+ *s++ = *r++;
+ }
+ }
return;
}
}