diff options
Diffstat (limited to 'erts/emulator/test/gc_SUITE.erl')
-rw-r--r-- | erts/emulator/test/gc_SUITE.erl | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl new file mode 100644 index 0000000000..066aa215b2 --- /dev/null +++ b/erts/emulator/test/gc_SUITE.erl @@ -0,0 +1,181 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +%% Test the garbage collector (or Memory Recycler) + +-module(gc_SUITE). + +-include("test_server.hrl"). +-export([all/1]). + +-define(default_timeout, ?t:minutes(10)). + +-export([grow_heap/1, grow_stack/1, grow_stack_heap/1]). + +all(suite) -> + [grow_heap,grow_stack, grow_stack_heap]. + +grow_heap(doc) -> ["Produce a growing list of elements, ", + "for X calls, then drop one item per call", + "until the list is empty."]; +grow_heap(Config) when is_list(Config) -> + ?line Dog=test_server:timetrap(test_server:minutes(40)), + ?line ok=grow_heap1(256), + case os:type() of + vxworks -> + stop_here; + _ -> + ?line ok=grow_heap1(512), + ?line ok=grow_heap1(1024), + ?line ok=grow_heap1(2048) + end, + ?line test_server:timetrap_cancel(Dog), + ok. + +grow_heap1(Len) -> + io:format("~ngrow_heap with ~p items.",[Len]), + show_heap("before:"), + grow_heap1([], Len, 0, up), + show_heap("after:"). + +grow_heap1(List, MaxLen, MaxLen, up) -> + show_heap("top:"), + grow_heap1(List, MaxLen, MaxLen-1, down); +grow_heap1(List, MaxLen, CurLen, up) -> + NewList=[make_arbit()|List], + grow_heap1(NewList, MaxLen, CurLen+1, up); +grow_heap1([], _MaxLen, _, down) -> + ok; +grow_heap1([_|List], MaxLen, CurLen, down) -> + ?line {_,_,C}=erlang:now(), + ?line Num=C rem (length(List))+1, + ?line Elem=lists:nth(Num, List), + ?line NewList=lists:delete(Elem, List), + grow_heap1(NewList, MaxLen, CurLen-1, down). + + + +grow_stack(doc) -> ["Increase and decrease stack size, and ", + "drop off some garbage from time to time."]; +grow_stack(Config) when is_list(Config) -> + ?line Dog=test_server:timetrap(test_server:minutes(80)), + show_heap("before:"), + case os:type() of + vxworks -> + ?line grow_stack1(25, 0); + _ -> + ?line grow_stack1(200, 0) + end, + show_heap("after:"), + ?line test_server:timetrap_cancel(Dog), + ok. + +grow_stack1(0, _) -> + ok; +grow_stack1(Recs, 0) -> +% show_heap("running:"), + grow_stack1(Recs-1, Recs), + grow_stack1(0,0); +grow_stack1(Recs, CurRecs) -> + grow_stack1(Recs, CurRecs-1), + make_arbit(), + grow_stack1(1,0), + ok. + + +%% Let's see how BEAM handles this one... +grow_stack_heap(doc) -> ["While growing the heap, bounces the size ", + "of the stack, and while reducing the heap", + "bounces the stack usage."]; +grow_stack_heap(Config) when is_list(Config) -> + case os:type() of + vxworks -> + {comment, "Takes too long to run on VxWorks/cpu32"}; + _ -> + ?line Dog=test_server:timetrap(test_server:minutes(40)), + ?line grow_stack_heap1(16), + ?line grow_stack_heap1(32), + ?line test_server:timetrap_cancel(Dog), + ok + end. + +grow_stack_heap1(MaxLen) -> + io:format("~ngrow_stack_heap with ~p items.",[MaxLen]), + show_heap("before:"), + grow_stack_heap1([], MaxLen, 0, up), + show_heap("after:"). + +grow_stack_heap1(List, MaxLen, MaxLen, up) -> + show_heap("top:"), + grow_stack_heap1(List, MaxLen, MaxLen-1, down); +grow_stack_heap1(List, MaxLen, CurLen, up) -> + grow_stack1(CurLen*2,0), + grow_stack_heap1([make_arbit()|List], MaxLen, CurLen+1, up), + ok; + +grow_stack_heap1([], _MaxLen, _, down) -> ok; +grow_stack_heap1([_|List], MaxLen, CurLen, down) -> + grow_stack1(CurLen*2,0), + ?line {_,_,C}=erlang:now(), + ?line Num=C rem (length(List))+1, + ?line Elem=lists:nth(Num, List), + ?line NewList=lists:delete(Elem, List), + grow_stack_heap1(NewList, MaxLen, CurLen-1, down), + ok. + + +%% Create an arbitrary element/term. +make_arbit() -> + {AA,BB,CC}=erlang:now(), + A=AA+1, B=BB+1, C=CC+1, + New = + case C rem 9 of + 0 -> make_string((B div C) +5); + 1 -> C; + 2 -> make_ref(); + 3 -> self(); + 4 -> list_to_binary(make_string((C div B) + 12)); + 5 -> (C*B)/(A+1); + 6 -> list_to_tuple(make_string((B div C) +5)); + 7 -> list_to_atom(make_string(((C div B) rem 254) + 2)); + 8 -> fun(X) -> {X,AA,make_string((B div C)+10)} end + end, + New. + +%% Create an arbitrary string of a certain length. +make_string(Length) -> + Alph="abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"++ + "0123456789", + make_string(Alph, Length, []). + +make_string(_, 0, Acc) -> + Acc; +make_string(Alph, Length, Acc) -> + {_,_,C}=erlang:now(), + Pos=1+(Length*C rem length(Alph)), + make_string(Alph, Length-1, + [lists:nth(Pos,Alph)|Acc]). + +show_heap(String) -> + garbage_collect(self()), + receive after 1 -> ok end, + {heap_size, HSize}=process_info(self(), heap_size), + {stack_size, SSize}=process_info(self(), stack_size), + io:format("Heap/Stack "++String++"~p/~p", [HSize, SSize]). + |