If the child wake up someone, process them.

It would the child complete its works if woken coroutine release the locks
that the child needs.

It may help for the cache, if the child wake up some someone, they are
probably accessing the same data.

Signed-off-by: Lai Jiangshan <la...@cn.fujitsu.com>
---
 qemu-coroutine.c |   29 +++++++++++++++++++++++------
 1 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/qemu-coroutine.c b/qemu-coroutine.c
index c67d557..ce6b3af 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -22,17 +22,25 @@ static QTAILQ_HEAD(, Coroutine) co_runnable_queue =
     QTAILQ_HEAD_INITIALIZER(co_runnable_queue);
 static QEMUBH* co_runnable_bh;
 
-static void qemu_co_process_runnable(void *opaque)
+static void coroutine_enter(Coroutine *self, Coroutine *co, void *opaque);
+static void process_runnable(Coroutine *self)
 {
     Coroutine *next;
 
-    trace_qemu_co_process_runnable();
     while ((next = QTAILQ_FIRST(&co_runnable_queue))) {
         QTAILQ_REMOVE(&co_runnable_queue, next, co_queue_next);
-        qemu_coroutine_enter(next, NULL);
+        coroutine_enter(self, next, NULL);
     }
 }
 
+static void qemu_co_process_runnable(void *opaque)
+{
+    Coroutine *self = qemu_coroutine_self();
+
+    trace_qemu_co_process_runnable();
+    process_runnable(self);
+}
+
 void qemu_co_runnable_schedule(Coroutine *co)
 {
     QTAILQ_INSERT_TAIL(&co_runnable_queue, co, co_queue_next);
@@ -69,10 +77,8 @@ static void coroutine_swap(Coroutine *from, Coroutine *to)
     }
 }
 
-void qemu_coroutine_enter(Coroutine *co, void *opaque)
+static void coroutine_enter(Coroutine *self, Coroutine *co, void *opaque)
 {
-    Coroutine *self = qemu_coroutine_self();
-
     trace_qemu_coroutine_enter(self, co, opaque);
 
     if (co->caller) {
@@ -85,6 +91,17 @@ void qemu_coroutine_enter(Coroutine *co, void *opaque)
     coroutine_swap(self, co);
 }
 
+void qemu_coroutine_enter(Coroutine *co, void *opaque)
+{
+    Coroutine *self = qemu_coroutine_self();
+    typeof(co_runnable_queue) snap = co_runnable_queue;
+
+    QTAILQ_INIT(&co_runnable_queue);
+    coroutine_enter(self, co, opaque);
+    process_runnable(self);
+    co_runnable_queue = snap;
+}
+
 void coroutine_fn qemu_coroutine_yield(void)
 {
     Coroutine *self = qemu_coroutine_self();
-- 
1.7.4.4


Reply via email to