diff options
author | Rickard Green <[email protected]> | 2013-10-30 17:29:18 +0100 |
---|---|---|
committer | Rickard Green <[email protected]> | 2013-11-18 20:12:36 +0100 |
commit | c6cb0293ba33e1671f8ed670d5add082e5ee674a (patch) | |
tree | a00e3500442c0a175fbc027b61b437b103b8b8fb /erts/emulator/test/process_SUITE.erl | |
parent | 406fd5c773b5ae73dbfc6b305a502ffbe236a9bb (diff) | |
download | otp-c6cb0293ba33e1671f8ed670d5add082e5ee674a.tar.gz otp-c6cb0293ba33e1671f8ed670d5add082e5ee674a.tar.bz2 otp-c6cb0293ba33e1671f8ed670d5add082e5ee674a.zip |
Functionality for disabling garbage collection
Being able to disable garbage collection over context
switches vastly simplifies implementation of yielding
native code that builds large or complex data structures
on the heap. This since the heap can be left in an
inconsistent state over the context switch.
Diffstat (limited to 'erts/emulator/test/process_SUITE.erl')
-rw-r--r-- | erts/emulator/test/process_SUITE.erl | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl index e66c6f09b6..bf31655066 100644 --- a/erts/emulator/test/process_SUITE.erl +++ b/erts/emulator/test/process_SUITE.erl @@ -55,7 +55,9 @@ no_priority_inversion/1, no_priority_inversion2/1, system_task_blast/1, - system_task_on_suspended/1]). + system_task_on_suspended/1, + gc_request_when_gc_disabled/1, + gc_request_blast_when_gc_disabled/1]). -export([prio_server/2, prio_client/2]). -export([init_per_testcase/2, end_per_testcase/2]). @@ -95,7 +97,8 @@ groups() -> otp_7738_resume]}, {system_task, [], [no_priority_inversion, no_priority_inversion2, - system_task_blast, system_task_on_suspended]}]. + system_task_blast, system_task_on_suspended, + gc_request_when_gc_disabled, gc_request_blast_when_gc_disabled]}]. init_per_suite(Config) -> A0 = case application:start(sasl) of @@ -2361,15 +2364,69 @@ system_task_on_suspended(Config) when is_list(Config) -> ok end. -gc_req(_Pid, 0) -> - []; -gc_req(Pid, N) -> - R0 = erts_internal:request_system_task(Pid, low, garbage_collect), - R1 = erts_internal:request_system_task(Pid, normal, garbage_collect), - R2 = erts_internal:request_system_task(Pid, high, garbage_collect), - R3 = erts_internal:request_system_task(Pid, max, garbage_collect), - [R0, R1, R2, R3 | gc_req(Pid, N-1)]. - +gc_request_when_gc_disabled(Config) when is_list(Config) -> + Master = self(), + AIS = erts_debug:set_internal_state(available_internal_state, true), + {P, M} = spawn_opt(fun () -> + true = erts_debug:set_internal_state(gc_state, + false), + Master ! {self(), gc_state, false}, + receive after 1000 -> ok end, + Master ! {self(), gc_state, true}, + false = erts_debug:set_internal_state(gc_state, + true), + receive after 100 -> ok end + end, [monitor, link]), + receive {P, gc_state, false} -> ok end, + ReqId = make_ref(), + async = garbage_collect(P, [{async, ReqId}]), + receive + {garbage_collect, ReqId, Result} -> + ?t:fail({unexpected_gc, Result}); + {P, gc_state, true} -> + ok + end, + receive {garbage_collect, ReqId, true} -> ok end, + erts_debug:set_internal_state(available_internal_state, AIS), + receive {'DOWN', M, process, P, _Reason} -> ok end, + ok. + +gc_request_blast_when_gc_disabled(Config) when is_list(Config) -> + Master = self(), + AIS = erts_debug:set_internal_state(available_internal_state, true), + {P, M} = spawn_opt(fun () -> + true = erts_debug:set_internal_state(gc_state, + false), + Master ! {self(), gc_state, false}, + receive after 1000 -> ok end, + false = erts_debug:set_internal_state(gc_state, + true), + receive after 100 -> ok end + end, [monitor, link]), + receive {P, gc_state, false} -> ok end, + PMs = lists:map(fun (N) -> + Prio = case N rem 4 of + 0 -> max; + 1 -> high; + 2 -> normal; + 3 -> low + end, + spawn_opt(fun () -> + erlang:garbage_collect(P) + end, [monitor, link, {priority, Prio}]) + end, lists:seq(1, 10000)), + lists:foreach(fun ({Proc, Mon}) -> + receive + {'DOWN', Mon, process, Proc, normal} -> + ok + end + end, + PMs), + erts_debug:set_internal_state(available_internal_state, AIS), + receive {'DOWN', M, process, P, _Reason} -> ok end, + ok. + + %% Internal functions wait_until(Fun) -> |