Every enqueued request now includes a hint as to how much work is pending in

the lower C-code.  We use that to scale the reduction count penalty so that we
can (hopefully) signal to the Erlang scheduler enough information for it to
properly throttle work.  'eagain' should only happen when queues are full, we
have no choice but to keep this calling proc busy in a recursive loop trying
the request over and over if we're going to preserve request ordering.
This commit is contained in:
Gregory Burd 2013-08-21 12:15:34 -04:00
parent e67da86a9b
commit 1bf66ae960

View file

@ -22,20 +22,28 @@
%% -------------------------------------------------------------------
-define(ASYNC_NIF_CALL(Fun, Args),
R = erlang:make_ref(),
case erlang:apply(Fun, [R|Args]) of
{ok, {enqueued, PercentFull}} ->
erlang:bump_reductions(erlang:trunc(2000 * PercentFull)),
receive
{R, {error, shutdown}=Error} ->
%% Work unit was queued, but not executed.
Error;
{R, {error, _Reason}=Error} ->
%% Work unit returned an error.
Error;
{R, Reply} ->
Reply
end;
Other ->
Other
end).
F = fun(F, A) ->
R = erlang:make_ref(),
case erlang:apply(F, [R|A]) of
{ok, {enqueued, PctBusy}} ->
case PctBusy of
0.0 -> ok;
_ -> erlang:bump_reductions(erlang:trunc(2000 * PctBusy))
end,
receive
{R, {error, shutdown}=Error} ->
%% Work unit was queued, but not executed.
Error;
{R, {error, _Reason}=Error} ->
%% Work unit returned an error.
Error;
{R, Reply} ->
Reply
end;
{error, eagain} ->
F(F, A);
Other ->
Other
end
end,
F(Fun, Args)).