From 38cec58103fb69b995e29cdd186061b8dc233d9d Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Wed, 27 Jan 2010 11:32:05 +0100 Subject: 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 --- lib/kernel/src/hipe_unified_loader.erl | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) 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), -- cgit v1.2.3