qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH V3 08/11] qom: introduce reclaimer to release obj in


From: Liu Ping Fan
Subject: [Qemu-devel] [PATCH V3 08/11] qom: introduce reclaimer to release obj in async
Date: Tue, 11 Sep 2012 15:51:49 +0800

From: Liu Ping Fan <address@hidden>

DeviceState will be protected by refcnt from disappearing during
dispatching. But when refcnt comes down to zero, DeviceState may
be still in use by iohandler, timer etc in main loop, we just delay
its free untill no reader.

This patch aim to build this delay reclaimer.

Signed-off-by: Liu Ping Fan <address@hidden>
---
 include/qemu/reclaimer.h |   30 +++++++++++++++++++++++++
 main-loop.c              |    5 ++++
 qemu-tool.c              |    5 ++++
 qom/Makefile.objs        |    2 +-
 qom/reclaimer.c          |   54 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 95 insertions(+), 1 deletions(-)
 create mode 100644 include/qemu/reclaimer.h
 create mode 100644 qom/reclaimer.c

diff --git a/include/qemu/reclaimer.h b/include/qemu/reclaimer.h
new file mode 100644
index 0000000..5143c4f
--- /dev/null
+++ b/include/qemu/reclaimer.h
@@ -0,0 +1,30 @@
+/*
+ * QEMU reclaimer
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_RECLAIMER
+#define QEMU_RECLAIMER
+
+#include "qemu-thread.h"
+
+typedef void ReleaseHandler(void *opaque);
+typedef struct Chunk {
+    QLIST_ENTRY(Chunk) list;
+    void *opaque;
+    ReleaseHandler *release;
+} Chunk;
+
+typedef struct ChunkHead {
+    struct QemuMutex lock;
+    QLIST_HEAD(, Chunk) reclaim_list;
+} ChunkHead;
+
+extern ChunkHead qdev_reclaimer;
+void reclaimer_enqueue(ChunkHead *head, void *opaque, ReleaseHandler *release);
+void reclaimer_worker(ChunkHead *head);
+void qemu_reclaimer(void);
+#endif
diff --git a/main-loop.c b/main-loop.c
index eb3b6e6..be9d095 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -26,6 +26,7 @@
 #include "qemu-timer.h"
 #include "slirp/slirp.h"
 #include "main-loop.h"
+#include "qemu/reclaimer.h"
 
 #ifndef _WIN32
 
@@ -505,5 +506,9 @@ int main_loop_wait(int nonblocking)
        them.  */
     qemu_bh_poll();
 
+    /* ref to device from iohandler/bh/timer do not obey the rules, so delay
+     * reclaiming until now.
+     */
+    qemu_reclaimer();
     return ret;
 }
diff --git a/qemu-tool.c b/qemu-tool.c
index 18205ba..f250c87 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -21,6 +21,7 @@
 #include "main-loop.h"
 #include "qemu_socket.h"
 #include "slirp/libslirp.h"
+#include "qemu/reclaimer.h"
 
 #include <sys/time.h>
 
@@ -100,6 +101,10 @@ void qemu_mutex_unlock_iothread(void)
 {
 }
 
+void qemu_reclaimer(void)
+{
+}
+
 int use_icount;
 
 void qemu_clock_warp(QEMUClock *clock)
diff --git a/qom/Makefile.objs b/qom/Makefile.objs
index 5ef060a..a579261 100644
--- a/qom/Makefile.objs
+++ b/qom/Makefile.objs
@@ -1,4 +1,4 @@
-qom-obj-y = object.o container.o qom-qobject.o
+qom-obj-y = object.o container.o qom-qobject.o reclaimer.o
 qom-obj-twice-y = cpu.o
 common-obj-y = $(qom-obj-twice-y)
 user-obj-y = $(qom-obj-twice-y)
diff --git a/qom/reclaimer.c b/qom/reclaimer.c
new file mode 100644
index 0000000..b098ad7
--- /dev/null
+++ b/qom/reclaimer.c
@@ -0,0 +1,54 @@
+/*
+ * QEMU reclaimer
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu-common.h"
+#include "qemu-thread.h"
+#include "main-loop.h"
+#include "qemu-queue.h"
+#include "qemu/reclaimer.h"
+
+ChunkHead qdev_reclaimer;
+
+static void reclaimer_init(ChunkHead *head)
+{
+  qemu_mutex_init(&head->lock);
+}
+
+void reclaimer_enqueue(ChunkHead *head, void *opaque, ReleaseHandler *release)
+{
+    Chunk *r = g_malloc0(sizeof(Chunk));
+    r->opaque = opaque;
+    r->release = release;
+    qemu_mutex_lock(&head->lock);
+    QLIST_INSERT_HEAD(&head->reclaim_list, r, list);
+    qemu_mutex_unlock(&head->lock);
+}
+
+void reclaimer_worker(ChunkHead *head)
+{
+    Chunk *cur, *next;
+
+    qemu_mutex_lock(&head->lock);
+    QLIST_FOREACH_SAFE(cur, &head->reclaim_list, list, next) {
+        QLIST_REMOVE(cur, list);
+        cur->release(cur->opaque);
+        g_free(cur);
+    }
+    qemu_mutex_unlock(&head->lock);
+}
+
+void qemu_reclaimer(void)
+{
+    static int init;
+
+    if (init == 0) {
+        init = 1;
+        reclaimer_init(&qdev_reclaimer);
+    }
+    reclaimer_worker(&qdev_reclaimer);
+}
-- 
1.7.4.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]