aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/doc/src/erl_tracer.xml13
-rw-r--r--erts/doc/src/notes.xml20
-rw-r--r--erts/emulator/Makefile.in4
-rw-r--r--erts/emulator/beam/bif.c6
-rw-r--r--erts/emulator/beam/erl_alloc_util.c12
-rw-r--r--erts/emulator/beam/erl_alloc_util.h7
-rw-r--r--erts/emulator/beam/erl_bits.c2
-rw-r--r--erts/emulator/beam/erl_bits.h1
-rw-r--r--erts/emulator/beam/erl_cpu_topology.c57
-rw-r--r--erts/emulator/beam/erl_db_hash.c2
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c16
-rw-r--r--erts/emulator/test/gc_SUITE.erl151
12 files changed, 127 insertions, 164 deletions
diff --git a/erts/doc/src/erl_tracer.xml b/erts/doc/src/erl_tracer.xml
index 63feebb0b5..fd3c17f337 100644
--- a/erts/doc/src/erl_tracer.xml
+++ b/erts/doc/src/erl_tracer.xml
@@ -653,7 +653,7 @@ ok
<0.37.0>
3> erlang:trace(new, true, [send,{tracer, erl_msg_tracer, Tracer}]).
0
-{<0.39.0>,<0.27.0>}
+{trace,<0.39.0>,<0.27.0>}
4> {ok, D} = file:open("/tmp/tmp.data",[write]).
{trace,#Port<0.486>,<0.40.0>}
{trace,<0.40.0>,<0.21.0>}
@@ -758,18 +758,21 @@ static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
/*
* argv[0]: TraceTag, should only be 'send'
- * argv[1]: TracerState, process to send {argv[2], argv[4]} to
+ * argv[1]: TracerState, process to send {Tracee, Recipient} to
* argv[2]: Tracee
- * argv[3]: Recipient
- * argv[4]: Options, ignored
+ * argv[3]: Message
+ * argv[4]: Options, map containing Recipient
*/
static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifPid to_pid;
+ ERL_NIF_TERM recipient, msg;
if (enif_get_local_pid(env, argv[1], &to_pid)) {
- ERL_NIF_TERM msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], argv[4]);
+ if (enif_get_map_value(env, argv[4], enif_make_atom(env, "extra"), &recipient)) {
+ msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], recipient);
enif_send(env, &to_pid, NULL, msg);
+ }
}
return enif_make_atom(env, "ok");
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 08f6732036..8ae87ac280 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -32,6 +32,26 @@
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 8.3.4</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ Add option to make SIGTERM trigger the OS default
+ behaviour instead of doing a gracefull shutdown. To
+ activate this bahviour the environment variable
+ ERL_ZZ_SIGTERM_KILL should be set to "true". This option
+ only works in OTP 19 as OTP 20 will have a different way
+ to deal with SIGTERM.</p>
+ <p>
+ Own Id: OTP-14418 Aux Id: ERIERL-15 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 8.3.3</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index 254e59f2c7..61c1e14741 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -149,6 +149,8 @@ endif
LIBS += $(TYPE_LIBS)
+ORIG_LIBS:= $(LIBS)
+
comma:=,
space:=
space+=
@@ -965,7 +967,7 @@ $(OBJDIR)/%.o: hipe/%.c
$(V_CC) $(subst O2,O3, $(CFLAGS)) $(INCLUDES) -c $< -o $@
$(BINDIR)/hipe_mkliterals$(TF_MARKER): $(OBJDIR)/hipe_mkliterals.o
- $(ld_verbose)$(CC) $(LDFLAGS) -o $@ $< $(TYPE_LIBS)
+ $(ld_verbose)$(CC) $(LDFLAGS) -o $@ $< $(ORIG_LIBS)
$(OBJDIR)/hipe_mkliterals.o: $(HIPE_ASM) $(TTF_DIR)/erl_alloc_types.h $(DTRACE_HEADERS) \
$(TTF_DIR)/OPCODES-GENERATED $(TTF_DIR)/TABLES-GENERATED
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 7134d2da56..40dd4129d2 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -2047,8 +2047,6 @@ ebif_bang_2(BIF_ALIST_2)
#define SEND_YIELD_CONTINUE (-8)
-Sint do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext*);
-
static Sint remote_send(Process *p, DistEntry *dep,
Eterm to, Eterm full_to, Eterm msg,
ErtsSendContext* ctx)
@@ -2102,8 +2100,8 @@ static Sint remote_send(Process *p, DistEntry *dep,
return res;
}
-Sint
-do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext* ctx)
+static Sint
+do_send(Process *p, Eterm to, Eterm msg, Eterm *refp, ErtsSendContext *ctx)
{
Eterm portid;
Port *pt;
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 4889fac923..6fddba4b34 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -821,7 +821,7 @@ static void clear_literal_range(void* start, Uint size)
#if HAVE_ERTS_MSEG
-void*
+static void*
erts_alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p, Uint flags)
{
void *res;
@@ -832,7 +832,7 @@ erts_alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p, Uint flags)
return res;
}
-void*
+static void*
erts_alcu_mseg_realloc(Allctr_t *allctr, void *seg,
Uint old_size, Uint *new_size_p)
{
@@ -845,7 +845,7 @@ erts_alcu_mseg_realloc(Allctr_t *allctr, void *seg,
return res;
}
-void
+static void
erts_alcu_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size, Uint flags)
{
erts_mseg_dealloc_opt(allctr->alloc_no, seg, (UWord) size, flags, &allctr->mseg_opt);
@@ -996,7 +996,7 @@ erts_alcu_exec_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size, Uint flags)
#endif /* HAVE_ERTS_MSEG */
-void*
+static void*
erts_alcu_sys_alloc(Allctr_t *allctr, Uint* size_p, int superalign)
{
void *res;
@@ -1013,7 +1013,7 @@ erts_alcu_sys_alloc(Allctr_t *allctr, Uint* size_p, int superalign)
return res;
}
-void*
+static void*
erts_alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint *size_p, Uint old_size, int superalign)
{
void *res;
@@ -1035,7 +1035,7 @@ erts_alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint *size_p, Uint old_size,
return res;
}
-void
+static void
erts_alcu_sys_dealloc(Allctr_t *allctr, void *ptr, Uint size, int superalign)
{
#if ERTS_SA_MB_CARRIERS && ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index f570703f25..7a96bd0319 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -195,10 +195,6 @@ extern UWord erts_literal_vspace_map[];
# define ERTS_VSPACE_WORD_BITS (sizeof(UWord)*8)
#endif
-void* erts_alcu_mseg_alloc(Allctr_t*, Uint *size_p, Uint flags);
-void* erts_alcu_mseg_realloc(Allctr_t*, void *seg, Uint old_size, Uint *new_size_p);
-void erts_alcu_mseg_dealloc(Allctr_t*, void *seg, Uint size, Uint flags);
-
#if HAVE_ERTS_MSEG
# if defined(ARCH_32)
void* erts_alcu_literal_32_mseg_alloc(Allctr_t*, Uint *size_p, Uint flags);
@@ -218,9 +214,6 @@ void erts_alcu_exec_mseg_dealloc(Allctr_t*, void *seg, Uint size, Uint flags);
# endif
#endif /* HAVE_ERTS_MSEG */
-void* erts_alcu_sys_alloc(Allctr_t*, Uint *size_p, int superalign);
-void* erts_alcu_sys_realloc(Allctr_t*, void *ptr, Uint *size_p, Uint old_size, int superalign);
-void erts_alcu_sys_dealloc(Allctr_t*, void *ptr, Uint size, int superalign);
#ifdef ARCH_32
void* erts_alcu_literal_32_sys_alloc(Allctr_t*, Uint *size_p, int superalign);
void* erts_alcu_literal_32_sys_realloc(Allctr_t*, void *ptr, Uint *size_p, Uint old_size, int superalign);
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index eea55b3239..71c64997c1 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -1636,7 +1636,7 @@ erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb)
return LSB[0] | (LSB[1]<<8) | (LSB[2]<<16) | (LSB[3]<<24);
}
-void
+static void
erts_align_utf8_bytes(ErlBinMatchBuffer* mb, byte* buf)
{
Uint bits = mb->size - mb->offset;
diff --git a/erts/emulator/beam/erl_bits.h b/erts/emulator/beam/erl_bits.h
index 632855255e..5da2b28a89 100644
--- a/erts/emulator/beam/erl_bits.h
+++ b/erts/emulator/beam/erl_bits.h
@@ -202,7 +202,6 @@ void erts_new_bs_put_string(ERL_BITS_PROTO_2(byte* iptr, Uint num_bytes));
Uint erts_bits_bufs_size(void);
Uint32 erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb);
-void erts_align_utf8_bytes(ErlBinMatchBuffer* mb, byte* buf);
Eterm erts_bs_get_utf8(ErlBinMatchBuffer* mb);
Eterm erts_bs_get_utf16(ErlBinMatchBuffer* mb, Uint flags);
Eterm erts_bs_append(Process* p, Eterm* reg, Uint live, Eterm build_size_term,
diff --git a/erts/emulator/beam/erl_cpu_topology.c b/erts/emulator/beam/erl_cpu_topology.c
index 4347f9f2b7..d0fd763798 100644
--- a/erts/emulator/beam/erl_cpu_topology.c
+++ b/erts/emulator/beam/erl_cpu_topology.c
@@ -2243,45 +2243,6 @@ add_cpu_groups(int groups,
return cgm;
}
-static void
-remove_cpu_groups(erts_cpu_groups_callback_t callback, void *arg)
-{
- erts_cpu_groups_map_t *prev_cgm, *cgm;
- erts_cpu_groups_callback_list_t *prev_cgcl, *cgcl;
-
- ERTS_SMP_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&cpuinfo_rwmtx));
-
- no_cpu_groups_callbacks--;
-
- prev_cgm = NULL;
- for (cgm = cpu_groups_maps; cgm; cgm = cgm->next) {
- prev_cgcl = NULL;
- for (cgcl = cgm->callback_list; cgcl; cgcl = cgcl->next) {
- if (cgcl->callback == callback && cgcl->arg == arg) {
- if (prev_cgcl)
- prev_cgcl->next = cgcl->next;
- else
- cgm->callback_list = cgcl->next;
- erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgcl);
- if (!cgm->callback_list) {
- if (prev_cgm)
- prev_cgm->next = cgm->next;
- else
- cpu_groups_maps = cgm->next;
- if (cgm->array)
- erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm->array);
- erts_free(ERTS_ALC_T_CPU_GRPS_MAP, cgm);
- }
- return;
- }
- prev_cgcl = cgcl;
- }
- prev_cgm = cgm;
- }
-
- erts_exit(ERTS_ABORT_EXIT, "Cpu groups not found\n");
-}
-
static int
cpu_groups_lookup(erts_cpu_groups_map_t *map,
ErtsSchedulerData *esdp)
@@ -2321,21 +2282,3 @@ update_cpu_groups_maps(void)
for (cgm = cpu_groups_maps; cgm; cgm = cgm->next)
make_cpu_groups_map(cgm, 0);
}
-
-void
-erts_add_cpu_groups(int groups,
- erts_cpu_groups_callback_t callback,
- void *arg)
-{
- erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
- add_cpu_groups(groups, callback, arg);
- erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
-}
-
-void erts_remove_cpu_groups(erts_cpu_groups_callback_t callback,
- void *arg)
-{
- erts_smp_rwmtx_rwlock(&cpuinfo_rwmtx);
- remove_cpu_groups(callback, arg);
- erts_smp_rwmtx_rwunlock(&cpuinfo_rwmtx);
-}
diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c
index 08a0f0e83b..0addfaa3c7 100644
--- a/erts/emulator/beam/erl_db_hash.c
+++ b/erts/emulator/beam/erl_db_hash.c
@@ -676,7 +676,7 @@ int db_create_hash(Process *p, DbTable *tbl)
sizeof(DbTableHashFineLocks));
for (i=0; i<DB_HASH_LOCK_CNT; ++i) {
erts_smp_rwmtx_init_opt_x(&tb->locks->lck_vec[i].lck, &rwmtx_opt,
- "db_hash_slot", make_small(i));
+ "db_hash_slot", tb->common.the_name);
}
/* This important property is needed to guarantee the two buckets
* involved in a grow/shrink operation it protected by the same lock:
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index 0acc2432a7..f8341f788a 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -969,17 +969,21 @@ efile_sendfile(Efile_error* errInfo, int in_fd, int out_fd,
fdrec.sfv_len = SENDFILE_CHUNK_SIZE;
else
fdrec.sfv_len = *nbytes;
+
retval = sendfilev(out_fd, &fdrec, 1, &len);
- /* Sometimes sendfilev can return -1 and still send data.
- When that happens we just pretend that no error happend. */
- if (retval != -1 || errno == EAGAIN || errno == EINTR ||
- len != 0) {
+ if (retval == -1 && errno == EINVAL) {
+ /* On some solaris versions (I've seen it on SunOS 5.10),
+ using a sfv_len larger then a filesize will result in
+ a -1 && errno == EINVAL return. We translate this so
+ a successful send of the data.*/
+ retval = len;
+ }
+
+ if (retval != -1 || errno == EAGAIN || errno == EINTR) {
*offset += len;
*nbytes -= len;
written += len;
- if (errno != EAGAIN && errno != EINTR && len != 0)
- retval = len;
}
} while (len == SENDFILE_CHUNK_SIZE);
#elif defined(__DARWIN__)
diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl
index 35dd147550..2c2cb9c32d 100644
--- a/erts/emulator/test/gc_SUITE.erl
+++ b/erts/emulator/test/gc_SUITE.erl
@@ -203,89 +203,90 @@ long_receive() ->
end.
minor_major_gc_option_self(_Config) ->
- Endless = fun Endless() ->
- receive
- {gc, Type} -> erlang:garbage_collect(self(), [{type, Type}])
- after 100 -> ok end,
- Endless()
- end,
-
- %% Try as major, a test process will self-trigger GC
- P1 = spawn(Endless),
- erlang:garbage_collect(P1, []),
- erlang:trace(P1, true, [garbage_collection]),
- P1 ! {gc, major},
- expect_trace_messages(P1, [gc_major_start, gc_major_end]),
- erlang:trace(P1, false, [garbage_collection]),
- erlang:exit(P1, kill),
-
- %% Try as minor, a test process will self-trigger GC
- P2 = spawn(Endless),
- erlang:garbage_collect(P2, []),
- erlang:trace(P2, true, [garbage_collection]),
- P2 ! {gc, minor},
- expect_trace_messages(P2, [gc_minor_start, gc_minor_end]),
- erlang:trace(P2, false, [garbage_collection]),
- erlang:exit(P2, kill).
+ %% Try as major, the test process will self-trigger GC
+ check_gc_tracing_around(
+ fun(Pid, Ref) ->
+ Pid ! {gc, Ref, major}
+ end, [gc_major_start, gc_major_end]),
+
+ %% Try as minor, the test process will self-trigger GC
+ check_gc_tracing_around(
+ fun(Pid, Ref) ->
+ Pid ! {gc, Ref, minor}
+ end, [gc_minor_start, gc_minor_end]).
minor_major_gc_option_async(_Config) ->
- Endless = fun Endless() ->
- receive after 100 -> ok end,
- Endless()
- end,
-
- %% Try with default option, must be major gc
- P1 = spawn(Endless),
- erlang:garbage_collect(P1, []),
- erlang:trace(P1, true, [garbage_collection]),
- erlang:garbage_collect(P1, []),
- expect_trace_messages(P1, [gc_major_start, gc_major_end]),
- erlang:trace(P1, false, [garbage_collection]),
- erlang:exit(P1, kill),
+ %% Try with default option, must be major GC
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ erlang:garbage_collect(Pid, [])
+ end, [gc_major_start, gc_major_end]),
%% Try with the 'major' type
- P2 = spawn(Endless),
- erlang:garbage_collect(P2, []),
- erlang:trace(P2, true, [garbage_collection]),
- erlang:garbage_collect(P2, [{type, major}]),
- expect_trace_messages(P2, [gc_major_start, gc_major_end]),
- erlang:trace(P2, false, [garbage_collection]),
- erlang:exit(P2, kill),
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ erlang:garbage_collect(Pid, [{type, major}])
+ end, [gc_major_start, gc_major_end]),
%% Try with 'minor' option, once
- P3 = spawn(Endless),
- erlang:garbage_collect(P3, []),
- erlang:trace(P3, true, [garbage_collection]),
- erlang:garbage_collect(P3, [{type, minor}]),
- expect_trace_messages(P3, [gc_minor_start, gc_minor_end]),
- erlang:trace(P3, false, [garbage_collection]),
- erlang:exit(P3, kill),
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ erlang:garbage_collect(Pid, [{type, minor}])
+ end, [gc_minor_start, gc_minor_end]),
%% Try with 'minor' option, once, async
- P4 = spawn(Endless),
+ check_gc_tracing_around(
+ fun(Pid, Ref) ->
+ ?assertEqual(async,
+ erlang:garbage_collect(Pid, [{type, minor}, {async, Ref}])),
+
+ receive
+ {garbage_collect, Ref, true} ->
+ ok
+ after 10000 ->
+ ct:fail("Did not receive a completion notification on async GC")
+ end
+ end, [gc_minor_start, gc_minor_end]).
+
+%% Traces garbage collection around the given operation, and fails the test if
+%% it results in any unexpected messages or if the expected trace tags are not
+%% received.
+check_gc_tracing_around(Fun, ExpectedTraceTags) ->
Ref = erlang:make_ref(),
- erlang:garbage_collect(P4, []),
- erlang:trace(P4, true, [garbage_collection]),
- ?assertEqual(async,
- erlang:garbage_collect(P4, [{type, minor}, {async, Ref}])),
- expect_trace_messages(P4, [gc_minor_start, gc_minor_end]),
- erlang:trace(P4, false, [garbage_collection]),
- receive {garbage_collect, Ref, true} -> ok;
- Other4 -> ct:pal("Unexpected message: ~p~n"
- ++ "while waiting for async gc result", [Other4])
- after 2000 -> ?assert(false)
- end,
- erlang:exit(P4, kill).
-
-%% Given a list of atoms, trace tags - receives messages and checks if they are
-%% trace events, and if the tag matches. Else will crash failing the test.
-expect_trace_messages(_Pid, []) -> ok;
+ Pid = spawn(
+ fun Endless() ->
+ receive
+ {gc, Ref, Type} ->
+ erlang:garbage_collect(self(), [{type, Type}])
+ after 100 ->
+ ok
+ end,
+ Endless()
+ end),
+ erlang:garbage_collect(Pid, []),
+ erlang:trace(Pid, true, [garbage_collection]),
+ Fun(Pid, Ref),
+ expect_trace_messages(Pid, ExpectedTraceTags),
+ erlang:trace(Pid, false, [garbage_collection]),
+ erlang:exit(Pid, kill),
+ check_no_unexpected_messages().
+
+%% Ensures that trace messages with the provided tags have all been received
+%% within a reasonable timeframe.
+expect_trace_messages(_Pid, []) ->
+ ok;
expect_trace_messages(Pid, [Tag | TraceTags]) ->
receive
- {trace, Pid, Tag, _Data} -> ok;
- AnythingElse ->
- ct:pal("Unexpected message: ~p~nWhile expected {trace, _, ~p, _}",
- [AnythingElse, Tag]),
- ?assert(false)
- end,
- expect_trace_messages(Pid, TraceTags).
+ {trace, Pid, Tag, _Data} ->
+ expect_trace_messages(Pid, TraceTags)
+ after 4000 ->
+ ct:fail("Didn't receive tag ~p within 4000ms", [Tag])
+ end.
+
+check_no_unexpected_messages() ->
+ receive
+ Anything ->
+ ct:fail("Unexpected message: ~p", [Anything])
+ after 0 ->
+ ok
+ end.