diff options
Diffstat (limited to 'erts/emulator/beam/erl_init.c')
-rw-r--r-- | erts/emulator/beam/erl_init.c | 84 |
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); |