diff options
-rw-r--r-- | erts/emulator/beam/erl_bif_trace.c | 36 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.c | 57 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.h | 5 |
3 files changed, 34 insertions, 64 deletions
diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index 6515eafbd5..764548d884 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -58,10 +58,17 @@ static struct { /* Protected by code write permission */ int local; BpFunctions f; /* Local functions */ BpFunctions e; /* Export entries */ +#ifdef ERTS_SMP + Process* stager; + ErtsThrPrgrLaterOp lop; +#endif } finish_bp; static Eterm trace_pattern(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist); +#ifdef ERTS_SMP +static void smp_bp_finisher(void* arg); +#endif static BIF_RETTYPE system_monitor(Process *p, Eterm monitor_pid, Eterm list); @@ -350,7 +357,10 @@ trace_pattern(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist) #ifdef ERTS_SMP if (finish_bp.current >= 0) { ASSERT(matches >= 0); - erts_notify_finish_breakpointing(p); + ASSERT(finish_bp.stager == NULL); + finish_bp.stager = p; + erts_schedule_thr_prgr_later_op(smp_bp_finisher, NULL, &finish_bp.lop); + erts_smp_proc_inc_refc(p); erts_suspend(p, ERTS_PROC_LOCK_MAIN, NULL); ERTS_BIF_YIELD_RETURN(p, make_small(matches)); } @@ -366,6 +376,29 @@ trace_pattern(Process* p, Eterm MFA, Eterm Pattern, Eterm flaglist) } } +#ifdef ERTS_SMP +static void smp_bp_finisher(void* null) +{ + if (erts_finish_breakpointing()) { /* Not done */ + /* Arrange for being called again */ + erts_schedule_thr_prgr_later_op(smp_bp_finisher, NULL, &finish_bp.lop); + } + else { /* Done */ + Process* p = finish_bp.stager; +#ifdef DEBUG + finish_bp.stager = NULL; +#endif + erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS); + if (!ERTS_PROC_IS_EXITING(p)) { + erts_resume(p, ERTS_PROC_LOCK_STATUS); + } + erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS); + erts_smp_proc_dec_refc(p); + erts_release_code_write_permission(); + } +} +#endif /* ERTS_SMP */ + void erts_get_default_trace_pattern(int *trace_pattern_is_on, Binary **match_spec, @@ -1531,7 +1564,6 @@ erts_finish_breakpointing(void) * are blocked, in which case memory barriers will be issued * when they are awaken.) */ - switch (finish_bp.current++) { case 0: /* diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 986619944e..7e91ad06fe 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -530,9 +530,6 @@ dbg_chk_aux_work_val(erts_aint32_t value) #ifdef ERTS_SMP_SCHEDULERS_NEED_TO_CHECK_CHILDREN valid |= ERTS_SSI_AUX_WORK_CHECK_CHILDREN; #endif -#ifdef ERTS_SMP - valid |= ERTS_SSI_AUX_WORK_FINISH_BP; -#endif #ifdef ERTS_SSI_AUX_WORK_REAP_PORTS valid |= ERTS_SSI_AUX_WORK_REAP_PORTS; #endif @@ -1450,55 +1447,6 @@ handle_async_ready_clean(ErtsAuxWorkData *awdp, #endif /* ERTS_USE_ASYNC_READY_Q */ -#ifdef ERTS_SMP -void -erts_notify_finish_breakpointing(Process* p) -{ - ErtsAuxWorkData* awdp = &p->scheduler_data->aux_work_data; - - ASSERT(awdp->bp_ix_activation.stager == NULL); - awdp->bp_ix_activation.stager = p; - awdp->bp_ix_activation.thr_prgr = erts_thr_progress_later(awdp->esdp); - erts_thr_progress_wakeup(awdp->esdp, awdp->bp_ix_activation.thr_prgr); - erts_smp_proc_inc_refc(p); - set_aux_work_flags_wakeup_relb(p->scheduler_data->ssi, - ERTS_SSI_AUX_WORK_FINISH_BP); -} - -static erts_aint32_t -handle_finish_bp(ErtsAuxWorkData* awdp, erts_aint32_t aux_work) -{ - ErtsThrPrgrVal current = haw_thr_prgr_current(awdp); - - if (!erts_thr_progress_has_reached_this(current, - awdp->bp_ix_activation.thr_prgr)) { - return aux_work & ~ERTS_SSI_AUX_WORK_FINISH_BP; - } - if (erts_finish_breakpointing()) { /* Not done */ - /* Arrange for being called again */ - awdp->bp_ix_activation.thr_prgr = - erts_thr_progress_later(awdp->esdp); - erts_thr_progress_wakeup(awdp->esdp, awdp->bp_ix_activation.thr_prgr); - } else { /* Done */ - Process* p; - - unset_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_FINISH_BP); - p = awdp->bp_ix_activation.stager; -#ifdef DEBUG - awdp->bp_ix_activation.stager = NULL; -#endif - erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS); - if (!ERTS_PROC_IS_EXITING(p)) { - erts_resume(p, ERTS_PROC_LOCK_STATUS); - } - erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS); - erts_smp_proc_dec_refc(p); - erts_release_code_write_permission(); - } - return aux_work & ~ERTS_SSI_AUX_WORK_FINISH_BP; -} -#endif /* ERTS_SMP */ - static ERTS_INLINE erts_aint32_t handle_fix_alloc(ErtsAuxWorkData *awdp, erts_aint32_t aux_work) { @@ -1949,11 +1897,6 @@ handle_aux_work(ErtsAuxWorkData *awdp, erts_aint32_t orig_aux_work, int waiting) HANDLE_AUX_WORK(ERTS_SSI_AUX_WORK_REAP_PORTS, handle_reap_ports); -#ifdef ERTS_SMP - HANDLE_AUX_WORK(ERTS_SSI_AUX_WORK_FINISH_BP, - handle_finish_bp); -#endif - ERTS_DBG_CHK_AUX_WORK_VAL(aux_work); #ifdef ERTS_SMP diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 71b066046b..fa6961e8a4 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -284,7 +284,6 @@ typedef enum { #define ERTS_SSI_AUX_WORK_SET_TMO (((erts_aint32_t) 1) << 11) #define ERTS_SSI_AUX_WORK_MSEG_CACHE_CHECK (((erts_aint32_t) 1) << 12) #define ERTS_SSI_AUX_WORK_REAP_PORTS (((erts_aint32_t) 1) << 13) -#define ERTS_SSI_AUX_WORK_FINISH_BP (((erts_aint32_t) 1) << 14) typedef struct ErtsSchedulerSleepInfo_ ErtsSchedulerSleepInfo; @@ -479,10 +478,6 @@ typedef struct { #endif #ifdef ERTS_SMP struct { - Process* stager; - ErtsThrPrgrVal thr_prgr; - } bp_ix_activation; - struct { int *sched2jix; int jix; ErtsDelayedAuxWorkWakeupJob *job; |