From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Vladimir Davydov Subject: [PATCH 05/18] vinyl: wake up fibers waiting for quota one by one Date: Thu, 16 Aug 2018 19:11:59 +0300 Message-Id: <4938e95febbd96d464ebe8f8fdbb4c1785013e1f.1534432819.git.vdavydov.dev@gmail.com> In-Reply-To: References: In-Reply-To: References: To: kostja@tarantool.org Cc: tarantool-patches@freelists.org List-ID: Currently, we wake up all fibers whenever we free some memory. This is inefficient, because it might occur that all available quota gets consumed by a few fibers while the rest will have to go back to sleep. This is also kinda unfair, because waking up all fibers breaks the order in which the fibers were put to sleep. This works now, because we free memory and wake up fibers infrequently (on dump) and there normally shouldn't be any fibers waiting for quota (if there were, the latency would rocket sky high because of absence of any kind of throttling). However, once throttling is introduced, fibers waiting for quota will become the norm. So let's wake up fibers one by one: whenever we free memory we wake up the first fiber in the line, which will wake up the next fiber on success and so forth. --- src/box/vy_quota.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/box/vy_quota.c b/src/box/vy_quota.c index 3ea7c80f..3677e22e 100644 --- a/src/box/vy_quota.c +++ b/src/box/vy_quota.c @@ -159,7 +159,7 @@ vy_quota_set_limit(struct vy_quota *q, size_t limit) q->limit = q->watermark = limit; if (q->used >= limit) q->quota_exceeded_cb(q); - fiber_cond_broadcast(&q->cond); + fiber_cond_signal(&q->cond); } void @@ -176,7 +176,7 @@ vy_quota_dump(struct vy_quota *q, size_t size, double duration) { assert(q->used >= size); q->used -= size; - fiber_cond_broadcast(&q->cond); + fiber_cond_signal(&q->cond); /* Account dump bandwidth. */ if (duration > 0) @@ -204,6 +204,9 @@ vy_quota_try_use(struct vy_quota *q, size_t size, double timeout) q->use_curr += size; if (q->used >= q->watermark) q->quota_exceeded_cb(q); + + /* Wake up the next fiber in the line waiting for quota. */ + fiber_cond_signal(&q->cond); return 0; } @@ -218,7 +221,7 @@ vy_quota_commit_use(struct vy_quota *q, size_t reserved, size_t used) q->use_curr -= excess; else /* was reset by timeout */ q->use_curr = 0; - fiber_cond_broadcast(&q->cond); + fiber_cond_signal(&q->cond); } if (reserved < used) vy_quota_force_use(q, used - reserved); -- 2.11.0