From 1bf66ae960b65a91983070faf25bdfe34f7d8fc1 Mon Sep 17 00:00:00 2001 From: Gregory Burd Date: Wed, 21 Aug 2013 12:15:34 -0400 Subject: [PATCH] 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. --- src/async_nif.hrl | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/async_nif.hrl b/src/async_nif.hrl index c225f16..e410def 100644 --- a/src/async_nif.hrl +++ b/src/async_nif.hrl @@ -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)).