57
57
copy_literal_area_signal_recv /1 ,
58
58
copy_literal_area_signal_exit /1 ,
59
59
copy_literal_area_signal_recv_exit /1 ,
60
+ copy_literal_area_signal_registers /1 ,
60
61
simultaneous_signals_basic /1 ,
61
62
simultaneous_signals_recv /1 ,
62
63
simultaneous_signals_exit /1 ,
63
64
simultaneous_signals_recv_exit /1 ]).
64
65
65
- -export ([spawn_spammers /3 ]).
66
+ -export ([check_literal_conversion / 1 , spawn_spammers /3 ]).
66
67
67
68
init_per_testcase (Func , Config ) when is_atom (Func ), is_list (Config ) ->
68
69
[{testcase , Func }|Config ].
@@ -107,6 +108,7 @@ groups() ->
107
108
copy_literal_area_signal_recv ,
108
109
copy_literal_area_signal_exit ,
109
110
copy_literal_area_signal_recv_exit ,
111
+ copy_literal_area_signal_registers ,
110
112
simultaneous_signals_basic ,
111
113
simultaneous_signals_recv ,
112
114
simultaneous_signals_exit ,
@@ -945,6 +947,48 @@ copy_literal_area_signal_exit(Config) when is_list(Config) ->
945
947
copy_literal_area_signal_recv_exit (Config ) when is_list (Config ) ->
946
948
copy_literal_area_signal_test (true , true ).
947
949
950
+ % % Tests the case where the literal is only present in the process' saved
951
+ % % registers. This is easy to provoke with hibernation, but can also occur
952
+ % % if a process happens to be scheduled out on e.g. a function call with a
953
+ % % literal argument just as it's being purged.
954
+ copy_literal_area_signal_registers (Config ) when is_list (Config ) ->
955
+ persistent_term :put ({? MODULE , ? FUNCTION_NAME }, [make_ref ()]),
956
+ LiteralArgs = persistent_term :get ({? MODULE , ? FUNCTION_NAME }),
957
+ true = is_list (LiteralArgs ),
958
+ 0 = erts_debug :size_shared (LiteralArgs ), % % Should be a literal...
959
+
960
+ Self = self (),
961
+
962
+ {Pid , Monitor } =
963
+ spawn_monitor (fun () ->
964
+ Self ! {sync , LiteralArgs },
965
+ erlang :hibernate (? MODULE ,
966
+ check_literal_conversion ,
967
+ LiteralArgs )
968
+ end ),
969
+
970
+ receive
971
+ {sync , LiteralArgs } ->
972
+ receive after 500 ->
973
+ {current_function ,{erlang ,hibernate ,3 }} =
974
+ process_info (Pid , current_function )
975
+ end
976
+ end ,
977
+
978
+ persistent_term :erase ({? MODULE , ? FUNCTION_NAME }),
979
+ receive after 1 -> ok end ,
980
+
981
+ literal_area_collector_test :check_idle (),
982
+
983
+ false = (0 =:= erts_debug :size_shared (LiteralArgs )),
984
+ Pid ! check_literal_conversion ,
985
+
986
+ receive
987
+ {'DOWN' , Monitor , process , Pid , R } ->
988
+ normal = R ,
989
+ ok
990
+ end .
991
+
948
992
copy_literal_area_signal_test (RecvPair , Exit ) ->
949
993
persistent_term :put ({? MODULE , ? FUNCTION_NAME }, make_ref ()),
950
994
Literal = persistent_term :get ({? MODULE , ? FUNCTION_NAME }),
@@ -958,12 +1002,7 @@ copy_literal_area_signal_test(RecvPair, Exit) ->
958
1002
true ->
959
1003
ok
960
1004
end ,
961
- receive check_literal_conversion -> ok end ,
962
- receive
963
- Literal ->
964
- % % Should not be a literal anymore...
965
- false = (0 == erts_debug :size_shared (Literal ))
966
- end
1005
+ check_literal_conversion (Literal )
967
1006
end ,
968
1007
PMs = lists :map (fun (_ ) ->
969
1008
spawn_opt (ProcF , [link , monitor ])
@@ -1014,6 +1053,15 @@ copy_literal_area_signal_test(RecvPair, Exit) ->
1014
1053
end , PMs ),
1015
1054
ok .
1016
1055
1056
+ % % Exported for optional use with hibernate/3
1057
+ check_literal_conversion (Literal ) ->
1058
+ receive
1059
+ check_literal_conversion ->
1060
+ % % Should not be a literal anymore...
1061
+ false = (0 == erts_debug :size_shared (Literal )),
1062
+ ok
1063
+ end .
1064
+
1017
1065
simultaneous_signals_basic (Config ) when is_list (Config ) ->
1018
1066
simultaneous_signals_test (false , false ).
1019
1067
0 commit comments