diff options
author | Lukas Larsson <[email protected]> | 2016-04-05 11:26:52 +0200 |
---|---|---|
committer | Lukas Larsson <[email protected]> | 2016-04-15 15:08:52 +0200 |
commit | c3e7acb4fe304d117f7361292d36f5d73df3e1c7 (patch) | |
tree | 50777c8c13d2e4eeba302b446c14683821dcd83b | |
parent | a1b352dfc68d501a385240cdb7f45a96cf9e3358 (diff) | |
download | otp-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.
-rw-r--r-- | erts/doc/src/erlang.xml | 13 | ||||
-rw-r--r-- | erts/emulator/beam/erl_bif_trace.c | 23 | ||||
-rw-r--r-- | erts/emulator/beam/erl_trace.c | 16 | ||||
-rw-r--r-- | erts/emulator/beam/erl_trace.h | 1 |
4 files changed, 42 insertions, 11 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index fde04504c8..423ccdf98f 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -8958,7 +8958,11 @@ timestamp() -> <name name="trace_delivered" arity="1"/> <fsummary>Notification when trace has been delivered.</fsummary> <desc> - <p>The delivery of trace messages is dislocated on the time-line + <p>The delivery of trace messages (generated by + <seealso marker="#trace/3"><c>erlang:trace/3</c></seealso>, + <seealso marker="kernel:seq_trace"><c>seq_trace</c></seealso> or + <seealso marker="#system_profile/2"><c>erlang:system_profile/2</c></seealso>) + is dislocated on the time-line compared to other events in the system. If you know that <c><anno>Tracee</anno></c> has passed some specific point in its execution, @@ -8984,8 +8988,11 @@ timestamp() -> or previously existing on the same node as the caller of <c>erlang:trace_delivered(<anno>Tracee</anno>)</c> resides on. The special <c><anno>Tracee</anno></c> atom <c>all</c> - denotes all processes - that currently are traced in the node.</p> + denotes all processes that currently are traced in the node.</p> + <p>When used together with an <seealso marker="#erl_tracer"> + Tracer Module</seealso> any message sent in the trace callback + is guaranteed to have reached it's recipient before the + <c>trace_delivered</c> message is sent.</p> <p>Example: Process <c>A</c> is <c><anno>Tracee</anno></c>, port <c>B</c> is tracer, and process <c>C</c> is the port owner of <c>B</c>. <c>C</c> wants to close <c>B</c> when 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); |