diff options
-rw-r--r-- | ioq.c | 29 |
1 files changed, 26 insertions, 3 deletions
@@ -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)); } |