From f4836a7883842f0e2ae20285ccedf9856c66b24a Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Thu, 1 Jun 2017 19:24:27 +0200 Subject: Fix check_process_code() on hibernated process --- erts/emulator/beam/beam_bif_load.c | 13 ++++++++++++- erts/emulator/beam/erl_gc.c | 5 ++++- erts/emulator/beam/erl_process.h | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) (limited to 'erts') diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index 0e192b1ebd..6072eaa8eb 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -808,6 +808,10 @@ check_process_code(Process* rp, Module* modp, int allow_gc, int *redsp) if (done_gc) { return am_true; } else { + if (rp->flags & F_HIBERNATED) { + /* GC wont help; everything on heap is live... */ + return am_true; + } if (!allow_gc) return am_aborted; /* @@ -870,6 +874,8 @@ check_process_code(Process* rp, Module* modp, int allow_gc, int *redsp) if (done_gc) { return am_true; } else { + int hibernated = !!(rp->flags & F_HIBERNATED); + int gc_cost; Eterm* literals; Uint lit_size; struct erl_off_heap_header* oh; @@ -886,13 +892,18 @@ check_process_code(Process* rp, Module* modp, int allow_gc, int *redsp) rp->ftrace = NIL; done_gc = 1; FLAGS(rp) |= F_NEED_FULLSWEEP; - *redsp += erts_garbage_collect(rp, 0, rp->arg_reg, rp->arity); + gc_cost = erts_garbage_collect(rp, 0, rp->arg_reg, rp->arity); + *redsp += gc_cost; literals = (Eterm *) modp->old.code[MI_LITERALS_START]; lit_size = (Eterm *) modp->old.code[MI_LITERALS_END] - literals; oh = (struct erl_off_heap_header *) modp->old.code[MI_LITERALS_OFF_HEAP]; *redsp += lit_size / 10; /* Need, better value... */ erts_garbage_collect_literals(rp, literals, lit_size, oh); + if (hibernated) { + erts_garbage_collect_hibernate(rp); + *redsp += gc_cost; + } } } return am_false; diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index 2f21111a2e..c22577a254 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -490,7 +490,7 @@ erts_garbage_collect(Process* p, int need, Eterm* objv, int nobj) esdp->gc_info.garbage_cols++; esdp->gc_info.reclaimed += reclaimed_now; - FLAGS(p) &= ~F_FORCE_GC; + FLAGS(p) &= ~(F_FORCE_GC|F_HIBERNATED); #ifdef CHECK_FOR_HOLES /* @@ -658,6 +658,8 @@ erts_garbage_collect_hibernate(Process* p) ErtsGcQuickSanityCheck(p); + p->flags |= F_HIBERNATED; + erts_smp_atomic32_read_band_nob(&p->state, ~ERTS_PSFLG_GC); } @@ -830,6 +832,7 @@ erts_garbage_collect_literals(Process* p, Eterm* literals, /* * Restore status. */ + p->flags &= ~F_HIBERNATED; erts_smp_atomic32_read_band_nob(&p->state, ~ERTS_PSFLG_GC); } diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 10c6fa4a67..41e5f55476 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -1292,6 +1292,7 @@ extern struct erts_system_profile_flags_t erts_system_profile_flags; #define F_P2PNR_RESCHED (1 << 9) /* Process has been rescheduled via erts_pid2proc_not_running() */ #define F_FORCE_GC (1 << 10) /* Force gc at process in-scheduling */ #define F_DISABLE_GC (1 << 11) /* Disable GC */ +#define F_HIBERNATED (1 << 12) /* Hibernated */ /* process trace_flags */ #define F_SENSITIVE (1 << 0) -- cgit v1.2.3 From c8f1d8218a2aa01a2b8d4f65af6e07e5ca2b631e Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Thu, 1 Jun 2017 19:29:36 +0200 Subject: Do not GC hibernated process from other processes --- erts/emulator/beam/erl_process.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index d583118e7b..bce4e7fff3 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -10059,7 +10059,8 @@ execute_sys_tasks(Process *c_p, erts_aint32_t *statep, int in_reds) reds++; } else { - if (!garbage_collected) { + if (!garbage_collected + && !(c_p->flags & F_HIBERNATED)) { FLAGS(c_p) |= F_NEED_FULLSWEEP; reds += erts_garbage_collect(c_p, 0, -- cgit v1.2.3