aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2011-11-10 10:42:42 +0100
committerBjörn Gustavsson <[email protected]>2011-11-17 09:27:10 +0100
commitbee543c25be70380be225021864a079c01b56255 (patch)
tree0a2fa3189ceff0215890eba5f4f18e031784d293
parent0b27c0ce578db5266dbaaa50a6d116836a03aa94 (diff)
downloadotp-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.c26
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);
}