1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2019-2021. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20-module(literal_area_collector_test).
21
22-export([check_idle/0, check_idle/1]).
23
24check_idle() ->
25    check_idle(5000).
26
27check_idle(Timeout) when is_integer(Timeout) > 0 ->
28    ScaledTimeout = Timeout*test_server:timetrap_scale_factor(),
29    Pid = find_literal_area_collector(),
30    Start = erlang:monotonic_time(millisecond),
31    try
32        wait_for_idle_literal_collector(Pid, Start, ScaledTimeout, -1, 0)
33    catch
34        throw:done ->
35            ok
36    end.
37
38wait_for_idle_literal_collector(Pid, Start, Timeout, NWaiting, WRedsStart) ->
39    {W, R} = case process_info(Pid, [status, reductions]) of
40                 [{status, waiting}, {reductions, Reds}] ->
41                     %% Assume that reds aren't bumped more than
42                     %% 2 in order to service this process info
43                     %% request...
44                     case {NWaiting > 100, Reds - WRedsStart =< 2*NWaiting} of
45                         {true, true} ->
46                             throw(done);
47                         {false, true} ->
48                             {NWaiting+1, WRedsStart};
49                         _ ->
50                             {0, Reds}
51                     end;
52                 _ ->
53                     {-1, 0}
54             end,
55    Now = erlang:monotonic_time(millisecond),
56    if Now - Start > Timeout ->
57            error({busy_literal_area_collecor_timout, Timeout});
58       true ->
59            ok
60    end,
61    receive after 1 -> ok end,
62    wait_for_idle_literal_collector(Pid, Start, Timeout, W, R).
63
64find_literal_area_collector() ->
65    case get('__literal_area_collector__') of
66        Pid when is_pid(Pid) ->
67            Pid;
68        _ ->
69            find_save_literal_area_collector(processes()),
70            find_literal_area_collector()
71    end.
72
73find_save_literal_area_collector([P|Ps]) ->
74    case process_info(P, initial_call) of
75        {initial_call,{erts_literal_area_collector,start,0}} ->
76            put('__literal_area_collector__', P);
77        _ ->
78            find_save_literal_area_collector(Ps)
79    end.
80