diff options
author | Björn Gustavsson <[email protected]> | 2011-11-10 10:42:42 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2011-11-17 09:27:10 +0100 |
commit | bee543c25be70380be225021864a079c01b56255 (patch) | |
tree | 0a2fa3189ceff0215890eba5f4f18e031784d293 | |
parent | 0b27c0ce578db5266dbaaa50a6d116836a03aa94 (diff) | |
download | otp-bee543c25be70380be225021864a079c01b56255.tar.gz otp-bee543c25be70380be225021864a079c01b56255.tar.bz2 otp-bee543c25be70380be225021864a079c01b56255.zip |
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
-rw-r--r-- | erts/emulator/beam/beam_bif_load.c | 26 |
1 files changed, 20 insertions, 6 deletions
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); } |