From 3a9a1c5cada0630c499fcf42dfb5b38d11694844 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 31 Aug 2013 03:14:40 +0000 Subject: ioq: correctly reenqueue blocked mfds on capacity increase Otherwise, reenqueue-ing only one mfd at-a-time is pointless and prevents cmogstored from utilizing new threads. --- ioq.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/ioq.c b/ioq.c index f7af1ab..154a84e 100644 --- a/ioq.c +++ b/ioq.c @@ -176,14 +176,37 @@ bool mog_ioq_contended(void) */ void mog_ioq_adjust(struct mog_ioq *ioq, unsigned value) { + struct mog_fd *mfd = NULL; + unsigned prev; + assert(value > 0 && "mog_ioq_adjust value must be non-zero"); CHECK(int, 0, pthread_mutex_lock(&ioq->mtx)); + prev = ioq->max; ioq->max = value; - /* capacity reduced, get some threads to yield themselves */ - if (ioq->cur > ioq->max) + if (ioq->cur > ioq->max) { + /* capacity reduced, get some threads to yield themselves */ ioq_set_contended(ioq); - + } else { + unsigned diff = value - prev; + + ioq->cur += diff; + + /* + * wake up all sleepers we made capacity for. + * unlike mog_ioq_next, we do not release ioq->mtx here + * to avoid infinite looping + */ + while (diff--) { + mfd = SIMPLEQ_FIRST(&ioq->ioq_head); + if (!mfd) + break; + + SIMPLEQ_REMOVE_HEAD(&ioq->ioq_head, ioqent); + TRACE(CMOGSTORED_IOQ_RESCHEDULE(mfd->fd)); + mog_activeq_push(ioq->svc->queue, mfd); + } + } CHECK(int, 0, pthread_mutex_unlock(&ioq->mtx)); } -- cgit v1.2.3-24-ge0c7