aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/bif.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/bif.c')
-rw-r--r--erts/emulator/beam/bif.c236
1 files changed, 124 insertions, 112 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 4b11884f38..652b95105f 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -59,6 +59,7 @@ Export *erts_convert_time_unit_trap = NULL;
static Export *await_msacc_mod_trap = NULL;
static erts_atomic32_t msacc;
+static Export *system_flag_scheduler_wall_time_trap;
static Export *await_sched_wall_time_mod_trap;
static erts_atomic32_t sched_wall_time;
@@ -227,17 +228,38 @@ BIF_RETTYPE link_1(BIF_ALIST_1)
goto res_no_proc;
}
- code = erts_dsig_prepare(&dsd, dep, BIF_P, ERTS_DSP_RLOCK, 0);
+ code = erts_dsig_prepare(&dsd, dep, BIF_P,
+ (ERTS_PROC_LOCK_MAIN | ERTS_PROC_LOCK_LINK),
+ ERTS_DSP_RLOCK, 0, 1);
switch (code) {
case ERTS_DSIG_PREP_NOT_ALIVE:
- /* Let the dlink trap handle it */
- case ERTS_DSIG_PREP_NOT_CONNECTED:
- erts_proc_unlock(BIF_P, ERTS_PROC_LOCK_LINK);
- BIF_TRAP1(dlink_trap, BIF_P, BIF_ARG_1);
-
+ case ERTS_DSIG_PREP_NOT_CONNECTED: {
+ ErtsProcLocks locks = ERTS_PROC_LOCK_MAIN | ERTS_PROC_LOCK_LINK;
+ erts_aint32_t state;
+ erts_proc_lock(BIF_P, (ERTS_PROC_LOCKS_ALL & ~locks));
+ locks = ERTS_PROC_LOCKS_ALL;
+ erts_send_exit_signal(BIF_P, BIF_ARG_1, BIF_P, &locks,
+ am_noconnection, NIL, NULL, 0);
+ erts_proc_unlock(BIF_P, locks & ERTS_PROC_LOCKS_ALL_MINOR);
+
+ /*
+ * Copy-paste from old dist_exit_3, not sure if we really
+ * need erts_handle_pending_exit when exit_2 does not.
+ */
+ state = erts_atomic32_read_acqb(&BIF_P->state);
+ if (state & (ERTS_PSFLG_EXITING|ERTS_PSFLG_PENDING_EXIT)) {
+ if (state & ERTS_PSFLG_PENDING_EXIT)
+ erts_handle_pending_exit(BIF_P, ERTS_PROC_LOCK_MAIN);
+ ERTS_BIF_EXITED(BIF_P);
+ }
+ BIF_RET(am_true);
+ }
+ case ERTS_DSIG_PREP_PENDING:
case ERTS_DSIG_PREP_CONNECTED:
- /* We are connected. Setup link and send link signal */
-
+ /*
+ * We have (pending) connection.
+ * Setup link and enqueue link signal.
+ */
erts_de_links_lock(dep);
erts_add_link(&ERTS_P_LINKS(BIF_P), LINK_PID, BIF_ARG_1);
@@ -256,8 +278,7 @@ BIF_RETTYPE link_1(BIF_ALIST_1)
ERTS_BIF_YIELD_RETURN(BIF_P, am_true);
BIF_RET(am_true);
default:
- ASSERT(! "Invalid dsig prepare result");
- BIF_ERROR(BIF_P, EXC_INTERNAL_ERROR);
+ ERTS_ASSERT(! "Invalid dsig prepare result");
}
}
}
@@ -292,7 +313,8 @@ remote_demonitor(Process *c_p, DistEntry *dep, Eterm ref, Eterm to)
ERTS_LC_ASSERT((ERTS_PROC_LOCK_MAIN|ERTS_PROC_LOCK_LINK)
== erts_proc_lc_my_proc_locks(c_p));
- code = erts_dsig_prepare(&dsd, dep, c_p, ERTS_DSP_RLOCK, 0);
+ code = erts_dsig_prepare(&dsd, dep, c_p, ERTS_PROC_LOCK_MAIN,
+ ERTS_DSP_RLOCK, 0, 0);
switch (code) {
case ERTS_DSIG_PREP_NOT_ALIVE:
case ERTS_DSIG_PREP_NOT_CONNECTED:
@@ -313,6 +335,7 @@ remote_demonitor(Process *c_p, DistEntry *dep, Eterm ref, Eterm to)
res = am_true;
break;
+ case ERTS_DSIG_PREP_PENDING:
case ERTS_DSIG_PREP_CONNECTED:
erts_de_links_lock(dep);
@@ -347,8 +370,7 @@ remote_demonitor(Process *c_p, DistEntry *dep, Eterm ref, Eterm to)
}
break;
default:
- ASSERT(! "Invalid dsig prepare result");
- return am_internal_error;
+ ERTS_ASSERT(! "Invalid dsig prepare result");
}
@@ -767,23 +789,20 @@ remote_monitor(Process *p, Eterm bifarg1, Eterm bifarg2,
BIF_RETTYPE ret;
int code;
+ ASSERT(dep);
erts_proc_lock(p, ERTS_PROC_LOCK_LINK);
- code = erts_dsig_prepare(&dsd, dep, p, ERTS_DSP_RLOCK, 0);
+ code = erts_dsig_prepare(&dsd, dep,
+ p, (ERTS_PROC_LOCK_MAIN | ERTS_PROC_LOCK_LINK),
+ ERTS_DSP_RLOCK, 0, 1);
switch (code) {
case ERTS_DSIG_PREP_NOT_ALIVE:
- /* Let the dmonitor_p trap handle it */
case ERTS_DSIG_PREP_NOT_CONNECTED:
erts_proc_unlock(p, ERTS_PROC_LOCK_LINK);
ERTS_BIF_PREP_TRAP2(ret, dmonitor_p_trap, p, bifarg1, bifarg2);
break;
+ case ERTS_DSIG_PREP_PENDING:
case ERTS_DSIG_PREP_CONNECTED:
- if (!(dep->flags & DFLAG_DIST_MONITOR)
- || (byname && !(dep->flags & DFLAG_DIST_MONITOR_NAME))) {
- erts_de_runlock(dep);
- erts_proc_unlock(p, ERTS_PROC_LOCK_LINK);
- ERTS_BIF_PREP_ERROR(ret, p, BADARG);
- }
- else {
+ {
Eterm p_trgt, p_name, d_name, mon_ref;
mon_ref = erts_make_ref(p);
@@ -818,9 +837,7 @@ remote_monitor(Process *p, Eterm bifarg1, Eterm bifarg2,
}
break;
default:
- ASSERT(! "Invalid dsig prepare result");
- ERTS_BIF_PREP_ERROR(ret, p, EXC_INTERNAL_ERROR);
- break;
+ ERTS_ASSERT(! "Invalid dsig prepare result");
}
BIF_RET(ret);
@@ -888,17 +905,17 @@ local_port:
if (!erts_is_alive && remote_node != am_Noname) {
goto badarg; /* Remote monitor from (this) undistributed node */
}
- dep = erts_sysname_to_connected_dist_entry(remote_node);
+ dep = erts_find_or_insert_dist_entry(remote_node);
if (dep == erts_this_dist_entry) {
ret = local_name_monitor(BIF_P, BIF_ARG_1, name);
} else {
ret = remote_monitor(BIF_P, BIF_ARG_1, BIF_ARG_2, dep, name, 1);
}
+ erts_deref_dist_entry(dep);
} else {
badarg:
ERTS_BIF_PREP_ERROR(ret, BIF_P, BADARG);
}
-
return ret;
}
@@ -1158,21 +1175,14 @@ BIF_RETTYPE unlink_1(BIF_ALIST_1)
BIF_RET(am_true);
}
- code = erts_dsig_prepare(&dsd, dep, BIF_P, ERTS_DSP_NO_LOCK, 0);
+ code = erts_dsig_prepare(&dsd, dep, BIF_P, ERTS_PROC_LOCK_MAIN,
+ ERTS_DSP_NO_LOCK, 0, 0);
switch (code) {
case ERTS_DSIG_PREP_NOT_ALIVE:
case ERTS_DSIG_PREP_NOT_CONNECTED:
-#if 1
BIF_RET(am_true);
-#else
- /*
- * This is how we used to do it, but the link is obviously not
- * active, so I see no point in setting up a connection.
- * /Rickard
- */
- BIF_TRAP1(dunlink_trap, BIF_P, BIF_ARG_1);
-#endif
+ case ERTS_DSIG_PREP_PENDING:
case ERTS_DSIG_PREP_CONNECTED:
erts_remove_dist_link(&dld, BIF_P->common.id, BIF_ARG_1, dep);
code = erts_dsig_send_unlink(&dsd, BIF_P->common.id, BIF_ARG_1);
@@ -1545,22 +1555,24 @@ BIF_RETTYPE exit_2(BIF_ALIST_2)
DistEntry *dep;
dep = external_pid_dist_entry(BIF_ARG_1);
+ ERTS_ASSERT(dep);
if(dep == erts_this_dist_entry)
BIF_RET(am_true);
- code = erts_dsig_prepare(&dsd, dep, BIF_P, ERTS_DSP_NO_LOCK, 0);
+ code = erts_dsig_prepare(&dsd, dep, BIF_P, ERTS_PROC_LOCK_MAIN,
+ ERTS_DSP_NO_LOCK, 0, 1);
switch (code) {
case ERTS_DSIG_PREP_NOT_ALIVE:
case ERTS_DSIG_PREP_NOT_CONNECTED:
- BIF_TRAP2(dexit_trap, BIF_P, BIF_ARG_1, BIF_ARG_2);
+ BIF_RET(am_true);
+ case ERTS_DSIG_PREP_PENDING:
case ERTS_DSIG_PREP_CONNECTED:
code = erts_dsig_send_exit2(&dsd, BIF_P->common.id, BIF_ARG_1, BIF_ARG_2);
if (code == ERTS_DSIG_SEND_YIELD)
ERTS_BIF_YIELD_RETURN(BIF_P, am_true);
BIF_RET(am_true);
default:
- ASSERT(! "Invalid dsig prepare result");
- BIF_ERROR(BIF_P, EXC_INTERNAL_ERROR);
+ ERTS_ASSERT(! "Invalid dsig prepare result");
}
}
else if (is_not_internal_pid(BIF_ARG_1)) {
@@ -1732,7 +1744,6 @@ BIF_RETTYPE process_flag_2(BIF_ALIST_2)
else if (BIF_ARG_1 == am_scheduler) {
ErtsRunQueue *old, *new, *curr;
Sint sched;
- erts_aint32_t state;
if (!is_small(BIF_ARG_2))
goto error;
@@ -1741,23 +1752,23 @@ BIF_RETTYPE process_flag_2(BIF_ALIST_2)
goto error;
if (sched == 0) {
+ old = erts_bind_runq_proc(BIF_P, 0);
new = NULL;
- state = erts_atomic32_read_band_mb(&BIF_P->state,
- ~ERTS_PSFLG_BOUND);
}
else {
+ int bound = !0;
new = erts_schedid2runq(sched);
- erts_atomic_set_nob(&BIF_P->run_queue, (erts_aint_t) new);
- state = erts_atomic32_read_bor_mb(&BIF_P->state,
- ERTS_PSFLG_BOUND);
+ old = erts_set_runq_proc(BIF_P, new, &bound);
+ if (!bound)
+ old = NULL;
}
+ old_value = old ? make_small(old->ix+1) : make_small(0);
+
curr = erts_proc_sched_data(BIF_P)->run_queue;
- old = (ERTS_PSFLG_BOUND & state) ? curr : NULL;
ASSERT(!old || old == curr);
- old_value = old ? make_small(old->ix+1) : make_small(0);
if (new && new != curr)
ERTS_BIF_YIELD_RETURN_X(BIF_P, old_value, am_scheduler);
else
@@ -1964,7 +1975,7 @@ ebif_bang_2(BIF_ALIST_2)
* Send a message to Process, Port or Registered Process.
* Returns non-negative reduction bump or negative result code.
*/
-#define SEND_TRAP (-1)
+#define SEND_NOCONNECT (-1)
#define SEND_YIELD (-2)
#define SEND_YIELD_RETURN (-3)
#define SEND_BADARG (-4)
@@ -1980,20 +1991,22 @@ static Sint remote_send(Process *p, DistEntry *dep,
{
Sint res;
int code;
-
ASSERT(is_atom(to) || is_external_pid(to));
ctx->dep = dep;
- code = erts_dsig_prepare(&ctx->dsd, dep, p, ERTS_DSP_NO_LOCK, !ctx->suspend);
+ code = erts_dsig_prepare(&ctx->dsd, dep, p, ERTS_PROC_LOCK_MAIN,
+ ERTS_DSP_NO_LOCK,
+ !ctx->suspend, ctx->connect);
switch (code) {
case ERTS_DSIG_PREP_NOT_ALIVE:
case ERTS_DSIG_PREP_NOT_CONNECTED:
- res = SEND_TRAP;
+ res = SEND_NOCONNECT;
break;
case ERTS_DSIG_PREP_WOULD_SUSPEND:
ASSERT(!ctx->suspend);
res = SEND_YIELD;
break;
+ case ERTS_DSIG_PREP_PENDING:
case ERTS_DSIG_PREP_CONNECTED: {
if (is_atom(to))
@@ -2170,6 +2183,7 @@ do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext *ctx)
}
return ret_val;
} else if (is_tuple(to)) { /* Remote send */
+ int deref_dep = 0;
int ret;
tp = tuple_val(to);
if (*tp != make_arityval(2))
@@ -2177,11 +2191,10 @@ do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext *ctx)
if (is_not_atom(tp[1]) || is_not_atom(tp[2]))
return SEND_BADARG;
- /* sysname_to_connected_dist_entry will return NULL if there
- is no dist_entry or the dist_entry has no port,
+ /* erts_find_dist_entry will return NULL if there is no dist_entry
but remote_send() will handle that. */
- dep = erts_sysname_to_connected_dist_entry(tp[2]);
+ dep = erts_find_dist_entry(tp[2]);
if (dep == erts_this_dist_entry) {
Eterm id;
@@ -2205,13 +2218,20 @@ do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext *ctx)
}
return 0;
}
+ if (dep == NULL) {
+ dep = erts_find_or_insert_dist_entry(tp[2]);
+ ASSERT(dep != erts_this_dist_entry);
+ deref_dep = 1;
+ }
+ ctx->dsd.node = tp[2];
ret = remote_send(p, dep, tp[1], to, msg, ctx);
if (ret == SEND_YIELD_CONTINUE) {
- if (dep)
- erts_ref_dist_entry(dep);
- ctx->dep_to_deref = dep;
+ erts_ref_dist_entry(ctx->dep);
+ ctx->deref_dep = 1;
}
+ if (deref_dep)
+ erts_deref_dist_entry(dep);
return ret;
} else {
if (IS_TRACED_FL(p, F_TRACE_SEND))
@@ -2223,20 +2243,15 @@ do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext *ctx)
send_message: {
ErtsProcLocks rp_locks = 0;
- Sint res;
if (p == rp)
rp_locks |= ERTS_PROC_LOCK_MAIN;
/* send to local process */
- res = erts_send_message(p, rp, &rp_locks, msg, 0);
- if (erts_use_sender_punish)
- res *= 4;
- else
- res = 0;
+ erts_send_message(p, rp, &rp_locks, msg, 0);
erts_proc_unlock(rp,
p == rp
? (rp_locks & ~ERTS_PROC_LOCK_MAIN)
: rp_locks);
- return res;
+ return 0;
}
}
@@ -2251,7 +2266,6 @@ BIF_RETTYPE send_3(BIF_ALIST_3)
Eterm msg = BIF_ARG_2;
Eterm opts = BIF_ARG_3;
- int connect = !0;
Eterm l = opts;
Sint result;
@@ -2262,14 +2276,15 @@ BIF_RETTYPE send_3(BIF_ALIST_3)
UseTmpHeap(sizeof(ErtsSendContext)/sizeof(Eterm), BIF_P);
ctx->suspend = !0;
- ctx->dep_to_deref = NULL;
+ ctx->connect = !0;
+ ctx->deref_dep = 0;
ctx->return_term = am_ok;
ctx->dss.reds = (Sint) (ERTS_BIF_REDS_LEFT(p) * TERM_TO_BINARY_LOOP_FACTOR);
ctx->dss.phase = ERTS_DSIG_SEND_PHASE_INIT;
while (is_list(l)) {
if (CAR(list_val(l)) == am_noconnect) {
- connect = 0;
+ ctx->connect = 0;
} else if (CAR(list_val(l)) == am_nosuspend) {
ctx->suspend = 0;
} else {
@@ -2291,8 +2306,8 @@ BIF_RETTYPE send_3(BIF_ALIST_3)
result = do_send(p, to, msg, &ref, ctx);
ERTS_MSACC_POP_STATE_M_X();
- if (result > 0) {
- ERTS_VBUMP_REDS(p, result);
+ if (result >= 0) {
+ ERTS_VBUMP_REDS(p, 4);
if (ERTS_IS_PROC_OUT_OF_REDS(p))
goto yield_return;
ERTS_BIF_PREP_RET(retval, am_ok);
@@ -2300,15 +2315,9 @@ BIF_RETTYPE send_3(BIF_ALIST_3)
}
switch (result) {
- case 0:
- /* May need to yield even though we do not bump reds here... */
- if (ERTS_IS_PROC_OUT_OF_REDS(p))
- goto yield_return;
- ERTS_BIF_PREP_RET(retval, am_ok);
- break;
- case SEND_TRAP:
- if (connect) {
- ERTS_BIF_PREP_TRAP3(retval, dsend3_trap, p, to, msg, opts);
+ case SEND_NOCONNECT:
+ if (ctx->connect) {
+ ERTS_BIF_PREP_RET(retval, am_ok);
} else {
ERTS_BIF_PREP_RET(retval, am_noconnect);
}
@@ -2412,7 +2421,8 @@ Eterm erl_send(Process *p, Eterm to, Eterm msg)
ref = NIL;
#endif
ctx->suspend = !0;
- ctx->dep_to_deref = NULL;
+ ctx->connect = !0;
+ ctx->deref_dep = 0;
ctx->return_term = msg;
ctx->dss.reds = (Sint) (ERTS_BIF_REDS_LEFT(p) * TERM_TO_BINARY_LOOP_FACTOR);
ctx->dss.phase = ERTS_DSIG_SEND_PHASE_INIT;
@@ -2421,8 +2431,8 @@ Eterm erl_send(Process *p, Eterm to, Eterm msg)
ERTS_MSACC_POP_STATE_M_X();
- if (result > 0) {
- ERTS_VBUMP_REDS(p, result);
+ if (result >= 0) {
+ ERTS_VBUMP_REDS(p, 4);
if (ERTS_IS_PROC_OUT_OF_REDS(p))
goto yield_return;
ERTS_BIF_PREP_RET(retval, msg);
@@ -2430,15 +2440,9 @@ Eterm erl_send(Process *p, Eterm to, Eterm msg)
}
switch (result) {
- case 0:
- /* May need to yield even though we do not bump reds here... */
- if (ERTS_IS_PROC_OUT_OF_REDS(p))
- goto yield_return;
+ case SEND_NOCONNECT:
ERTS_BIF_PREP_RET(retval, msg);
break;
- case SEND_TRAP:
- ERTS_BIF_PREP_TRAP2(retval, dsend2_trap, p, to, msg);
- break;
case SEND_YIELD:
ERTS_BIF_PREP_YIELD2(retval, bif_export[BIF_send_2], p, to, msg);
break;
@@ -3097,7 +3101,7 @@ BIF_RETTYPE list_to_integer_2(BIF_ALIST_2)
static int do_float_to_charbuf(Process *p, Eterm efloat, Eterm list,
char *fbuf, int sizeof_fbuf) {
- const static int arity_two = make_arityval(2);
+ Eterm arity_two = make_arityval(2);
int decimals = SYS_DEFAULT_FLOAT_DECIMALS;
int compact = 0;
enum fmt_type_ {
@@ -3461,7 +3465,7 @@ BIF_RETTYPE binary_to_float_1(BIF_ALIST_1)
if (bit_offs)
erts_copy_bits(bytes, bit_offs, 1, buf, 0, 1, size*8);
else
- memcpy(buf, bytes, size);
+ sys_memcpy(buf, bytes, size);
buf[size] = '\0';
@@ -4195,10 +4199,10 @@ BIF_RETTYPE list_to_port_1(BIF_ALIST_1)
buf[i] = '\0'; /* null terminal */
cp = &buf[0];
- if (strncmp("#Port<", cp, 6) != 0)
+ if (sys_strncmp("#Port<", cp, 6) != 0)
goto bad;
- cp += 6; /* strlen("#Port<") */
+ cp += 6; /* sys_strlen("#Port<") */
if (sscanf(cp, "%u.%u>", (unsigned int*)&n, (unsigned int*)&p) < 2)
goto bad;
@@ -4384,23 +4388,24 @@ BIF_RETTYPE group_leader_2(BIF_ALIST_2)
int code;
ErtsDSigData dsd;
dep = external_pid_dist_entry(BIF_ARG_2);
+ ERTS_ASSERT(dep);
if(dep == erts_this_dist_entry)
BIF_ERROR(BIF_P, BADARG);
- code = erts_dsig_prepare(&dsd, dep, BIF_P, ERTS_DSP_NO_LOCK, 0);
+ code = erts_dsig_prepare(&dsd, dep, BIF_P, ERTS_PROC_LOCK_MAIN,
+ ERTS_DSP_NO_LOCK, 0, 1);
switch (code) {
case ERTS_DSIG_PREP_NOT_ALIVE:
- BIF_RET(am_true);
case ERTS_DSIG_PREP_NOT_CONNECTED:
- BIF_TRAP2(dgroup_leader_trap, BIF_P, BIF_ARG_1, BIF_ARG_2);
+ BIF_RET(am_true);
+ case ERTS_DSIG_PREP_PENDING:
case ERTS_DSIG_PREP_CONNECTED:
code = erts_dsig_send_group_leader(&dsd, BIF_ARG_1, BIF_ARG_2);
if (code == ERTS_DSIG_SEND_YIELD)
ERTS_BIF_YIELD_RETURN(BIF_P, am_true);
BIF_RET(am_true);
default:
- ASSERT(! "Invalid dsig prepare result");
- BIF_ERROR(BIF_P, EXC_INTERNAL_ERROR);
+ ERTS_ASSERT(! "Invalid dsig prepare result");
}
}
else if (is_internal_pid(BIF_ARG_2)) {
@@ -4472,7 +4477,7 @@ BIF_RETTYPE group_leader_2(BIF_ALIST_2)
BIF_ERROR(BIF_P, BADARG);
}
}
-
+
BIF_RETTYPE system_flag_2(BIF_ALIST_2)
{
Sint n;
@@ -4690,17 +4695,9 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
BIF_RET(am_true);
} else if (BIF_ARG_1 == am_scheduler_wall_time) {
- if (BIF_ARG_2 == am_true || BIF_ARG_2 == am_false) {
- erts_aint32_t new = BIF_ARG_2 == am_true ? 1 : 0;
- erts_aint32_t old = erts_atomic32_xchg_nob(&sched_wall_time,
- new);
- Eterm ref = erts_sched_wall_time_request(BIF_P, 1, new, 0, 0);
- ASSERT(is_value(ref));
- BIF_TRAP2(await_sched_wall_time_mod_trap,
- BIF_P,
- ref,
- old ? am_true : am_false);
- }
+ if (BIF_ARG_2 == am_true || BIF_ARG_2 == am_false)
+ BIF_TRAP1(system_flag_scheduler_wall_time_trap,
+ BIF_P, BIF_ARG_2);
} else if (BIF_ARG_1 == am_dirty_cpu_schedulers_online) {
Sint old_no;
if (!is_small(BIF_ARG_2))
@@ -4807,11 +4804,24 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
"scheduled for removal in Erlang/OTP 18. For more\n"
"information see the erlang:system_flag/2 documentation.\n");
return erts_bind_schedulers(BIF_P, BIF_ARG_2);
+ } else if (ERTS_IS_ATOM_STR("erts_alloc", BIF_ARG_1)) {
+ return erts_alloc_set_dyn_param(BIF_P, BIF_ARG_2);
}
error:
BIF_ERROR(BIF_P, BADARG);
}
+BIF_RETTYPE erts_internal_scheduler_wall_time_1(BIF_ALIST_1)
+{
+ erts_aint32_t new = BIF_ARG_1 == am_true ? 1 : 0;
+ erts_aint32_t old = erts_atomic32_xchg_nob(&sched_wall_time,
+ new);
+ Eterm ref = erts_sched_wall_time_request(BIF_P, 1, new, 0, 0);
+ ASSERT(is_value(ref));
+ BIF_TRAP2(await_sched_wall_time_mod_trap,
+ BIF_P, ref, old ? am_true : am_false);
+}
+
/**********************************************************************/
BIF_RETTYPE phash_2(BIF_ALIST_2)
@@ -5070,8 +5080,10 @@ void erts_init_bif(void)
await_proc_exit_trap = erts_export_put(am_erlang,am_await_proc_exit,3);
await_port_send_result_trap
= erts_export_put(am_erts_internal, am_await_port_send_result, 3);
+ system_flag_scheduler_wall_time_trap
+ = erts_export_put(am_erts_internal, am_system_flag_scheduler_wall_time, 1);
await_sched_wall_time_mod_trap
- = erts_export_put(am_erlang, am_await_sched_wall_time_modifications, 2);
+ = erts_export_put(am_erts_internal, am_await_sched_wall_time_modifications, 2);
await_msacc_mod_trap
= erts_export_put(am_erts_internal, am_await_microstate_accounting_modifications, 3);