aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/configure.in2
-rw-r--r--erts/doc/src/erlang.xml4
-rw-r--r--erts/doc/src/erts_alloc.xml48
-rw-r--r--erts/emulator/beam/bif.tab1
-rw-r--r--erts/emulator/beam/break.c2
-rw-r--r--erts/emulator/beam/dist.c4
-rw-r--r--erts/emulator/beam/erl_alloc.c50
-rw-r--r--erts/emulator/beam/erl_alloc_util.c25
-rw-r--r--erts/emulator/beam/erl_alloc_util.h7
-rwxr-xr-xerts/emulator/beam/erl_bif_info.c4
-rw-r--r--erts/emulator/beam/erl_bif_os.c22
-rw-r--r--erts/emulator/beam/erl_process_dump.c46
-rw-r--r--erts/emulator/beam/sys.h2
-rw-r--r--erts/emulator/sys/common/erl_mmap.c12
-rw-r--r--erts/emulator/sys/common/erl_mmap.h4
-rw-r--r--erts/emulator/sys/unix/sys.c10
-rw-r--r--erts/emulator/sys/win32/sys_env.c18
-rw-r--r--erts/emulator/test/alloc_SUITE.erl12
-rw-r--r--erts/emulator/test/bif_SUITE.erl10
-rw-r--r--erts/emulator/test/hash_SUITE.erl6
-rw-r--r--erts/etc/common/erlexec.c4
-rw-r--r--erts/etc/unix/cerl.src30
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin54536 -> 54672 bytes
-rw-r--r--erts/preloaded/src/Makefile2
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl7
-rw-r--r--erts/test/z_SUITE.erl31
26 files changed, 289 insertions, 74 deletions
diff --git a/erts/configure.in b/erts/configure.in
index 8288a1aab1..b47a6ff094 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1977,7 +1977,7 @@ AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlop
gethrtime localtime_r gmtime_r inet_pton \
mmap mremap memcpy mallopt sbrk _sbrk __sbrk brk _brk __brk \
flockfile fstat strlcpy strlcat setsid posix2time time2posix \
- setlocale nl_langinfo poll])
+ setlocale nl_langinfo poll mlockall])
case X$erl_xcomp_posix_memalign in
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index bc38055b62..cbb25c2cf2 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -4727,8 +4727,8 @@ true</pre>
<name name="statistics" arity="1" clause_i="6"/>
<fsummary>Information about the run-queue</fsummary>
<desc>
- <p>Returns the length of the run queue, that is, the number
- of processes that are ready to run.</p>
+ <p>Returns the total length of the run queues, that is, the number
+ of processes that are ready to run on all available run queues.</p>
</desc>
</func>
<func>
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 9dab5b3876..a0ec89f398 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -271,22 +271,18 @@
memory segment cache is not reused if its size exceeds the
requested size with more than relative max cache bad fit
percent of the requested size. Default value is 20.</item>
- <tag><marker id="MMscmgc"><c><![CDATA[+MMscmgc <amount>]]></c></marker></tag>
- <item>
- Set <seealso marker="#MMscs">super carrier</seealso> max guaranteed
- no of carriers. This parameter defaults to <c>65536</c>. This
- parameter determines an amount of pre-allocated structures that is
- needed in order to keep track of different areas in the super carrier.
- When the system runs out of such structures it may crash due to an
- out of memory condition.
- </item>
<tag><marker id="MMsco"><c><![CDATA[+MMsco true|false]]></c></marker></tag>
<item>
Set <seealso marker="#MMscs">super carrier</seealso> only flag. This
flag defaults to <c>true</c>. When a super carrier is used and this
- flag is <c>true</c>, the system will crash when a carrier request
- cannot be satisfied by the super carrier. When the flag is <c>false</c>
- the system will try to create requested carrier by other means.
+ flag is <c>true</c>, <c>mseg_alloc</c> will only create carriers
+ in the super carrier. Note that the <c>alloc_util</c> framework may
+ create <c>sys_alloc</c> carriers, so if you want all carriers to
+ be created in the super carrier, you therefore want to disable use
+ of <c>sys_alloc</c> carriers by also passing
+ <seealso marker="#Musac"><c>+Musac false</c></seealso>. When the flag
+ is <c>false</c>, <c>mseg_alloc</c> will try to create carriers outside
+ of the super carrier when the super carrier is full.
<br/><br/>
<em>NOTE</em>: Setting this flag to <c>false</c> may not be supported
on all systems. This flag will in that case be ignored.
@@ -295,6 +291,19 @@
disabled on halfword heap systems. This flag will be
ignored on halfword heap systems.
</item>
+ <tag><marker id="MMscrfsd"><c><![CDATA[+MMscrfsd <amount>]]></c></marker></tag>
+ <item>
+ Set <seealso marker="#MMscs">super carrier</seealso> reserved
+ free segment descriptors. This parameter defaults to <c>65536</c>.
+ This parameter determines the amount of memory to reserve for
+ free segment descriptors used by the super carrier. If the system
+ runs out of reserved memory for free segment descriptors, other
+ memory will be used. This may however cause fragmentation issues,
+ so you want to ensure that this never happens. The maximum amount
+ of free segment descriptors used can be retrieved from the
+ <c>erts_mmap</c> tuple part of the result from calling
+ <seealso marker="erts:erlang#system_info_allocator_tuple">erlang:system_info({allocator, mseg_alloc})</seealso>.
+ </item>
<tag><marker id="MMscrpm"><c><![CDATA[+MMscrpm true|false]]></c></marker></tag>
<item>
Set <seealso marker="#MMscs">super carrier</seealso> reserve physical
@@ -549,6 +558,11 @@
placed in separate memory segments. When this limit has been
reached, new carriers will be placed in memory retrieved from
<c>sys_alloc</c>.</item>
+ <tag><marker id="Musac"><c><![CDATA[+Musac <bool>]]></c></marker></tag>
+ <item>
+ Allow <c>sys_alloc</c> carriers. By default <c>true</c>. If
+ set to <c>false</c>, <c>sys_alloc</c> carriers will never be
+ created by allocators using the <c>alloc_util</c> framework.</item>
</taglist>
<p>Instrumentation flags:</p>
<taglist>
@@ -604,6 +618,16 @@
</item>
</taglist>
</item>
+ <tag><marker id="Mlpm"><c>+Mlpm all|no</c></marker></tag>
+ <item>Lock physical memory. The default value is <c>no</c>, i.e.,
+ no physical memory will be locked. If set to <c>all</c>, all
+ memory mappings made by the runtime system, will be locked into
+ physical memory. If set to <c>all</c>, the runtime system will fail
+ to start if this feature is not supported, the user has not got enough
+ privileges, or the user is not allowed to lock enough physical memory.
+ The runtime system will also fail with an out of memory condition
+ if the user limit on the amount of locked memory is reached.
+ </item>
</taglist>
<p>Only some default values have been presented
here.
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index dc8e9101de..6037c08dd8 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -572,6 +572,7 @@ bif erlang:float_to_binary/2
bif erlang:binary_to_float/1
bif io:printable_range/0
+bif os:unsetenv/1
#
# Obsolete
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 99604fa3bc..b7e1092907 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -757,7 +757,7 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
return; /* Can't create the crash dump, skip it */
time(&now);
- erts_fdprintf(fd, "=erl_crash_dump:0.2\n%s", ctime(&now));
+ erts_fdprintf(fd, "=erl_crash_dump:0.3\n%s", ctime(&now));
if (file != NULL)
erts_fdprintf(fd, "The error occurred in file %s, line %d\n", file, line);
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index aabccac822..6ecf3f0722 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -1509,12 +1509,12 @@ int erts_net_message(Port *prt,
break;
}
rp = erts_pid2proc(NULL, 0, mon->pid, rp_locks);
+
+ erts_destroy_monitor(mon);
if (rp == NULL) {
break;
}
- erts_destroy_monitor(mon);
-
mon = erts_remove_monitor(&ERTS_P_MONITORS(rp), ref);
if (mon == NULL) {
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index d8da616d05..b5ba9bb94a 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -100,6 +100,8 @@ static Uint install_debug_functions(void);
#endif
#endif
+static int lock_all_physical_memory = 0;
+
ErtsAllocatorFunctions_t erts_allctrs[ERTS_ALC_A_MAX+1];
ErtsAllocatorInfo_t erts_allctrs_info[ERTS_ALC_A_MAX+1];
ErtsAllocatorThrSpec_t erts_allctr_thr_spec[ERTS_ALC_A_MAX+1];
@@ -618,6 +620,8 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
hdbg_init();
#endif
+ lock_all_physical_memory = 0;
+
ncpu = eaiop->ncpu;
if (ncpu < 1)
ncpu = 1;
@@ -641,6 +645,20 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
if (argc && argv)
handle_args(argc, argv, &init);
+ if (lock_all_physical_memory) {
+#ifdef HAVE_MLOCKALL
+ errno = 0;
+ if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0) {
+ int err = errno;
+ char *errstr = err ? strerror(err) : "unknown";
+ erl_exit(-1, "Failed to lock physical memory: %s (%d)\n",
+ errstr, err);
+ }
+#else
+ erl_exit(-1, "Failed to lock physical memory: Not supported\n");
+#endif
+ }
+
#ifndef ERTS_SMP
init.sl_alloc.thr_spec = 0;
init.std_alloc.thr_spec = 0;
@@ -1486,11 +1504,11 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
#endif
get_bool_value(argv[i]+8, argv, &i);
}
- else if (has_prefix("scmgc", argv[i]+3)) {
+ else if (has_prefix("scrfsd", argv[i]+3)) {
#if HAVE_ERTS_MSEG
- init->mseg.mmap.scmgc =
+ init->mseg.mmap.scrfsd =
#endif
- get_amount_value(argv[i]+8, argv, &i);
+ get_amount_value(argv[i]+9, argv, &i);
}
else {
bad_param(param, param+2);
@@ -1630,6 +1648,19 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
bad_param(param, param+2);
}
break;
+ case 'l':
+ if (has_prefix("pm", param+2)) {
+ arg = get_value(argv[i]+5, argv, &i);
+ if (strcmp("all", arg) == 0)
+ lock_all_physical_memory = 1;
+ else if (strcmp("no", arg) == 0)
+ lock_all_physical_memory = 0;
+ else
+ bad_value(param, param+4, arg);
+ break;
+ }
+ bad_param(param, param+2);
+ break;
case 'u':
if (has_prefix("ycs", argv[i]+3)) {
init->alloc_util.ycs
@@ -1639,6 +1670,10 @@ handle_args(int *argc, char **argv, erts_alc_hndl_args_init_t *init)
init->alloc_util.mmc
= get_amount_value(argv[i]+6, argv, &i);
}
+ else if (has_prefix("sac", argv[i]+3)) {
+ init->alloc_util.sac
+ = get_bool_value(argv[i]+6, argv, &i);
+ }
else {
int a;
int start = i;
@@ -2749,8 +2784,8 @@ erts_allocator_options(void *proc)
#endif
Uint sz, *szp, *hp, **hpp;
Eterm res, features, settings;
- Eterm atoms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+6];
- Uint terms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+6];
+ Eterm atoms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+7];
+ Uint terms[ERTS_ALC_A_MAX-ERTS_ALC_A_MIN+7];
int a, length;
SysAllocStat sas;
Uint *endp = NULL;
@@ -2848,6 +2883,11 @@ erts_allocator_options(void *proc)
terms[length++] = erts_bld_2tup_list(hpp, szp, 3, o, v);
}
+ atoms[length] = am_atom_put("lock_physical_memory", 20);
+ terms[length++] = (lock_all_physical_memory
+ ? am_atom_put("all", 3)
+ : am_atom_put("no", 2));
+
settings = erts_bld_2tup_list(hpp, szp, length, atoms, terms);
length = 0;
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index a6f256a15e..9dce7f6505 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -98,6 +98,7 @@ static Uint sys_alloc_carrier_size;
#if HAVE_ERTS_MSEG
static Uint max_mseg_carriers;
#endif
+static int allow_sys_alloc_carriers;
#define ONE_GIGA (1000000000)
@@ -3256,13 +3257,15 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
int is_mseg = 0;
#endif
-#if HALFWORD_HEAP
- flags |= CFLG_FORCE_MSEG;
-#elif ERTS_SUPER_ALIGNED_MSEG_ONLY
- if (flags & CFLG_MBC) {
+ if (HALFWORD_HEAP
+ || (ERTS_SUPER_ALIGNED_MSEG_ONLY && (flags & CFLG_MBC))
+ || !allow_sys_alloc_carriers) {
flags |= CFLG_FORCE_MSEG;
- }
+ flags &= ~CFLG_FORCE_SYS_ALLOC;
+#if !HAVE_ERTS_MSEG
+ return NULL;
#endif
+ }
ASSERT((flags & CFLG_SBC && !(flags & CFLG_MBC))
|| (flags & CFLG_MBC && !(flags & CFLG_SBC)));
@@ -3697,6 +3700,7 @@ static struct {
Eterm mmc;
#endif
Eterm ycs;
+ Eterm sac;
Eterm fix_types;
@@ -3789,6 +3793,7 @@ init_atoms(Allctr_t *allctr)
AM_INIT(mmc);
#endif
AM_INIT(ycs);
+ AM_INIT(sac);
AM_INIT(fix_types);
@@ -4509,17 +4514,22 @@ erts_alcu_au_info_options(int *print_to_p, void *print_to_arg,
#if HAVE_ERTS_MSEG
"option mmc: %beu\n"
#endif
- "option ycs: %beu\n",
+ "option ycs: %beu\n"
+ "option sac: %s\n",
#if HAVE_ERTS_MSEG
max_mseg_carriers,
#endif
- sys_alloc_carrier_size);
+ sys_alloc_carrier_size,
+ allow_sys_alloc_carriers ? "true" : "false");
}
if (hpp || szp) {
res = NIL;
ensure_atoms_initialized(NULL);
add_2tup(hpp, szp, &res,
+ am.sac,
+ allow_sys_alloc_carriers ? am_true : am_false);
+ add_2tup(hpp, szp, &res,
am.ycs,
bld_uint(hpp, szp, sys_alloc_carrier_size));
#if HAVE_ERTS_MSEG
@@ -5681,6 +5691,7 @@ erts_alcu_init(AlcUInit_t *init)
#else /* #if HAVE_ERTS_MSEG */
sys_alloc_carrier_size = ((init->ycs + 4095) / 4096) * 4096;
#endif
+ allow_sys_alloc_carriers = init->sac;
#ifdef DEBUG
carrier_alignment = sizeof(Unit_t);
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
index 222f137024..7be6b1ed9d 100644
--- a/erts/emulator/beam/erl_alloc_util.h
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -32,6 +32,7 @@ typedef struct Allctr_t_ Allctr_t;
typedef struct {
UWord ycs;
UWord mmc;
+ int sac;
} AlcUInit_t;
typedef struct {
@@ -75,7 +76,8 @@ typedef struct {
#define ERTS_DEFAULT_ALCU_INIT { \
1024*1024, /* (bytes) ycs: sys_alloc carrier size */\
- ~((UWord) 0) /* (amount) mmc: max mseg carriers */ \
+ ~((UWord) 0), /* (amount) mmc: max mseg carriers */\
+ 1 /* (bool) sac: sys_alloc carriers */\
}
#define ERTS_DEFAULT_ALLCTR_INIT { \
@@ -109,7 +111,8 @@ typedef struct {
#define ERTS_DEFAULT_ALCU_INIT { \
128*1024, /* (bytes) ycs: sys_alloc carrier size */\
- 1024 /* (amount) mmc: max mseg carriers */\
+ 1024, /* (amount) mmc: max mseg carriers */\
+ 1 /* (bool) sac: sys_alloc carriers */\
}
#define ERTS_DEFAULT_ALLCTR_INIT { \
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 5fbcbbe250..d7f1e2d971 100755
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -1771,7 +1771,11 @@ info_1_tuple(Process* BIF_P, /* Pointer to current process. */
#if defined(PURIFY)
BIF_RET(erts_make_integer(purify_new_leaks(), BIF_P));
#elif defined(VALGRIND)
+# ifdef VALGRIND_DO_ADDED_LEAK_CHECK
+ VALGRIND_DO_ADDED_LEAK_CHECK;
+# else
VALGRIND_DO_LEAK_CHECK;
+# endif
BIF_RET(make_small(0));
#endif
} else if (*tp == am_fd) {
diff --git a/erts/emulator/beam/erl_bif_os.c b/erts/emulator/beam/erl_bif_os.c
index 1062d4379b..e07c622928 100644
--- a/erts/emulator/beam/erl_bif_os.c
+++ b/erts/emulator/beam/erl_bif_os.c
@@ -180,3 +180,25 @@ BIF_RETTYPE os_putenv_2(BIF_ALIST_2)
BIF_RET(am_true);
}
+BIF_RETTYPE os_unsetenv_1(BIF_ALIST_1)
+{
+ char *key_buf;
+ char buf[STATIC_BUF_SIZE];
+
+ key_buf = erts_convert_filename_to_native(BIF_ARG_1,buf,STATIC_BUF_SIZE,
+ ERTS_ALC_T_TMP,0,0,NULL);
+ if (!key_buf) {
+ BIF_ERROR(BIF_P, BADARG);
+ }
+
+ if (erts_sys_unsetenv(key_buf)) {
+ if (key_buf != buf) {
+ erts_free(ERTS_ALC_T_TMP, key_buf);
+ }
+ BIF_ERROR(BIF_P, BADARG);
+ }
+ if (key_buf != buf) {
+ erts_free(ERTS_ALC_T_TMP, key_buf);
+ }
+ BIF_RET(am_true);
+}
diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c
index 6cd0d23b97..2f3cf23b00 100644
--- a/erts/emulator/beam/erl_process_dump.c
+++ b/erts/emulator/beam/erl_process_dump.c
@@ -34,8 +34,8 @@
#define ERTS_WANT_EXTERNAL_TAGS
#include "external.h"
-#define WORD_FMT "%X"
-#define ADDR_FMT "%X"
+#define PTR_FMT "%bpX"
+#define ETERM_FMT "%beX"
#define OUR_NIL _make_header(0,_TAG_HEADER_FLOAT)
@@ -210,9 +210,9 @@ static void
dump_element(int to, void *to_arg, Eterm x)
{
if (is_list(x)) {
- erts_print(to, to_arg, "H" WORD_FMT, list_val(x));
+ erts_print(to, to_arg, "H" PTR_FMT, list_val(x));
} else if (is_boxed(x)) {
- erts_print(to, to_arg, "H" WORD_FMT, boxed_val(x));
+ erts_print(to, to_arg, "H" PTR_FMT, boxed_val(x));
} else if (is_immed(x)) {
if (is_atom(x)) {
unsigned char* s = atom_tab(atom_val(x))->name;
@@ -311,7 +311,7 @@ heap_dump(int to, void *to_arg, Eterm x)
} else if (is_list(x)) {
ptr = list_val(x);
if (ptr[0] != OUR_NIL) {
- erts_print(to, to_arg, ADDR_FMT ":l", ptr);
+ erts_print(to, to_arg, PTR_FMT ":l", ptr);
dump_element(to, to_arg, ptr[0]);
erts_putc(to, to_arg, '|');
dump_element(to, to_arg, ptr[1]);
@@ -330,12 +330,12 @@ heap_dump(int to, void *to_arg, Eterm x)
ptr = boxed_val(x);
hdr = *ptr;
if (hdr != OUR_NIL) { /* If not visited */
- erts_print(to, to_arg, ADDR_FMT ":", ptr);
+ erts_print(to, to_arg, PTR_FMT ":", ptr);
if (is_arity_value(hdr)) {
Uint i;
Uint arity = arityval(hdr);
- erts_print(to, to_arg, "t" WORD_FMT ":", arity);
+ erts_print(to, to_arg, "t" ETERM_FMT ":", arity);
for (i = 1; i <= arity; i++) {
dump_element(to, to_arg, ptr[i]);
if (is_immed(ptr[i])) {
@@ -388,21 +388,43 @@ heap_dump(int to, void *to_arg, Eterm x)
val->flags = (UWord) all_binaries;
all_binaries = val;
}
- erts_print(to, to_arg, "Yc%X:%X:%X", val,
+ erts_print(to, to_arg,
+ "Yc" PTR_FMT ":" PTR_FMT ":" PTR_FMT,
+ val,
pb->bytes - (byte *)val->orig_bytes,
size);
} else if (tag == SUB_BINARY_SUBTAG) {
ErlSubBin* Sb = (ErlSubBin *) binary_val(x);
- Eterm* real_bin = binary_val(Sb->orig);
+ Eterm* real_bin;
void* val;
+ /*
+ * Must use boxed_val() here, because the original
+ * binary may have been visited and have had its
+ * header word changed to OUR_NIL (in which case
+ * binary_val() will cause an assertion failure in
+ * the DEBUG emulator).
+ */
+
+ real_bin = boxed_val(Sb->orig);
+
if (thing_subtag(*real_bin) == REFC_BINARY_SUBTAG) {
+ /*
+ * Unvisited REFC_BINARY: Point directly to
+ * the binary.
+ */
ProcBin* pb = (ProcBin *) real_bin;
val = pb->val;
- } else { /* Heap binary */
+ } else {
+ /*
+ * Heap binary or visited REFC binary: Point
+ * to heap binary or ProcBin on the heap.
+ */
val = real_bin;
}
- erts_print(to, to_arg, "Ys%X:%X:%X", val, Sb->offs, size);
+ erts_print(to, to_arg,
+ "Ys" PTR_FMT ":" PTR_FMT ":" PTR_FMT,
+ val, Sb->offs, size);
}
erts_putc(to, to_arg, '\n');
*ptr = OUR_NIL;
@@ -438,7 +460,7 @@ dump_binaries(int to, void *to_arg, Binary* current)
long size = current->orig_size;
byte* bytes = (byte*) current->orig_bytes;
- erts_print(to, to_arg, "=binary:%X\n", current);
+ erts_print(to, to_arg, "=binary:" PTR_FMT "\n", current);
erts_print(to, to_arg, "%X:", size);
for (i = 0; i < size; i++) {
erts_print(to, to_arg, "%02X", bytes[i]);
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 9561c0be96..d22f125945 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -750,6 +750,8 @@ int erts_sys_getenv(char *key, char *value, size_t *size);
int erts_sys_getenv_raw(char *key, char *value, size_t *size);
/* erts_sys_getenv__() is only allowed to be used in early init phase */
int erts_sys_getenv__(char *key, char *value, size_t *size);
+/* erst_sys_unsetenv() returns 0 on success and a value != 0 on failure. */
+int erts_sys_unsetenv(char *key);
/* Easier to use, but not as efficient, environment functions */
char *erts_read_env(char *key);
diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c
index a9da7430fb..3f6813e1a5 100644
--- a/erts/emulator/sys/common/erl_mmap.c
+++ b/erts/emulator/sys/common/erl_mmap.c
@@ -2057,7 +2057,7 @@ static struct {
Eterm scs;
Eterm sco;
Eterm scrpm;
- Eterm scmgc;
+ Eterm scrfsd;
int is_initialized;
erts_mtx_t init_mutex;
@@ -2090,7 +2090,7 @@ static void init_atoms(void)
AM_INIT(scs);
AM_INIT(sco);
AM_INIT(scrpm);
- AM_INIT(scmgc);
+ AM_INIT(scrfsd);
am.is_initialized = 1;
}
erts_mtx_unlock(&am.init_mutex);
@@ -2121,7 +2121,7 @@ erts_mmap_init(ErtsMMapInit *init)
#if defined(HARD_DEBUG) || 0
erts_fprintf(stderr, "erts_mmap: scs = %bpu\n", init->scs);
erts_fprintf(stderr, "erts_mmap: sco = %i\n", init->sco);
- erts_fprintf(stderr, "erts_mmap: scmgc = %i\n", init->scmgc);
+ erts_fprintf(stderr, "erts_mmap: scrfsd = %i\n", init->scrfsd);
#endif
erts_page_inv_mask = pagesize - 1;
if (pagesize & erts_page_inv_mask)
@@ -2234,7 +2234,7 @@ erts_mmap_init(ErtsMMapInit *init)
mmap_state.no_os_mmap = init->sco;
- desc_size = init->scmgc;
+ desc_size = init->scrfsd;
if (desc_size < 100)
desc_size = 100;
desc_size *= sizeof(ErtsFreeSegDesc);
@@ -2418,7 +2418,7 @@ Eterm erts_mmap_info_options(char *prefix,
if (mmap_state.supercarrier) {
erts_print(to, arg, "%ssco: %T\n", prefix, sco);
erts_print(to, arg, "%sscrpm: %T\n", prefix, scrpm);
- erts_print(to, arg, "%sscmgc: %beu\n", prefix, mmap_state.desc.reserved);
+ erts_print(to, arg, "%sscrfsd: %beu\n", prefix, mmap_state.desc.reserved);
}
}
@@ -2429,7 +2429,7 @@ Eterm erts_mmap_info_options(char *prefix,
res = NIL;
if (mmap_state.supercarrier) {
- add_2tup(hpp, szp, &res, am.scmgc,
+ add_2tup(hpp, szp, &res, am.scrfsd,
erts_bld_uint(hpp,szp, mmap_state.desc.reserved));
add_2tup(hpp, szp, &res, am.scrpm, scrpm);
add_2tup(hpp, szp, &res, am.sco, sco);
diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h
index e6934dbb26..778a8e0e80 100644
--- a/erts/emulator/sys/common/erl_mmap.h
+++ b/erts/emulator/sys/common/erl_mmap.h
@@ -45,8 +45,8 @@ typedef struct {
} predefined_area;
UWord scs; /* super carrier size */
int sco; /* super carrier only? */
- Uint scmgc; /* super carrier: max guaranteed (number of) carriers */
- int scrpm;
+ UWord scrfsd; /* super carrier reserved free segment descriptors */
+ int scrpm; /* super carrier reserve physical memory */
}ErtsMMapInit;
#define ERTS_MMAP_INIT_DEFAULT_INITER \
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 401b37b9d2..61f9f6a59a 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -2489,6 +2489,16 @@ erts_sys_getenv(char *key, char *value, size_t *size)
return res;
}
+int
+erts_sys_unsetenv(char *key)
+{
+ int res;
+ erts_smp_rwmtx_rwlock(&environ_rwmtx);
+ res = unsetenv(key);
+ erts_smp_rwmtx_rwunlock(&environ_rwmtx);
+ return res;
+}
+
void
sys_init_io(void)
{
diff --git a/erts/emulator/sys/win32/sys_env.c b/erts/emulator/sys/win32/sys_env.c
index 754f4c6e4c..9f977ad6c8 100644
--- a/erts/emulator/sys/win32/sys_env.c
+++ b/erts/emulator/sys/win32/sys_env.c
@@ -141,6 +141,24 @@ void fini_getenv_state(GETENV_STATE *state)
erts_smp_rwmtx_runlock(&environ_rwmtx);
}
+int erts_sys_unsetenv(char *key)
+{
+ int res = 0;
+ WCHAR *wkey = (WCHAR *) key;
+
+ SetLastError(0);
+ erts_smp_rwmtx_rlock(&environ_rwmtx);
+ GetEnvironmentVariableW(wkey,
+ NULL,
+ 0);
+ if (GetLastError() != ERROR_ENVVAR_NOT_FOUND) {
+ res = (SetEnvironmentVariableW(wkey,
+ NULL) ? 0 : 1);
+ }
+ erts_smp_rwmtx_runlock(&environ_rwmtx);
+ return res;
+}
+
char*
win_build_environment(char* new_env)
{
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index f6ff6bb813..cd2d043f7e 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -114,8 +114,8 @@ cpool(Cfg) -> ?line drv_case(Cfg).
erts_mmap(Config) when is_list(Config) ->
case {?t:os_type(), is_halfword_vm()} of
{{unix, _}, false} ->
- [erts_mmap_do(Config, SCO, SCRPM, SCMGC)
- || SCO <-[true,false], SCMGC <-[1234,0], SCRPM <- [true,false]];
+ [erts_mmap_do(Config, SCO, SCRPM, SCRFSD)
+ || SCO <-[true,false], SCRFSD <-[1234,0], SCRPM <- [true,false]];
{_,true} ->
{skipped, "No supercarrier support on halfword vm"};
@@ -126,14 +126,14 @@ erts_mmap(Config) when is_list(Config) ->
end.
-erts_mmap_do(Config, SCO, SCRPM, SCMGC) ->
+erts_mmap_do(Config, SCO, SCRPM, SCRFSD) ->
SCS = 100, % Mb
O1 = "+MMscs" ++ integer_to_list(SCS)
++ " +MMsco" ++ atom_to_list(SCO)
++ " +MMscrpm" ++ atom_to_list(SCRPM),
- Opts = case SCMGC of
+ Opts = case SCRFSD of
0 -> O1;
- _ -> O1 ++ " +MMscmgc"++integer_to_list(SCMGC)
+ _ -> O1 ++ " +MMscrfsd"++integer_to_list(SCRFSD)
end,
{ok, Node} = start_node(Config, Opts),
Self = self(),
@@ -148,7 +148,7 @@ erts_mmap_do(Config, SCO, SCRPM, SCMGC) ->
Total = SCS*1024*1024,
{reserved,Reserved} = lists:keyfind(reserved,1,Segs),
- true = (Reserved >= SCMGC),
+ true = (Reserved >= SCRFSD),
case {SCO,lists:keyfind(os,1,EM)} of
{true, false} -> ok;
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index 02c6de8cb1..fbc229bc53 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -388,8 +388,12 @@ os_env(Config) when is_list(Config) ->
false -> ?line ok;
BadVal -> ?line ?t:fail(BadVal)
end,
- %% os:putenv and os:getenv currently uses a temp buf of size 1024
- %% for storing key+value
+ true = os:putenv(EnvVar1, "mors"),
+ true = os:unsetenv(EnvVar1),
+ false = os:getenv(EnvVar1),
+ true = os:unsetenv(EnvVar1), % unset unset variable
+ %% os:putenv, os:getenv and os:unsetenv currently use a temp
+ %% buffer of size 1024 for storing key+value
?line os_env_long(1010, 1030, "hej hopp").
os_env_long(Min, Max, _Value) when Min > Max ->
@@ -398,7 +402,7 @@ os_env_long(Min, Max, Value) ->
?line EnvVar = lists:duplicate(Min, $X),
?line true = os:putenv(EnvVar, Value),
?line Value = os:getenv(EnvVar),
- ?line true = os:putenv(EnvVar, ""),
+ true = os:unsetenv(EnvVar),
?line os_env_long(Min+1, Max, Value).
otp_7526(doc) ->
diff --git a/erts/emulator/test/hash_SUITE.erl b/erts/emulator/test/hash_SUITE.erl
index 43c9d64af7..738c9c8b16 100644
--- a/erts/emulator/test/hash_SUITE.erl
+++ b/erts/emulator/test/hash_SUITE.erl
@@ -32,7 +32,7 @@
%%
-module(hash_SUITE).
-export([basic_test/0,cmp_test/1,range_test/0,spread_test/1,
- phash2_test/0, otp_5292_test/0, bit_level_binaries/0,
+ phash2_test/0, otp_5292_test/0,
otp_7127_test/0]).
-compile({nowarn_deprecated_function, {erlang,hash,2}}).
@@ -152,7 +152,7 @@ otp_5292(Config) when is_list(Config) ->
%% Test hashing bit-level binaries.
bit_level_binaries(Config) when is_list(Config) ->
- bit_level_binaries().
+ bit_level_binaries_do().
otp_7127(suite) ->
[];
@@ -537,7 +537,7 @@ hash_int(Start, End, F) ->
md5(T) ->
erlang:md5(term_to_binary(T)).
-bit_level_binaries() ->
+bit_level_binaries_do() ->
[3511317,7022633,14044578,28087749,56173436,112344123,90467083|_] =
bit_level_all_different(fun erlang:hash/2),
[3511317,7022633,14044578,28087749,56173436,112344123,90467083|_] =
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index c9908caf20..f098e56a2e 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -103,14 +103,16 @@ static char *plusM_other_switches[] = {
"ea",
"ummc",
"uycs",
+ "usac",
"im",
"is",
"it",
+ "lpm",
"Mamcbf",
"Mrmcbf",
"Mmcs",
"Mscs",
- "Mscmgc",
+ "Mscrfsd",
"Msco",
"Mscrpm",
"Ye",
diff --git a/erts/etc/unix/cerl.src b/erts/etc/unix/cerl.src
index 41baa323ed..be8343e87e 100644
--- a/erts/etc/unix/cerl.src
+++ b/erts/etc/unix/cerl.src
@@ -33,6 +33,7 @@
# You have to start beam in gdb using "run".
# -rgdb Run the debug compiled emulator in gdb.
# You have to start beam in gdb using "run".
+# -dump Dump the bt of all threads in a core.
# -break F Run the debug compiled emulator in emacs and gdb and set break.
# The session is started, i.e. "run" is already don for you.
# -xxgdb FIXME currently disabled
@@ -178,6 +179,12 @@ while [ $# -gt 0 ]; do
cargs="$cargs -frmptr"
TYPE=.frmptr
;;
+ "-dump")
+ shift
+ GDB=dump
+ core="$1"
+ shift
+ ;;
"-gdb")
shift
GDB=egdb
@@ -331,7 +338,7 @@ elif [ "x$GDB" = "xgdb" ]; then
echo "source $ROOTDIR/erts/etc/unix/etp-commands" > $cmdfile
# Fire up gdb in emacs...
exec gdb $GDBBP -x $cmdfile $gdbcmd
-else
+elif [ "x$GDB" = "xegdb" ]; then
if [ "x$EMACS" = "x" ]; then
EMACS=emacs
fi
@@ -339,7 +346,7 @@ else
case "x$core" in
x)
# Get emu args to use from erlexec...
- beam_args=`$EXEC -emu_args_exit ${1+"$@"}`
+ beam_args=`$EXEC -emu_args_exit ${1+"$@"} | tr '\n' ' '`
gdbcmd="(insert-string \"set args $beam_args\") \
(comint-send-input)"
;;
@@ -372,4 +379,23 @@ else
(comint-send-input)"
# Fire up gdb in emacs...
exec $EMACS --eval "(progn (gdb \"gdb $GDBARGS$EMU_NAME\") $gdbcmd)"
+elif [ "x$GDB" = "xdump" ]; then
+ cmdfile="/tmp/.cerlgdb.$$"
+ case "x$core" in
+ x/*)
+ gdbcmd="$EMU_NAME ${core}"
+ ;;
+ *)
+ dir=`pwd`
+ gdbcmd="$EMU_NAME ${dir}/${core}"
+ ;;
+ esac
+ echo "set width 0
+set height 0
+set verbose off
+
+source $ROOTDIR/erts/etc/unix/etp-commands
+thread apply all bt
+" > $cmdfile
+ exec gdb --batch --command=$cmdfile $gdbcmd
fi
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index f51ccfe8ce..ece0e6d5e8 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/src/Makefile b/erts/preloaded/src/Makefile
index c1580b1495..4ea2d41075 100644
--- a/erts/preloaded/src/Makefile
+++ b/erts/preloaded/src/Makefile
@@ -68,7 +68,7 @@ KERNEL_SRC=$(ERL_TOP)/lib/kernel/src
KERNEL_INCLUDE=$(ERL_TOP)/lib/kernel/include
STDLIB_INCLUDE=$(ERL_TOP)/lib/stdlib/include
-ERL_COMPILE_FLAGS += +warn_obsolete_guard -I$(KERNEL_SRC) -I$(KERNEL_INCLUDE)
+ERL_COMPILE_FLAGS += +warn_obsolete_guard +debug_info -I$(KERNEL_SRC) -I$(KERNEL_INCLUDE)
debug opt: $(TARGET_FILES)
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index e8ddfc4a57..fc43d1d4fa 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -1439,7 +1439,12 @@ normalize(Name, Acc) ->
[Atom | Rest] when is_atom(Atom) ->
normalize(atom_to_list(Atom) ++ Rest, Acc);
[$\\ | Chars] ->
- normalize(Chars, [$/ | Acc]);
+ case erlang:system_info(os_type) of
+ {win32, _} ->
+ normalize(Chars, [$/ | Acc]);
+ _ ->
+ normalize(Chars, [$\\ | Acc])
+ end;
[Char | Chars] ->
normalize(Chars, [Char | Acc]);
[] ->
diff --git a/erts/test/z_SUITE.erl b/erts/test/z_SUITE.erl
index ccf22a9b6b..da72b18f05 100644
--- a/erts/test/z_SUITE.erl
+++ b/erts/test/z_SUITE.erl
@@ -231,6 +231,20 @@ mod_time_list(F) ->
str_strip(S) ->
string:strip(string:strip(string:strip(S), both, $\n), both, $\r).
+dump_core(#core_search_conf{ cerl = false }, _) ->
+ ok;
+dump_core(_, {ignore, _Core}) ->
+ ok;
+dump_core(#core_search_conf{ cerl = Cerl }, Core) ->
+ Dump = case test_server:is_debug() of
+ true ->
+ os:cmd(Cerl ++ " -debug -dump " ++ Core);
+ _ ->
+ os:cmd(Cerl ++ " -dump " ++ Core)
+ end,
+ ct:log("~s~n~n~s",[Core,Dump]).
+
+
format_core(Conf, {ignore, Core}) ->
format_core(Conf, Core, "[ignored] ");
format_core(Conf, Core) ->
@@ -254,11 +268,16 @@ core_file_search(#core_search_conf{search_dir = Base,
extra_search_dir = XBase,
cerl = Cerl,
run_by_ts = RunByTS} = Conf) ->
- case Cerl of
- false -> ok;
- _ -> catch io:format("A cerl script that probably can be used for "
- "inspection of emulator cores:~n ~s~n",
- [Cerl])
+ case {Cerl,test_server:is_debug()} of
+ {false,_} -> ok;
+ {_,true} ->
+ catch io:format("A cerl script that probably can be used for "
+ "inspection of emulator cores:~n ~s -debug~n",
+ [Cerl]);
+ _ ->
+ catch io:format("A cerl script that probably can be used for "
+ "inspection of emulator cores:~n ~s~n",
+ [Cerl])
end,
io:format("Searching for core-files in: ~s~s~n",
[case XBase of
@@ -329,6 +348,8 @@ core_file_search(#core_search_conf{search_dir = Base,
["Ignored core-files found:",
lists:reverse(ICores)]
end]),
+
+ lists:foreach(fun(C) -> dump_core(Conf,C) end, Cores),
case {RunByTS, ICores, FCores} of
{true, [], []} -> ok;
{true, _, []} -> {comment, Res};