From a36d8ef028b2f71428fc7b98800d6c83e4566cbe Mon Sep 17 00:00:00 2001 From: Daniel Gorin Date: Sat, 13 Jul 2024 16:39:30 +0100 Subject: [PATCH] [pause_proc_timer][5/n] ErtsMonitorSuspend can pause the proc timer We add a flag to the monitor state to indicate that the proc timer is to be stopped (or was already stopped) and take it into account while suspending the process. Nothing sets the new flag yet, that happens in the next commit --- erts/emulator/beam/erl_monitor_link.h | 3 ++- erts/emulator/beam/erl_proc_sig_queue.c | 32 +++++++++++++------------ 2 files changed, 19 insertions(+), 16 deletions(-) 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);