diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 25 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_mmap.c | 8 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_mmap.h | 12 | ||||
-rw-r--r-- | erts/emulator/test/trace_port_SUITE.erl | 22 |
4 files changed, 50 insertions, 17 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 039f97ef43..23931f0e54 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -769,32 +769,25 @@ enif_port_command(ErlNifEnv *env, const ErlNifPort* to_port, if (scheduler > 0) prt = erts_port_lookup(to_port->port_id, iflags); -#ifdef ERTS_DIRTY_SCHEDULERS - else if (scheduler < 0) { + else { +#ifdef ERTS_SMP if (ERTS_PROC_IS_EXITING(c_p)) return 0; prt = erts_thr_port_lookup(to_port->port_id, iflags); - } +#else + erts_exit(ERTS_ABORT_EXIT, + "enif_port_command: called from non-scheduler " + "thread on non-SMP VM"); #endif - else { - erts_exit(ERTS_ABORT_EXIT, "enif_port_command: " - "called from non-scheduler thread"); } if (!prt) res = 0; - else { - - if (IS_TRACED_FL(prt, F_TRACE_RECEIVE)) - trace_port_receive(prt, c_p->common.id, am_command, msg); - - res = erts_port_output_async(prt, c_p->common.id, msg); - } + else + res = erts_port_output_async(prt, c_p->common.id, msg); -#ifdef ERTS_DIRTY_SCHEDULERS - if (scheduler < 0) + if (scheduler <= 0) erts_port_dec_refc(prt); -#endif return res; } diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c index 53009a1481..7bbb406f29 100644 --- a/erts/emulator/sys/common/erl_mmap.c +++ b/erts/emulator/sys/common/erl_mmap.c @@ -1334,9 +1334,17 @@ os_mremap(void *ptr, UWord old_size, UWord new_size, int try_superalign) #define ERTS_MMAP_RESERVE_PROT_EXEC (ERTS_MMAP_PROT_EXEC) #define ERTS_MMAP_RESERVE_FLAGS (ERTS_MMAP_FLAGS|MAP_FIXED) #define ERTS_MMAP_UNRESERVE_PROT (PROT_NONE) +#if defined(__FreeBSD__) +#define ERTS_MMAP_UNRESERVE_FLAGS (ERTS_MMAP_FLAGS|MAP_FIXED) +#else #define ERTS_MMAP_UNRESERVE_FLAGS (ERTS_MMAP_FLAGS|MAP_NORESERVE|MAP_FIXED) +#endif /* __FreeBSD__ */ #define ERTS_MMAP_VIRTUAL_PROT (PROT_NONE) +#if defined(__FreeBSD__) +#define ERTS_MMAP_VIRTUAL_FLAGS (ERTS_MMAP_FLAGS) +#else #define ERTS_MMAP_VIRTUAL_FLAGS (ERTS_MMAP_FLAGS|MAP_NORESERVE) +#endif /* __FreeBSD__ */ static int os_reserve_physical(char *ptr, UWord size, int exec) diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h index 7ac61a82c1..fa51b663fa 100644 --- a/erts/emulator/sys/common/erl_mmap.h +++ b/erts/emulator/sys/common/erl_mmap.h @@ -38,7 +38,17 @@ # if HAVE_MREMAP # define ERTS_HAVE_OS_MREMAP 1 # endif -# if defined(MAP_FIXED) && defined(MAP_NORESERVE) +/* + * MAP_NORESERVE is undefined in FreeBSD 10.x and later. + * This is to enable 64bit HiPE experimentally on FreeBSD. + * Note that on FreeBSD MAP_NORESERVE was "never implemented" + * even before 11.x (and the flag does not exist in /usr/src/sys/vm/mmap.c + * of 10.3-STABLE r301478 either), and HiPE was working on OTP 18.3.3, + * so mandating MAP_NORESERVE on FreeBSD might not be needed. + * See the following message on how MAP_NORESERVE was treated on FreeBSD: + * <http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150202/122958.html> + */ +# if defined(MAP_FIXED) && (defined(MAP_NORESERVE) || defined(__FreeBSD__)) # define ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION 1 # endif #endif diff --git a/erts/emulator/test/trace_port_SUITE.erl b/erts/emulator/test/trace_port_SUITE.erl index a66563d15b..e4db368ea1 100644 --- a/erts/emulator/test/trace_port_SUITE.erl +++ b/erts/emulator/test/trace_port_SUITE.erl @@ -26,6 +26,7 @@ return_trace/1, send/1, receive_trace/1, + receive_trace_non_scheduler/1, process_events/1, schedule/1, gc/1, @@ -40,6 +41,7 @@ suite() -> all() -> [call_trace, return_trace, send, receive_trace, + receive_trace_non_scheduler, process_events, schedule, gc, default_tracer, tracer_port_crash]. @@ -184,6 +186,26 @@ receive_trace(Config) when is_list(Config) -> expect({trace_ts,Receiver,'receive',Huge,ts}), ok. +%% Test sending receive traces to a port. +receive_trace_non_scheduler(Config) when is_list(Config) -> + start_tracer(Config), + S = self(), + Receiver = spawn( + fun() -> + receive + go -> + Ref = S ! erlang:trace_delivered(all), + receive {trace_delivered, Ref, all} -> ok end + end + end), + trac(Receiver, true, ['receive']), + Receiver ! go, + Ref = receive R -> R end, + expect({trace,Receiver,'receive',go}), + expect({trace,Receiver,'receive',{trace_delivered, all, Ref}}), + + ok. + %% Tests a few process events (like getting linked). process_events(Config) when is_list(Config) -> start_tracer(Config), |