aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2016-04-05 11:26:52 +0200
committerLukas Larsson <[email protected]>2016-04-15 15:08:52 +0200
commitc3e7acb4fe304d117f7361292d36f5d73df3e1c7 (patch)
tree50777c8c13d2e4eeba302b446c14683821dcd83b /erts/emulator
parenta1b352dfc68d501a385240cdb7f45a96cf9e3358 (diff)
downloadotp-c3e7acb4fe304d117f7361292d36f5d73df3e1c7.tar.gz
otp-c3e7acb4fe304d117f7361292d36f5d73df3e1c7.tar.bz2
otp-c3e7acb4fe304d117f7361292d36f5d73df3e1c7.zip
erts: Make trace_delivered go via sys msg dispatcher again
This is needed as otherwise messages from system_profile will not be guaranteed to arrive before trace delivered.
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/erl_bif_trace.c23
-rw-r--r--erts/emulator/beam/erl_trace.c16
-rw-r--r--erts/emulator/beam/erl_trace.h1
3 files changed, 32 insertions, 8 deletions
diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c
index 7e2fe7fcd4..ff2018aa27 100644
--- a/erts/emulator/beam/erl_bif_trace.c
+++ b/erts/emulator/beam/erl_bif_trace.c
@@ -2253,25 +2253,32 @@ static void
reply_trace_delivered_all(void *vtdarp)
{
ErtsTraceDeliveredAll *tdarp = (ErtsTraceDeliveredAll *) vtdarp;
- ErtsProcLocks rp_locks = 0;
if (erts_smp_atomic32_dec_read_nob(&tdarp->refc) == 0) {
+ Eterm ref_copy, msg;
Process *rp = tdarp->proc;
Eterm *hp = NULL;
- ErlOffHeap *ohp = NULL;
- ErtsMessage *mp = NULL;
- Eterm ref_copy, msg;
-
+ ErlOffHeap *ohp;
+#ifdef ERTS_SMP
+ ErlHeapFragment *bp;
+ bp = new_message_buffer(4 + NC_HEAP_SIZE(tdarp->ref));
+ hp = &bp->mem[0];
+ ohp = &bp->off_heap;
+#else
+ ErtsProcLocks rp_locks = 0;
+ ErtsMessage *mp;
mp = erts_alloc_message_heap(
rp, &rp_locks, 4 + NC_HEAP_SIZE(tdarp->ref), &hp, &ohp);
+#endif
ref_copy = STORE_NC(&hp, ohp, tdarp->ref);
msg = TUPLE3(hp, am_trace_delivered, tdarp->target, ref_copy);
+#ifdef ERTS_SMP
+ erts_send_sys_msg_proc(rp->common.id, rp->common.id, msg, bp);
+#else
erts_queue_message(rp, &rp_locks, mp, msg);
-
- if (rp_locks)
- erts_smp_proc_unlock(rp, rp_locks);
+#endif
erts_free(ERTS_ALC_T_MISC_AUX_WORK, vtdarp);
erts_proc_dec_refc(rp);
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index cd3c14e213..bd88769dfc 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -84,6 +84,7 @@ enum ErtsSysMsgType {
SYS_MSG_TYPE_UNDEFINED,
SYS_MSG_TYPE_SYSMON,
SYS_MSG_TYPE_ERRLGR,
+ SYS_MSG_TYPE_PROC_MSG,
SYS_MSG_TYPE_SYSPROF
};
@@ -2157,6 +2158,13 @@ erts_queue_error_logger_message(Eterm from, Eterm msg, ErlHeapFragment *bp)
enqueue_sys_msg(SYS_MSG_TYPE_ERRLGR, from, am_error_logger, msg, bp);
}
+void
+erts_send_sys_msg_proc(Eterm from, Eterm to, Eterm msg, ErlHeapFragment *bp)
+{
+ ASSERT(is_internal_pid(to));
+ enqueue_sys_msg(SYS_MSG_TYPE_PROC_MSG, from, to, msg, bp);
+}
+
#ifdef DEBUG_PRINTOUTS
static void
print_msg_type(ErtsSysMsgQ *smqp)
@@ -2171,6 +2179,9 @@ print_msg_type(ErtsSysMsgQ *smqp)
case SYS_MSG_TYPE_ERRLGR:
erts_fprintf(stderr, "ERRLGR ");
break;
+ case SYS_MSG_TYPE_PROC_MSG:
+ erts_fprintf(stderr, "PROC_MSG ");
+ break;
default:
erts_fprintf(stderr, "??? ");
break;
@@ -2241,6 +2252,8 @@ sys_msg_disp_failure(ErtsSysMsgQ *smqp, Eterm receiver)
no_elgger, tag, CAR(list_val(tp[3])));
break;
}
+ case SYS_MSG_TYPE_PROC_MSG:
+ break;
default:
ASSERT(0);
}
@@ -2358,6 +2371,9 @@ sys_msg_dispatcher_func(void *unused)
print_msg_type(smqp);
#endif
switch (smqp->type) {
+ case SYS_MSG_TYPE_PROC_MSG:
+ receiver = smqp->to;
+ break;
case SYS_MSG_TYPE_SYSMON:
receiver = erts_get_system_monitor();
if (smqp->from == receiver) {
diff --git a/erts/emulator/beam/erl_trace.h b/erts/emulator/beam/erl_trace.h
index 14d0c36016..177fd373a6 100644
--- a/erts/emulator/beam/erl_trace.h
+++ b/erts/emulator/beam/erl_trace.h
@@ -87,6 +87,7 @@ void erts_foreach_sys_msg_in_q(void (*func)(Eterm,
Eterm,
ErlHeapFragment *));
void erts_queue_error_logger_message(Eterm, Eterm, ErlHeapFragment *);
+void erts_send_sys_msg_proc(Eterm, Eterm, Eterm, ErlHeapFragment *);
#endif
void trace_send(Process*, Eterm, Eterm);