From bee543c25be70380be225021864a079c01b56255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 10 Nov 2011 10:42:42 +0100 Subject: BEAM loader: Don't stop other schedulers until truly needed The erlang:module_load/2 BIF will stop all other schedulers before it starts to process the BEAM file. That is not a problem when starting the Erlang/OTP system, since the start-up is mostly sequential. It is a problem, however, when big BEAM files are loaded in an already running system. After the refactoring in the previous commits, we can now do most of the processing of the BEAM file before we stop the other schedulers, so that we can minimize the time when only one scheduler will be running. Suggested-by: Bob Ippolito --- erts/emulator/beam/beam_bif_load.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'erts/emulator/beam/beam_bif_load.c') diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c index e57becbe9f..efb72cd3e7 100644 --- a/erts/emulator/beam/beam_bif_load.c +++ b/erts/emulator/beam/beam_bif_load.c @@ -54,6 +54,7 @@ load_module_2(BIF_ALIST_2) byte* code; Eterm res; byte* temp_alloc = NULL; + struct LoaderState* stp; if (is_not_atom(BIF_ARG_1)) { error: @@ -63,13 +64,28 @@ load_module_2(BIF_ALIST_2) if ((code = erts_get_aligned_binary_bytes(BIF_ARG_2, &temp_alloc)) == NULL) { goto error; } + hp = HAlloc(BIF_P, 3); + + /* + * Read the BEAM file and prepare the module for loading. + */ + stp = erts_alloc_loader_state(); + sz = binary_size(BIF_ARG_2); + reason = erts_prepare_loading(stp, BIF_P, BIF_P->group_leader, + &BIF_ARG_1, code, sz); + erts_free_aligned_binary_bytes(temp_alloc); + if (reason != NIL) { + res = TUPLE2(hp, am_error, reason); + BIF_RET(res); + } + + /* + * Stop all other processes and finish the loading of the module. + */ erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); erts_smp_thr_progress_block(); - hp = HAlloc(BIF_P, 3); - sz = binary_size(BIF_ARG_2); - reason = erts_load_module(BIF_P, 0, BIF_P->group_leader, - &BIF_ARG_1, code, sz); + reason = erts_finish_loading(stp, BIF_P, 0, &BIF_ARG_1); if (reason != NIL) { res = TUPLE2(hp, am_error, reason); } else { @@ -77,10 +93,8 @@ load_module_2(BIF_ALIST_2) res = TUPLE2(hp, am_module, BIF_ARG_1); } - erts_free_aligned_binary_bytes(temp_alloc); erts_smp_thr_progress_unblock(); erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); - BIF_RET(res); } -- cgit v1.2.3