aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/bif.c
diff options
context:
space:
mode:
authorRickard Green <rickard@erlang.org>2011-05-11 14:52:38 +0200
committerRickard Green <rickard@erlang.org>2011-05-11 14:52:38 +0200
commit116deb98aa1309039d06530de3351feec1163c3f (patch)
tree34e98231f345dec4992d22fdb5068a943842a524 /erts/emulator/beam/bif.c
parent68fe6a14539b82250373ef114d6576e74e1b8f2e (diff)
parentaeda9e6b3b28849a27b0f4f5386d000e40a198d0 (diff)
downloadotp-116deb98aa1309039d06530de3351feec1163c3f.tar.gz
otp-116deb98aa1309039d06530de3351feec1163c3f.tar.bz2
otp-116deb98aa1309039d06530de3351feec1163c3f.zip
Merge branch 'rickard/gc-other/OTP-9211' into dev
* rickard/gc-other/OTP-9211: Fix bad assertions Avoid scheduling of processes being garbage collected by others
Diffstat (limited to 'erts/emulator/beam/bif.c')
-rw-r--r--erts/emulator/beam/bif.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index b3325d635b..8c35644125 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -3215,20 +3215,32 @@ BIF_RETTYPE garbage_collect_1(BIF_ALIST_1)
BIF_ERROR(BIF_P, BADARG);
}
- rp = erts_pid2proc_not_running(BIF_P, ERTS_PROC_LOCK_MAIN,
+ if (BIF_P->id == BIF_ARG_1)
+ rp = BIF_P;
+ else {
+#ifdef ERTS_SMP
+ rp = erts_pid2proc_suspend(BIF_P, ERTS_PROC_LOCK_MAIN,
BIF_ARG_1, ERTS_PROC_LOCK_MAIN);
- if (!rp)
- BIF_RET(am_false);
- if (rp == ERTS_PROC_LOCK_BUSY)
- ERTS_BIF_YIELD1(bif_export[BIF_garbage_collect_1], BIF_P, BIF_ARG_1);
+ if (rp == ERTS_PROC_LOCK_BUSY)
+ ERTS_BIF_YIELD1(bif_export[BIF_garbage_collect_1], BIF_P, BIF_ARG_1);
+#else
+ rp = erts_pid2proc(BIF_P, 0, BIF_ARG_1, 0);
+#endif
+ if (!rp)
+ BIF_RET(am_false);
+ }
/* The GC cost is taken for the process executing this BIF. */
FLAGS(rp) |= F_NEED_FULLSWEEP;
reds = erts_garbage_collect(rp, 0, rp->arg_reg, rp->arity);
- if (BIF_P != rp)
+#ifdef ERTS_SMP
+ if (BIF_P != rp) {
+ erts_resume(rp, ERTS_PROC_LOCK_MAIN);
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_MAIN);
+ }
+#endif
BIF_RET2(am_true, reds);
}