diff options
author | Rickard Green <[email protected]> | 2011-04-08 14:50:26 +0200 |
---|---|---|
committer | Rickard Green <[email protected]> | 2011-04-11 17:29:39 +0200 |
commit | 031fd45d17d4887fdd437ae73608e55e76660781 (patch) | |
tree | d30bae310bd875eb896850396cbf50b4a21a1eb7 /erts/emulator/beam/bif.c | |
parent | b7ecdcd1ae9e11b8f75e11b82d94da32837932bc (diff) | |
download | otp-031fd45d17d4887fdd437ae73608e55e76660781.tar.gz otp-031fd45d17d4887fdd437ae73608e55e76660781.tar.bz2 otp-031fd45d17d4887fdd437ae73608e55e76660781.zip |
Avoid scheduling of processes being garbage collected by others
Diffstat (limited to 'erts/emulator/beam/bif.c')
-rw-r--r-- | erts/emulator/beam/bif.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index f01580eb2b..53a18cb2e9 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -3217,20 +3217,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); } |