All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: pbonzini@redhat.com, aliguori@us.ibm.com, qemulist@gmail.com,
	stefanha@redhat.com
Subject: [Qemu-devel] [PATCH 8/9] main-loop: drive main event loop via QContext
Date: Fri,  3 May 2013 11:03:51 -0500	[thread overview]
Message-ID: <1367597032-28934-9-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1367597032-28934-1-git-send-email-mdroth@linux.vnet.ibm.com>

This series attaches the global AioContext's GSource to the QContext
we've layered on top of the main GMainContext. This, paired with the
similar treatment given to IOHandlers earlier, allows us to drive the
main loop without using fill/poll functions to add/dispatch events that
are external to our main (Glib)QContext.

This patch breaks Slirp, which needs to be re-worked so that it can be
driven via QContext. Patches are on the list to port that to GSource,
so we assume for the purposes of this RFC that that's a solved problem.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 async.c             |   16 +++++++++++
 include/block/aio.h |    6 +++++
 main-loop.c         |   75 ++++++++++++++++++---------------------------------
 3 files changed, 48 insertions(+), 49 deletions(-)

diff --git a/async.c b/async.c
index 90fe906..a36e2e1 100644
--- a/async.c
+++ b/async.c
@@ -22,10 +22,13 @@
  * THE SOFTWARE.
  */
 
+#include <glib.h>
 #include "qemu-common.h"
 #include "block/aio.h"
 #include "block/thread-pool.h"
 #include "qemu/main-loop.h"
+#include "qcontext/qcontext.h"
+#include "qcontext/glib-qcontext.h"
 
 /***********************************************************/
 /* bottom halves (can be seen as timers which expire ASAP) */
@@ -219,6 +222,19 @@ AioContext *aio_context_new(void)
     return ctx;
 }
 
+void aio_context_attach(AioContext *ctx, QContext *qctx)
+{
+    GSource *aio_gsource = aio_get_g_source(ctx);
+    GMainContext *qctx_main_context =
+        glib_qcontext_get_context(GLIB_QCONTEXT(qctx));
+
+    /* TODO: implement AioContext as a QSource instead of a GSource
+     * so we can attach to any QContext implementation instead of
+     * acting directly on the underlying GMainContext
+     */
+    g_source_attach(aio_gsource, qctx_main_context);
+}
+
 void aio_context_ref(AioContext *ctx)
 {
     g_source_ref(&ctx->source);
diff --git a/include/block/aio.h b/include/block/aio.h
index 1836793..400df54 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -17,6 +17,7 @@
 #include "qemu-common.h"
 #include "qemu/queue.h"
 #include "qemu/event_notifier.h"
+#include "qcontext/qcontext.h"
 
 typedef struct BlockDriverAIOCB BlockDriverAIOCB;
 typedef void BlockDriverCompletionFunc(void *opaque, int ret);
@@ -244,4 +245,9 @@ void qemu_aio_set_fd_handler(int fd,
                              void *opaque);
 #endif
 
+/* Attach an AioContext to a QContext so that it can be driven by a
+ * QContext-based event loop
+ */
+void aio_context_attach(AioContext *ctx, QContext *qctx);
+
 #endif
diff --git a/main-loop.c b/main-loop.c
index ae284a6..708581d 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -136,7 +136,6 @@ static GArray *gpollfds;
 int qemu_init_main_loop(void)
 {
     int ret;
-    GSource *src;
     Error *err = NULL;
 
     init_clocks();
@@ -159,62 +158,37 @@ int qemu_init_main_loop(void)
         return ret;
     }
 
+    /* TODO: we can drop gpollfds completely once we integrate
+     * Ping Fan's slirp->glib patches. Until then slirp won't
+     * work since we're no longer driving it via fill/poll
+     * functions
+     */
     gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
     qemu_aio_context = aio_context_new();
-    src = aio_get_g_source(qemu_aio_context);
-    g_source_attach(src, NULL);
-    g_source_unref(src);
+    aio_context_attach(qemu_aio_context, qemu_qcontext);
     return 0;
 }
 
-static int max_priority;
-
 #ifndef _WIN32
-static int glib_pollfds_idx;
-static int glib_n_poll_fds;
-
-static void glib_pollfds_fill(uint32_t *cur_timeout)
-{
-    GMainContext *context = g_main_context_default();
-    int timeout = 0;
-    int n;
-
-    g_main_context_prepare(context, &max_priority);
-
-    glib_pollfds_idx = gpollfds->len;
-    n = glib_n_poll_fds;
-    do {
-        GPollFD *pfds;
-        glib_n_poll_fds = n;
-        g_array_set_size(gpollfds, glib_pollfds_idx + glib_n_poll_fds);
-        pfds = &g_array_index(gpollfds, GPollFD, glib_pollfds_idx);
-        n = g_main_context_query(context, max_priority, &timeout, pfds,
-                                 glib_n_poll_fds);
-    } while (n != glib_n_poll_fds);
-
-    if (timeout >= 0 && timeout < *cur_timeout) {
-        *cur_timeout = timeout;
-    }
-}
-
-static void glib_pollfds_poll(void)
-{
-    GMainContext *context = g_main_context_default();
-    GPollFD *pfds = &g_array_index(gpollfds, GPollFD, glib_pollfds_idx);
-
-    if (g_main_context_check(context, max_priority, pfds, glib_n_poll_fds)) {
-        g_main_context_dispatch(context);
-    }
-}
 
 #define MAX_MAIN_LOOP_SPIN (1000)
 
 static int os_host_main_loop_wait(uint32_t timeout)
 {
-    int ret;
+    QContext *qctx = qemu_get_qcontext();
+    gboolean ret;
+    int calculated_timeout = 0;
+    int events_dispatched = 0;
     static int spin_counter;
 
-    glib_pollfds_fill(&timeout);
+    ret = qcontext_prepare(qctx, &calculated_timeout);
+    if (ret) {
+        qcontext_dispatch(qctx);
+        events_dispatched = 1;
+    }
+    if (calculated_timeout >= 0 && calculated_timeout < timeout) {
+        timeout = calculated_timeout;
+    }
 
     /* If the I/O thread is very busy or we are incorrectly busy waiting in
      * the I/O thread, this can lead to starvation of the BQL such that the
@@ -241,15 +215,16 @@ static int os_host_main_loop_wait(uint32_t timeout)
     } else {
         spin_counter++;
     }
-
-    ret = g_poll((GPollFD *)gpollfds->data, gpollfds->len, timeout);
-
+    ret = qcontext_poll(qctx, timeout);
     if (timeout > 0) {
         qemu_mutex_lock_iothread();
     }
+    if (ret && qcontext_check(qctx)) {
+        qcontext_dispatch(qctx);
+        events_dispatched = 1;
+    }
 
-    glib_pollfds_poll();
-    return ret;
+    return events_dispatched;
 }
 #else
 /***********************************************************/
@@ -391,6 +366,8 @@ static void pollfds_poll(GArray *pollfds, int nfds, fd_set *rfds,
     }
 }
 
+static int max_priority;
+
 static int os_host_main_loop_wait(uint32_t timeout)
 {
     GMainContext *context = g_main_context_default();
-- 
1.7.9.5

  parent reply	other threads:[~2013-05-03 16:05 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-03 16:03 [Qemu-devel] [RFC 0/9] QContext: QOM class to support multiple event loops Michael Roth
2013-05-03 16:03 ` [Qemu-devel] [PATCH 1/9] qom: add qom_init_completion Michael Roth
2013-05-06  7:45   ` Paolo Bonzini
2013-05-06 19:01     ` mdroth
2013-05-03 16:03 ` [Qemu-devel] [PATCH 2/9] qom: add object_property_add_unnamed_child Michael Roth
2013-05-06  7:44   ` Paolo Bonzini
2013-05-06 18:48     ` mdroth
2013-05-08 11:33       ` Stefan Hajnoczi
2013-05-03 16:03 ` [Qemu-devel] [PATCH 3/9] QSource: QEMU event source object Michael Roth
2013-05-03 16:03 ` [Qemu-devel] [PATCH 4/9] QContext: QEMU event loop context, abstract base class Michael Roth
2013-05-03 16:03 ` [Qemu-devel] [PATCH 5/9] GlibQContext: a QContext wrapper around GMainContexts Michael Roth
2013-05-03 16:03 ` [Qemu-devel] [PATCH 6/9] QContext: add unit tests Michael Roth
2013-05-03 16:03 ` [Qemu-devel] [PATCH 7/9] iohandler: associate with main event loop via a QSource Michael Roth
2013-05-06  7:53   ` Paolo Bonzini
2013-05-06 19:03     ` mdroth
2013-08-15  6:07     ` Wenchao Xia
2013-05-03 16:03 ` Michael Roth [this message]
2013-05-03 16:03 ` [Qemu-devel] [PATCH 9/9] dataplane: use a QContext event loop in place of custom thread Michael Roth
2013-05-06  7:54   ` Paolo Bonzini
2013-05-06 19:13     ` mdroth
2013-05-06  3:26 ` [Qemu-devel] [RFC 0/9] QContext: QOM class to support multiple event loops liu ping fan
2013-05-06 18:43   ` mdroth
2013-05-06  7:54 ` Paolo Bonzini
2013-05-06 12:25   ` Anthony Liguori
2013-05-06 18:35     ` mdroth
2013-05-06 20:04       ` Paolo Bonzini
2013-05-06 18:17   ` mdroth
2013-05-08 11:54     ` Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1367597032-28934-9-git-send-email-mdroth@linux.vnet.ibm.com \
    --to=mdroth@linux.vnet.ibm.com \
    --cc=aliguori@us.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemulist@gmail.com \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.