]> git.proxmox.com Git - mirror_qemu.git/blobdiff - util/main-loop.c
i386: Update new x86_apicid parsing rules with die_offset support
[mirror_qemu.git] / util / main-loop.c
index 992f9b0f3457fd959eb975df0165ec34aa47676a..a9f4e8de75f7b00f8c690875849b344eadf044ce 100644 (file)
 #include "qapi/error.h"
 #include "qemu/cutils.h"
 #include "qemu/timer.h"
-#include "qemu/sockets.h"      // struct in_addr needed for libslirp.h
 #include "sysemu/qtest.h"
 #include "sysemu/cpus.h"
 #include "sysemu/replay.h"
-#include "slirp/libslirp.h"
 #include "qemu/main-loop.h"
 #include "block/aio.h"
 #include "qemu/error-report.h"
@@ -71,7 +69,7 @@ static void sigfd_handler(void *opaque)
     }
 }
 
-static int qemu_signal_init(void)
+static int qemu_signal_init(Error **errp)
 {
     int sigfd;
     sigset_t set;
@@ -96,7 +94,7 @@ static int qemu_signal_init(void)
     sigdelset(&set, SIG_IPI);
     sigfd = qemu_signalfd(&set);
     if (sigfd == -1) {
-        fprintf(stderr, "failed to create signalfd\n");
+        error_setg_errno(errp, errno, "failed to create signalfd");
         return -errno;
     }
 
@@ -109,7 +107,7 @@ static int qemu_signal_init(void)
 
 #else /* _WIN32 */
 
-static int qemu_signal_init(void)
+static int qemu_signal_init(Error **errp)
 {
     return 0;
 }
@@ -148,7 +146,7 @@ int qemu_init_main_loop(Error **errp)
 
     init_clocks(qemu_timer_notify_cb);
 
-    ret = qemu_signal_init();
+    ret = qemu_signal_init(errp);
     if (ret) {
         return ret;
     }
@@ -222,36 +220,11 @@ static int os_host_main_loop_wait(int64_t timeout)
 {
     GMainContext *context = g_main_context_default();
     int ret;
-    static int spin_counter;
 
     g_main_context_acquire(context);
 
     glib_pollfds_fill(&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
-     * VCPU threads never run.  To make sure we can detect the later case,
-     * print a message to the screen.  If we run into this condition, create
-     * a fake timeout in order to give the VCPU threads a chance to run.
-     */
-    if (!timeout && (spin_counter > MAX_MAIN_LOOP_SPIN)) {
-        static bool notified;
-
-        if (!notified && !qtest_enabled() && !qtest_driver()) {
-            warn_report("I/O thread spun for %d iterations",
-                        MAX_MAIN_LOOP_SPIN);
-            notified = true;
-        }
-
-        timeout = SCALE_MS;
-    }
-
-
-    if (timeout) {
-        spin_counter = 0;
-    } else {
-        spin_counter++;
-    }
     qemu_mutex_unlock_iothread();
     replay_mutex_unlock();
 
@@ -449,7 +422,7 @@ static int os_host_main_loop_wait(int64_t timeout)
     g_main_context_prepare(context, &max_priority);
     n_poll_fds = g_main_context_query(context, max_priority, &poll_timeout,
                                       poll_fds, ARRAY_SIZE(poll_fds));
-    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
+    g_assert(n_poll_fds + w->num <= ARRAY_SIZE(poll_fds));
 
     for (i = 0; i < w->num; i++) {
         poll_fds[n_poll_fds + i].fd = (DWORD_PTR)w->events[i];
@@ -494,25 +467,42 @@ static int os_host_main_loop_wait(int64_t timeout)
 }
 #endif
 
+static NotifierList main_loop_poll_notifiers =
+    NOTIFIER_LIST_INITIALIZER(main_loop_poll_notifiers);
+
+void main_loop_poll_add_notifier(Notifier *notify)
+{
+    notifier_list_add(&main_loop_poll_notifiers, notify);
+}
+
+void main_loop_poll_remove_notifier(Notifier *notify)
+{
+    notifier_remove(notify);
+}
+
 void main_loop_wait(int nonblocking)
 {
+    MainLoopPoll mlpoll = {
+        .state = MAIN_LOOP_POLL_FILL,
+        .timeout = UINT32_MAX,
+        .pollfds = gpollfds,
+    };
     int ret;
-    uint32_t timeout = UINT32_MAX;
     int64_t timeout_ns;
 
     if (nonblocking) {
-        timeout = 0;
+        mlpoll.timeout = 0;
     }
 
     /* poll any events */
     g_array_set_size(gpollfds, 0); /* reset for new iteration */
     /* XXX: separate device handlers from system ones */
-    slirp_pollfds_fill(gpollfds, &timeout);
+    notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);
 
-    if (timeout == UINT32_MAX) {
+    if (mlpoll.timeout == UINT32_MAX) {
         timeout_ns = -1;
     } else {
-        timeout_ns = (uint64_t)timeout * (int64_t)(SCALE_MS);
+        timeout_ns = (uint64_t)mlpoll.timeout * (int64_t)(SCALE_MS);
     }
 
     timeout_ns = qemu_soonest_timeout(timeout_ns,
@@ -520,7 +510,8 @@ void main_loop_wait(int nonblocking)
                                           &main_loop_tlg));
 
     ret = os_host_main_loop_wait(timeout_ns);
-    slirp_pollfds_poll(gpollfds, (ret < 0));
+    mlpoll.state = ret < 0 ? MAIN_LOOP_POLL_ERR : MAIN_LOOP_POLL_OK;
+    notifier_list_notify(&main_loop_poll_notifiers, &mlpoll);
 
     /* CPU thread can infinitely wait for event after
        missing the warp */