aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/test/gen_server_SUITE.erl
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2010-05-12 04:04:59 +0000
committerErlang/OTP <[email protected]>2010-05-12 04:04:59 +0000
commitdd908223cbf62adfeaefac982c4087cd35bb1805 (patch)
treece35140043845c72d0f1196f0a9a13dcef278286 /lib/stdlib/test/gen_server_SUITE.erl
parent3bcc56eb8f6034d73cbc6d1903785a278feae163 (diff)
parent84f65232d00de87042b11b07db4dad30cc7e1fa4 (diff)
downloadotp-dd908223cbf62adfeaefac982c4087cd35bb1805.tar.gz
otp-dd908223cbf62adfeaefac982c4087cd35bb1805.tar.bz2
otp-dd908223cbf62adfeaefac982c4087cd35bb1805.zip
Merge branch 'bg/opt-receive' into dev
* bg/opt-receive: Test that gen_server:call/2,3 are fast even with a huge message queue erts: Add tests for the receive optimization Update primary bootstrap erts: Implement recv_mark/1 and recv_set/1 for real compiler tests: Cover the error handling code in beam_receive compiler test: Test optimization of receive statements Optimize selective receives in the presence of a large message queue Introduce the new recv_mark/1 and recv_mark/1 instructions Compile tests that communicate with R12 nodes with the r12 option Move p_run/2 to test_lib gen: Inline wait_resp_mon/2 to help the compiler optimize OTP-8623 bg/opt-receive reveive statements that can only read out a newly created reference are now specially optimized so that it will execute in constant time regardless of the number of messages in the receive queue for the process. That optimization will benefit calls to gen_server:call(). (See gen:do_call/4 for an example of a receive statement that will be optimized.)
Diffstat (limited to 'lib/stdlib/test/gen_server_SUITE.erl')
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl55
1 files changed, 48 insertions, 7 deletions
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index 6efdce78a1..0f60c2c4ee 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1996-2010. 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%
%%
-module(gen_server_SUITE).
@@ -30,7 +30,8 @@
call_remote_n1/1, call_remote_n2/1, call_remote_n3/1, spec_init/1,
spec_init_local_registered_parent/1,
spec_init_global_registered_parent/1,
- otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1
+ otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1,
+ call_with_huge_message_queue/1
]).
% spawn export
@@ -51,7 +52,8 @@ all(suite) ->
call_remote_n2, call_remote_n3, spec_init,
spec_init_local_registered_parent,
spec_init_global_registered_parent,
- otp_5854, hibernate, otp_7669, call_format_status].
+ otp_5854, hibernate, otp_7669, call_format_status,
+ call_with_huge_message_queue].
-define(default_timeout, ?t:minutes(1)).
@@ -904,6 +906,45 @@ call_format_status(Config) when is_list(Config) ->
?line [format_status_called | _] = lists:reverse(Data2),
ok.
+%% Test that the time for a huge message queue is not
+%% significantly slower than with an empty message queue.
+call_with_huge_message_queue(Config) when is_list(Config) ->
+ ?line Pid = spawn_link(fun echo_loop/0),
+
+ ?line {Time,ok} = tc(fun() -> calls(10, Pid) end),
+
+ ?line [self() ! {msg,N} || N <- lists:seq(1, 500000)],
+ erlang:garbage_collect(),
+ ?line {NewTime,ok} = tc(fun() -> calls(10, Pid) end),
+ io:format("Time for empty message queue: ~p", [Time]),
+ io:format("Time for huge message queue: ~p", [NewTime]),
+
+ case (NewTime+1) / (Time+1) of
+ Q when Q < 10 ->
+ ok;
+ Q ->
+ io:format("Q = ~p", [Q]),
+ ?line ?t:fail()
+ end,
+ ok.
+
+calls(0, _) -> ok;
+calls(N, Pid) ->
+ {ultimate_answer,42} = call(Pid, {ultimate_answer,42}),
+ calls(N-1, Pid).
+
+call(Pid, Msg) ->
+ gen_server:call(Pid, Msg, infinity).
+
+tc(Fun) ->
+ timer:tc(erlang, apply, [Fun,[]]).
+
+echo_loop() ->
+ receive
+ {'$gen_call',{Pid,Ref},Msg} ->
+ Pid ! {Ref,Msg},
+ echo_loop()
+ end.
%%--------------------------------------------------------------
%% Help functions to spec_init_*