From a86bb2d592486144414fbbebca85ab36ffca2446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 1 Apr 2013 18:44:47 +0200 Subject: Don't lookup the node unless required in gen:call/{3,4} Move some operations that aren't required for the happy path. The operations were small, so they shouldn't show a big difference in benchmarks except for systems with many active gen processes. --- lib/stdlib/src/gen.erl | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'lib/stdlib') diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl index 42555aedd7..d9db17170b 100644 --- a/lib/stdlib/src/gen.erl +++ b/lib/stdlib/src/gen.erl @@ -17,6 +17,7 @@ %% %CopyrightEnd% %% -module(gen). +-compile({inline,[get_node/1]}). %%%----------------------------------------------------------------- %%% This module implements the really generic stuff of the generic @@ -194,16 +195,6 @@ call({_Name, Node}=Process, Label, Request, Timeout) end. do_call(Process, Label, Request, Timeout) -> - %% We trust the arguments to be correct, i.e - %% Process is either a local or remote pid, - %% or a {Name, Node} tuple (of atoms) and in this - %% case this node (node()) _is_ distributed and Node =/= node(). - Node = case Process of - {_S, N} when is_atom(N) -> - N; - _ when is_pid(Process) -> - node(Process) - end, try erlang:monitor(process, Process) of Mref -> %% If the monitor/2 call failed to set up a connection to a @@ -222,6 +213,7 @@ do_call(Process, Label, Request, Timeout) -> erlang:demonitor(Mref, [flush]), {ok, Reply}; {'DOWN', Mref, _, _, noconnection} -> + Node = get_node(Process), exit({nodedown, Node}); {'DOWN', Mref, _, _, Reason} -> exit(Reason) @@ -241,6 +233,7 @@ do_call(Process, Label, Request, Timeout) -> %% Do the best possible with monitor_node/2. %% This code may hang indefinitely if the Process %% does not exist. It is only used for featureweak remote nodes. + Node = get_node(Process), monitor_node(Node, true), receive {nodedown, Node} -> @@ -253,6 +246,18 @@ do_call(Process, Label, Request, Timeout) -> end end. +get_node(Process) -> + %% We trust the arguments to be correct, i.e + %% Process is either a local or remote pid, + %% or a {Name, Node} tuple (of atoms) and in this + %% case this node (node()) _is_ distributed and Node =/= node(). + case Process of + {_S, N} when is_atom(N) -> + N; + _ when is_pid(Process) -> + node(Process) + end. + wait_resp(Node, Tag, Timeout) -> receive {Tag, Reply} -> -- cgit v1.2.3 From 3bdde42c1f945a1485b36b3fe33839f93199339e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Mon, 1 Apr 2013 18:49:52 +0200 Subject: Use erlang:demonitor's flush option on timeout It is equivalent to the few lines removed, except more efficient. --- lib/stdlib/src/gen.erl | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'lib/stdlib') diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl index d9db17170b..5df5530ba1 100644 --- a/lib/stdlib/src/gen.erl +++ b/lib/stdlib/src/gen.erl @@ -218,11 +218,7 @@ do_call(Process, Label, Request, Timeout) -> {'DOWN', Mref, _, _, Reason} -> exit(Reason) after Timeout -> - erlang:demonitor(Mref), - receive - {'DOWN', Mref, _, _, _} -> true - after 0 -> true - end, + erlang:demonitor(Mref, [flush]), exit(timeout) end catch -- cgit v1.2.3