about summary refs log tree commit homepage
diff options
context:
space:
mode:
-rw-r--r--ioq.c29
1 files 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));
 }