diff options
Diffstat (limited to 'erts/emulator/beam/erl_process.c')
-rw-r--r-- | erts/emulator/beam/erl_process.c | 50 |
1 files changed, 32 insertions, 18 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index ea3b369be2..3c8b1631b4 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -1634,6 +1634,11 @@ unset_aux_work_flags(ErtsSchedulerSleepInfo *ssi, erts_aint32_t flgs) return erts_atomic32_read_band_nob(&ssi->aux_work, ~flgs); } +static ERTS_INLINE erts_aint32_t +unset_aux_work_flags_mb(ErtsSchedulerSleepInfo *ssi, erts_aint32_t flgs) +{ + return erts_atomic32_read_band_mb(&ssi->aux_work, ~flgs); +} static ERTS_INLINE void haw_chk_later_cleanup_op_wakeup(ErtsAuxWorkData *awdp, ErtsThrPrgrVal val) @@ -1729,9 +1734,7 @@ handle_delayed_aux_work_wakeup(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, in if (!waiting && awdp->delayed_wakeup.next > awdp->esdp->reductions) return aux_work; - unset_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_DELAYED_AW_WAKEUP); - - ERTS_THR_MEMORY_BARRIER; + unset_aux_work_flags_mb(awdp->ssi, ERTS_SSI_AUX_WORK_DELAYED_AW_WAKEUP); max_jix = awdp->delayed_wakeup.jix; awdp->delayed_wakeup.jix = -1; @@ -1855,7 +1858,7 @@ handle_misc_aux_work(ErtsAuxWorkData *awdp, { ErtsThrQ_t *q = &misc_aux_work_queues[awdp->sched_id].q; - unset_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_MISC); + unset_aux_work_flags_mb(awdp->ssi, ERTS_SSI_AUX_WORK_MISC); while (1) { erts_misc_aux_work_t *mawp = erts_thr_q_dequeue(q); if (!mawp) @@ -1957,7 +1960,7 @@ handle_async_ready(ErtsAuxWorkData *awdp, ASSERT(!awdp->esdp || !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp)); - unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_ASYNC_READY); + unset_aux_work_flags_mb(ssi, ERTS_SSI_AUX_WORK_ASYNC_READY); if (erts_check_async_ready(awdp->async_ready.queue)) { if (set_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_ASYNC_READY) & ERTS_SSI_AUX_WORK_ASYNC_READY_CLEAN) { @@ -2013,8 +2016,8 @@ handle_fix_alloc(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting) ASSERT(!awdp->esdp || !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp)); - unset_aux_work_flags(ssi, (ERTS_SSI_AUX_WORK_FIX_ALLOC_LOWER_LIM - | ERTS_SSI_AUX_WORK_FIX_ALLOC_DEALLOC)); + unset_aux_work_flags_mb(ssi, (ERTS_SSI_AUX_WORK_FIX_ALLOC_LOWER_LIM + | ERTS_SSI_AUX_WORK_FIX_ALLOC_DEALLOC)); aux_work &= ~(ERTS_SSI_AUX_WORK_FIX_ALLOC_LOWER_LIM | ERTS_SSI_AUX_WORK_FIX_ALLOC_DEALLOC); res = erts_alloc_fix_alloc_shrink(awdp->sched_id, aux_work); @@ -2062,7 +2065,7 @@ handle_delayed_dealloc(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waitin ASSERT(!awdp->esdp || !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp)); - unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_DD); + unset_aux_work_flags_mb(ssi, ERTS_SSI_AUX_WORK_DD); ERTS_MSACC_SET_STATE_CACHED_M_X(ERTS_MSACC_STATE_ALLOC); erts_alloc_scheduler_handle_delayed_dealloc((void *) awdp->esdp, &need_thr_progress, @@ -2158,7 +2161,7 @@ handle_canceled_timers(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waitin ASSERT(!awdp->esdp || !ERTS_SCHEDULER_IS_DIRTY(awdp->esdp)); - unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_CNCLD_TMRS); + unset_aux_work_flags_mb(ssi, ERTS_SSI_AUX_WORK_CNCLD_TMRS); erts_handle_canceled_timers((void *) awdp->esdp, &need_thr_progress, &wakeup, @@ -2328,7 +2331,7 @@ handle_debug_wait_completed(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int w awdp->debug.wait_completed.callback = NULL; awdp->debug.wait_completed.arg = NULL; - unset_aux_work_flags(ssi, ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED); + unset_aux_work_flags_mb(ssi, ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED); return aux_work & ~ERTS_SSI_AUX_WORK_DEBUG_WAIT_COMPLETED; } @@ -2464,7 +2467,7 @@ int erts_halt_code; static ERTS_INLINE erts_aint32_t handle_reap_ports(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting) { - unset_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_REAP_PORTS); + unset_aux_work_flags_mb(awdp->ssi, ERTS_SSI_AUX_WORK_REAP_PORTS); ERTS_RUNQ_FLGS_SET(awdp->esdp->run_queue, ERTS_RUNQ_FLG_HALTING); if (erts_atomic32_dec_read_acqb(&erts_halt_progress) == 0) { @@ -2559,7 +2562,7 @@ handle_yield(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting) static ERTS_INLINE erts_aint32_t handle_mseg_cache_check(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting) { - unset_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_MSEG_CACHE_CHECK); + unset_aux_work_flags_mb(awdp->ssi, ERTS_SSI_AUX_WORK_MSEG_CACHE_CHECK); erts_mseg_cache_check(); return aux_work & ~ERTS_SSI_AUX_WORK_MSEG_CACHE_CHECK; } @@ -2570,7 +2573,7 @@ handle_mseg_cache_check(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiti static ERTS_INLINE erts_aint32_t handle_setup_aux_work_timer(ErtsAuxWorkData *awdp, erts_aint32_t aux_work, int waiting) { - unset_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_SET_TMO); + unset_aux_work_flags_mb(awdp->ssi, ERTS_SSI_AUX_WORK_SET_TMO); setup_aux_work_timer(awdp->esdp); return aux_work & ~ERTS_SSI_AUX_WORK_SET_TMO; } @@ -8699,6 +8702,9 @@ erts_internal_suspend_process_2(BIF_ALIST_2) if (BIF_P->common.id == BIF_ARG_1) BIF_RET(am_badarg); /* We are not allowed to suspend ourselves */ + if (!is_internal_pid(BIF_ARG_1)) + BIF_RET(am_badarg); + if (is_not_nil(BIF_ARG_2)) { /* Parse option list */ Eterm arg = BIF_ARG_2; @@ -8847,6 +8853,9 @@ resume_process_1(BIF_ALIST_1) if (BIF_P->common.id == BIF_ARG_1) BIF_ERROR(BIF_P, BADARG); + if (!is_internal_pid(BIF_ARG_1)) + BIF_ERROR(BIF_P, BADARG); + mon = erts_monitor_tree_lookup(ERTS_P_MONITORS(BIF_P), BIF_ARG_1); if (!mon) { @@ -12209,9 +12218,11 @@ erl_create_process(Process* parent, /* Parent of process (default group leader). ErtsLinkData *ldp; ldp = erts_link_create(ERTS_LNK_TYPE_DIST_PROC, parent_id, p->common.id); - code = erts_link_dist_insert(&ldp->a, so->dist_entry->mld); - ASSERT(code); erts_link_tree_insert(&ERTS_P_LINKS(p), &ldp->b); + if (!erts_link_dist_insert(&ldp->a, so->mld)) { + erts_proc_sig_send_link_exit(NULL, THE_NON_VALUE, &ldp->a, + am_noconnection, NIL); + } } if (so->flags & SPO_MONITOR) { @@ -12219,9 +12230,12 @@ erl_create_process(Process* parent, /* Parent of process (default group leader). mdp = erts_monitor_create(ERTS_MON_TYPE_DIST_PROC, spawn_ref, parent_id, p->common.id, NIL); - code = erts_monitor_dist_insert(&mdp->origin, so->dist_entry->mld); - ASSERT(code); (void)code; - erts_monitor_tree_insert(&ERTS_P_MONITORS(p), &mdp->target); + if (erts_monitor_dist_insert(&mdp->origin, so->mld)) { + erts_monitor_tree_insert(&ERTS_P_MONITORS(p), &mdp->target); + } + else { + erts_monitor_release_both(mdp); + } } if (have_seqtrace(token)) { |