aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2018-01-02 14:38:09 +0100
committerLukas Larsson <[email protected]>2018-02-26 17:45:45 +0100
commit94c94e901b69e9320011570041cf16ecd960dea2 (patch)
tree6c304e61fab044787d1fbd141b01c80776e214d2 /erts/emulator/beam
parent0c08677522f1add0f6161328a0009e3ac3401f1e (diff)
downloadotp-94c94e901b69e9320011570041cf16ecd960dea2.tar.gz
otp-94c94e901b69e9320011570041cf16ecd960dea2.tar.bz2
otp-94c94e901b69e9320011570041cf16ecd960dea2.zip
erts: Delay cleanup of removed tracer on dirty scheds
It is not simple to do the correct de-allocation on a dirty schedulers, so we just delay it until this process runs on a normal scheduler.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/erl_trace.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index db7d0ac449..9fda4ff6ff 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -3009,24 +3009,28 @@ is_tracer_enabled(Process* c_p, ErtsProcLocks c_p_locks,
ASSERT(0);
}
- /* Only remove tracer on self() and ports */
+ /* Only remove tracer on (self() or ports) AND we are on a normal scheduler */
if (is_internal_port(t_p->id) || (c_p && c_p->common.id == t_p->id)) {
+ ErtsSchedulerData *esdp = erts_get_scheduler_data();
ErtsProcLocks c_p_xlocks = 0;
- if (is_internal_pid(t_p->id)) {
- ERTS_SMP_LC_ASSERT(erts_proc_lc_my_proc_locks(c_p) & ERTS_PROC_LOCK_MAIN);
- if (c_p_locks != ERTS_PROC_LOCKS_ALL) {
- c_p_xlocks = ~c_p_locks & ERTS_PROC_LOCKS_ALL;
- if (erts_smp_proc_trylock(c_p, c_p_xlocks) == EBUSY) {
- erts_smp_proc_unlock(c_p, c_p_locks & ~ERTS_PROC_LOCK_MAIN);
- erts_smp_proc_lock(c_p, ERTS_PROC_LOCKS_ALL_MINOR);
+ if (esdp && !ERTS_SCHEDULER_IS_DIRTY(esdp)) {
+ if (is_internal_pid(t_p->id)) {
+ ERTS_SMP_LC_ASSERT(erts_proc_lc_my_proc_locks(c_p) & ERTS_PROC_LOCK_MAIN);
+ if (c_p_locks != ERTS_PROC_LOCKS_ALL) {
+ c_p_xlocks = ~c_p_locks & ERTS_PROC_LOCKS_ALL;
+ if (erts_smp_proc_trylock(c_p, c_p_xlocks) == EBUSY) {
+ erts_smp_proc_unlock(c_p, c_p_locks & ~ERTS_PROC_LOCK_MAIN);
+ erts_smp_proc_lock(c_p, ERTS_PROC_LOCKS_ALL_MINOR);
+ }
}
}
- }
- erts_tracer_replace(t_p, erts_tracer_nil);
- t_p->trace_flags &= ~TRACEE_FLAGS;
- if (c_p_xlocks)
- erts_smp_proc_unlock(c_p, c_p_xlocks);
+ erts_tracer_replace(t_p, erts_tracer_nil);
+ t_p->trace_flags &= ~TRACEE_FLAGS;
+
+ if (c_p_xlocks)
+ erts_smp_proc_unlock(c_p, c_p_xlocks);
+ }
}
return 0;