summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/erl_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/erl_init.c')
-rw-r--r--erts/emulator/beam/erl_init.c84
1 files changed, 70 insertions, 14 deletions
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 2f2e48d3c0..7df1e6a841 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -275,7 +275,7 @@ static ERTS_INLINE void
set_default_time_adj(int *time_correction_p, ErtsTimeWarpMode *time_warp_mode_p)
{
*time_correction_p = 1;
- *time_warp_mode_p = ERTS_NO_TIME_WARP_MODE;
+ *time_warp_mode_p = ERTS_MULTI_TIME_WARP_MODE;
if (!erts_check_time_adj_support(*time_correction_p,
*time_warp_mode_p)) {
*time_correction_p = 0;
@@ -388,6 +388,7 @@ erl_init(int ncpu,
erl_nif_init();
erts_msacc_init();
beamfile_init();
+ erts_late_init_external();
}
static Eterm
@@ -631,6 +632,7 @@ void erts_usage(void)
H_DEFAULT_MAX_SIZE);
erts_fprintf(stderr, "-hmaxk bool enable or disable kill at max heap size (default true)\n");
erts_fprintf(stderr, "-hmaxel bool enable or disable error_logger report at max heap size (default true)\n");
+ erts_fprintf(stderr, "-hmaxib bool enable or disable including off-heap binaries into max heap size (default false)\n");
erts_fprintf(stderr, "-hpds size set initial process dictionary size (default %d)\n",
erts_pd_initial_size);
erts_fprintf(stderr, "-hmqd val set default message queue data flag for processes;\n");
@@ -652,6 +654,7 @@ void erts_usage(void)
#ifdef BEAMASM
erts_fprintf(stderr, "-JDdump bool enable or disable dumping of generated assembly code for each module loaded\n");
erts_fprintf(stderr, "-JPperf true|false|dump|map|fp|no_fp enable or disable support for perf on Linux\n");
+ erts_fprintf(stderr, "-JMsingle bool enable the use of single-mapped RWX memory for JIT:ed code\n");
erts_fprintf(stderr, "\n");
#endif
@@ -1579,6 +1582,8 @@ erl_start(int argc, char **argv)
* h|max - max_heap_size
* h|maxk - max_heap_kill
* h|maxel - max_heap_error_logger
+ * h|maxib - map_heap_include_shared_binaries
+ *
*
*/
if (has_prefix("mbs", sub_param)) {
@@ -1641,6 +1646,17 @@ erl_start(int argc, char **argv)
erts_usage();
}
VERBOSE(DEBUG_SYSTEM, ("using max heap log %d\n", H_MAX_FLAGS));
+ } else if (has_prefix("maxib", sub_param)) {
+ arg = get_arg(sub_param+5, argv[i+1], &i);
+ if (sys_strcmp(arg,"true") == 0) {
+ H_MAX_FLAGS |= MAX_HEAP_SIZE_INCLUDE_OH_BINS;
+ } else if (sys_strcmp(arg,"false") == 0) {
+ H_MAX_FLAGS &= ~MAX_HEAP_SIZE_INCLUDE_OH_BINS;
+ } else {
+ erts_fprintf(stderr, "bad max heap include bins %s\n", arg);
+ erts_usage();
+ }
+ VERBOSE(DEBUG_SYSTEM, ("using max heap log %d\n", H_MAX_FLAGS));
} else if (has_prefix("max", sub_param)) {
Sint hMaxSize;
char *rest;
@@ -1753,6 +1769,23 @@ erl_start(int argc, char **argv)
#endif
}
break;
+ case 'M':
+ sub_param++;
+ if (has_prefix("single", sub_param)) {
+ arg = get_arg(sub_param+6, argv[i + 1], &i);
+ if (sys_strcmp(arg, "true") == 0) {
+ erts_jit_single_map = 1;
+ } else if (sys_strcmp(arg, "false") == 0) {
+ erts_jit_single_map = 0;
+ } else {
+ erts_fprintf(stderr, "bad +JMsingle support flag %s\n", arg);
+ erts_usage();
+ }
+ } else {
+ erts_fprintf(stderr, "bad +JM sub-option %s\n", arg);
+ erts_usage();
+ }
+ break;
default:
erts_fprintf(stderr, "invalid JIT option %s\n", argv[i]);
break;
@@ -2561,7 +2594,7 @@ __decl_noreturn void erts_thr_fatal_error(int err, const char *what)
static void
-system_cleanup(int flush_async)
+system_cleanup(int flush)
{
/*
* Make sure only one thread exits the runtime system.
@@ -2591,24 +2624,43 @@ system_cleanup(int flush_async)
* (in threaded non smp case).
*/
- if (!flush_async
- || !erts_initialized
- )
+ if (!flush || !erts_initialized)
return;
+ /*
+ * We only flush as a result of calling erts_halt() (which in turn
+ * is called from the erlang:halt() BIF when flushing is enabled);
+ * otherwise, flushing wont work properly. If erts_halt() has
+ * been called, 'erts_halt_code' won't equal INT_MIN...
+ */
+ ASSERT(erts_halt_code != INT_MIN);
+
+ /*
+ * Nif on-halt handlers may have been added after we initiated
+ * a halt. If so, make sure that these late added handlers are
+ * executed as well..
+ */
+ erts_nif_execute_on_halt();
+
#ifdef ERTS_ENABLE_LOCK_CHECK
erts_lc_check_exact(NULL, 0);
#endif
erts_exit_flush_async();
+
+ /*
+ * Wait for all NIF calls with delayed halt functionality
+ * enabled to complete before we continue...
+ */
+ erts_nif_wait_calls();
}
static int erts_exit_code;
static __decl_noreturn void __noreturn
-erts_exit_vv(int n, int flush_async, const char *fmt, va_list args1, va_list args2)
+erts_exit_vv(int n, int flush, const char *fmt, va_list args1, va_list args2)
{
- system_cleanup(flush_async);
+ system_cleanup(flush);
if (fmt != NULL && *fmt != '\0')
erl_error(fmt, args2); /* Print error message. */
@@ -2621,25 +2673,25 @@ erts_exit_vv(int n, int flush_async, const char *fmt, va_list args1, va_list arg
erl_crash_dump_v((char*) NULL, 0, fmt, args1);
}
- erts_exit_epilogue();
+ erts_exit_epilogue(flush);
}
-__decl_noreturn void __noreturn erts_exit_epilogue(void)
+__decl_noreturn void __noreturn erts_exit_epilogue(int flush)
{
int n = erts_exit_code;
sys_tty_reset(n);
if (n == ERTS_INTR_EXIT)
- exit(0);
+ (void) (flush ? exit(0) : _exit(0));
else if (n == ERTS_DUMP_EXIT)
ERTS_EXIT_AFTER_DUMP(1);
else if (n == ERTS_ERROR_EXIT || n == ERTS_ABORT_EXIT)
abort();
- exit(n);
+ (void) (flush ? exit(n) : _exit(n));
}
-/* Exit without flushing async threads */
+/* Exit without flushing */
__decl_noreturn void __noreturn erts_exit(int n, const char *fmt, ...)
{
va_list args1, args2;
@@ -2650,8 +2702,12 @@ __decl_noreturn void __noreturn erts_exit(int n, const char *fmt, ...)
va_end(args1);
}
-/* Exit after flushing async threads */
-__decl_noreturn void __noreturn erts_flush_async_exit(int n, char *fmt, ...)
+/*
+ * Exit after flushing. This is a continuation of erts_halt() and wont
+ * work properly if called by its own without proper initialization
+ * as made in erts_halt().
+ */
+__decl_noreturn void __noreturn erts_flush_exit(int n, char *fmt, ...)
{
va_list args1, args2;
va_start(args1, fmt);