aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_emu.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r--erts/emulator/beam/beam_emu.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 4351dda5a7..ec4f9b4339 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -422,6 +422,7 @@ static Eterm add_stacktrace(Process* c_p, Eterm Value, Eterm exc);
static void save_stacktrace(Process* c_p, BeamInstr* pc, Eterm* reg,
ErtsCodeMFA *bif_mfa, Eterm args);
static struct StackTrace * get_trace_from_exc(Eterm exc);
+static Eterm *get_freason_ptr_from_exc(Eterm exc);
static Eterm make_arglist(Process* c_p, Eterm* reg, int a);
void
@@ -1904,6 +1905,25 @@ static int is_raised_exc(Eterm exc) {
}
}
+static Eterm *get_freason_ptr_from_exc(Eterm exc) {
+ static Eterm dummy_freason;
+ struct StackTrace* s;
+
+ if (exc == NIL) {
+ /*
+ * Is is not exactly clear when exc can be NIL. Probably only
+ * when the exception has been generated from native code.
+ * Return a pointer to an Eterm that can be safely written and
+ * ignored.
+ */
+ return &dummy_freason;
+ } else {
+ ASSERT(is_list(exc));
+ s = (struct StackTrace *) big_val(CDR(list_val(exc)));
+ return &s->freason;
+ }
+}
+
/*
* Creating a list with the argument registers
*/
@@ -3261,20 +3281,23 @@ erts_is_builtin(Eterm Mod, Eterm Name, int arity)
/*
- * Return the current number of reductions for the given process.
+ * Return the current number of reductions consumed by the given process.
* To get the total number of reductions, p->reds must be added.
*/
Uint
-erts_current_reductions(Process *current, Process *p)
+erts_current_reductions(Process *c_p, Process *p)
{
- if (current != p) {
+ Sint reds_left;
+ if (c_p != p || !(erts_atomic32_read_nob(&c_p->state)
+ & ERTS_PSFLG_RUNNING)) {
return 0;
- } else if (current->fcalls < 0 && ERTS_PROC_GET_SAVED_CALLS_BUF(current)) {
- return current->fcalls + CONTEXT_REDS;
+ } else if (c_p->fcalls < 0 && ERTS_PROC_GET_SAVED_CALLS_BUF(c_p)) {
+ reds_left = c_p->fcalls + CONTEXT_REDS;
} else {
- return REDS_IN(current) - current->fcalls;
+ reds_left = c_p->fcalls;
}
+ return REDS_IN(c_p) - reds_left - erts_proc_sched_data(p)->virtual_reds;
}
int