diff --git a/erts/emulator/beam/erl_monitor_link.h b/erts/emulator/beam/erl_monitor_link.h index 757c997d0cdc..3d67eb9d7b42 100644 --- a/erts/emulator/beam/erl_monitor_link.h +++ b/erts/emulator/beam/erl_monitor_link.h @@ -735,7 +735,8 @@ struct ErtsMonitorSuspend__ { erts_atomic64_t state; }; #define ERTS_MSUSPEND_STATE_FLG_ACTIVE ((erts_aint64_t) (((Uint64) 1) << 63)) -#define ERTS_MSUSPEND_STATE_COUNTER_MASK (~ERTS_MSUSPEND_STATE_FLG_ACTIVE) +#define ERTS_MSUSPEND_STATE_FLG_PAUSE_TIMER ((erts_aint64_t) (((Uint64) 1) << 62)) +#define ERTS_MSUSPEND_STATE_COUNTER_MASK (((erts_aint64_t) (((Uint64) 1) << 62)) - 1) /* * --- Monitor tree operations --- diff --git a/erts/emulator/beam/erl_proc_sig_queue.c b/erts/emulator/beam/erl_proc_sig_queue.c index 628d2a11dbdb..eeca97b1453b 100644 --- a/erts/emulator/beam/erl_proc_sig_queue.c +++ b/erts/emulator/beam/erl_proc_sig_queue.c @@ -4992,6 +4992,19 @@ handle_process_info(Process *c_p, ErtsSigRecvTracing *tracing, return ((int) reds)*4 + 8; } +static void +activate_suspend_monitor(Process *c_p, ErtsMonitorSuspend *msp) +{ + erts_aint64_t mstate; + int pause_proc_timer = 0; + + mstate = erts_atomic64_read_bor_acqb(&msp->state, + ERTS_MSUSPEND_STATE_FLG_ACTIVE); + ASSERT(!(mstate & ERTS_MSUSPEND_STATE_FLG_ACTIVE)); + pause_proc_timer = !!(mstate & ERTS_MSUSPEND_STATE_FLG_PAUSE_TIMER); + erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL, pause_proc_timer); +} + static void handle_suspend(Process *c_p, ErtsMonitor *mon, int *yieldp) { @@ -5000,14 +5013,8 @@ handle_suspend(Process *c_p, ErtsMonitor *mon, int *yieldp) ASSERT(mon->type == ERTS_MON_TYPE_SUSPEND); if (!(state & ERTS_PSFLG_DIRTY_RUNNING)) { - ErtsMonitorSuspend *msp; - erts_aint64_t mstate; - - msp = (ErtsMonitorSuspend *) erts_monitor_to_data(mon); - mstate = erts_atomic64_read_bor_acqb(&msp->state, - ERTS_MSUSPEND_STATE_FLG_ACTIVE); - ASSERT(!(mstate & ERTS_MSUSPEND_STATE_FLG_ACTIVE)); (void) mstate; - erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL, 0); + ErtsMonitorSuspend *msp = (ErtsMonitorSuspend *) erts_monitor_to_data(mon); + activate_suspend_monitor(c_p, msp); *yieldp = !0; } else { @@ -5207,18 +5214,13 @@ erts_proc_sig_handle_pending_suspend(Process *c_p) psusp = (ErtsProcSigPendingSuspend *) ERTS_PROC_GET_PENDING_SUSPEND(c_p); msp = psusp->mon; - + while (msp) { ErtsMonitorSuspend *next_msp = msp->next; msp->next = NULL; if (!(state & ERTS_PSFLG_EXITING) && erts_monitor_is_in_table(&msp->md.u.target)) { - erts_aint64_t mstate; - - mstate = erts_atomic64_read_bor_acqb(&msp->state, - ERTS_MSUSPEND_STATE_FLG_ACTIVE); - ASSERT(!(mstate & ERTS_MSUSPEND_STATE_FLG_ACTIVE)); (void) mstate; - erts_suspend(c_p, ERTS_PROC_LOCK_MAIN, NULL, 0); + activate_suspend_monitor(c_p, msp); } erts_monitor_release(&msp->md.u.target);