summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/erl_process.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/erl_process.c')
-rw-r--r--erts/emulator/beam/erl_process.c50
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)) {