diff options
author | Mikael Pettersson <[email protected]> | 2010-01-27 11:32:05 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2010-01-27 16:35:07 +0100 |
commit | 38cec58103fb69b995e29cdd186061b8dc233d9d (patch) | |
tree | a9bd657b0209bb37fe32c4c7da03b1e717722e16 /lib | |
parent | fabf2e7b08fedd7e8e8cfcebd0cca059eee92658 (diff) | |
download | otp-38cec58103fb69b995e29cdd186061b8dc233d9d.tar.gz otp-38cec58103fb69b995e29cdd186061b8dc233d9d.tar.bz2 otp-38cec58103fb69b995e29cdd186061b8dc233d9d.zip |
fix hipe loader SMP non-atomicity error
Loading native code is a multi-step operation that needs to be
atomic, but the HiPE loader failed to ensure that.
This caused corruption of runtime system structure in some cases.
Fix by blocking multi_scheduling around main loader entry points.
Signed-off-by: Mikael Pettersson <[email protected]>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/kernel/src/hipe_unified_loader.erl | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl index 7e26d57ced..42eab67478 100644 --- a/lib/kernel/src/hipe_unified_loader.erl +++ b/lib/kernel/src/hipe_unified_loader.erl @@ -96,6 +96,14 @@ load_hipe_modules() -> %% code:load_file/1) and the atom `no_native' on failure. load_native_code(Mod, Bin) when is_atom(Mod), is_binary(Bin) -> + erlang:system_flag(multi_scheduling, block), + try + load_native_code_nosmp(Mod, Bin) + after + erlang:system_flag(multi_scheduling, unblock) + end. + +load_native_code_nosmp(Mod, Bin) -> Architecture = erlang:system_info(hipe_architecture), try chunk_name(Architecture) of ChunkTag -> @@ -120,6 +128,14 @@ load_native_code(Mod, Bin) when is_atom(Mod), is_binary(Bin) -> -spec post_beam_load(atom()) -> 'ok'. post_beam_load(Mod) when is_atom(Mod) -> + erlang:system_flag(multi_scheduling, block), + try + post_beam_load_nosmp(Mod) + after + erlang:system_flag(multi_scheduling, unblock) + end. + +post_beam_load_nosmp(Mod) -> Architecture = erlang:system_info(hipe_architecture), try chunk_name(Architecture) of _ChunkTag -> patch_to_emu(Mod) catch _:_ -> ok @@ -141,6 +157,14 @@ version_check(Version, Mod) when is_atom(Mod) -> -spec load_module(Mod, binary(), _) -> 'bad_crc' | {'module',Mod} when is_subtype(Mod,atom()). load_module(Mod, Bin, Beam) -> + erlang:system_flag(multi_scheduling, block), + try + load_module_nosmp(Mod, Bin, Beam) + after + erlang:system_flag(multi_scheduling, unblock) + end. + +load_module_nosmp(Mod, Bin, Beam) -> load_module(Mod, Bin, Beam, []). load_module(Mod, Bin, Beam, OldReferencesToPatch) -> @@ -154,6 +178,14 @@ load_module(Mod, Bin, Beam, OldReferencesToPatch) -> -spec load(Mod, binary()) -> 'bad_crc' | {'module',Mod} when is_subtype(Mod,atom()). load(Mod, Bin) -> + erlang:system_flag(multi_scheduling, block), + try + load_nosmp(Mod, Bin) + after + erlang:system_flag(multi_scheduling, unblock) + end. + +load_nosmp(Mod, Bin) -> ?debug_msg("********* Loading funs in module ~w *********\n",[Mod]), %% Loading just some functions in a module; patch closures separately. put(hipe_patch_closures, true), |