qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC PATCH 11/13] rcuify iohandlers


From: Paolo Bonzini
Subject: [Qemu-devel] [RFC PATCH 11/13] rcuify iohandlers
Date: Mon, 15 Aug 2011 14:08:38 -0700

Just a proof of concept, with the write-side still under the global
lock, in order to test the call_rcu code.

Signed-off-by: Paolo Bonzini <address@hidden>
---
 iohandler.c |   45 ++++++++++++++++++++-------------------------
 1 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/iohandler.c b/iohandler.c
index 2b82421..4c1f68f 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -26,17 +26,18 @@
 #include "qemu-common.h"
 #include "qemu-char.h"
 #include "qemu-queue.h"
+#include "rcu.h"
 
 #ifndef _WIN32
 #include <sys/wait.h>
 #endif
 
 typedef struct IOHandlerRecord {
+    struct rcu_head h;
     int fd;
     IOCanReadHandler *fd_read_poll;
     IOHandler *fd_read;
     IOHandler *fd_write;
-    int deleted;
     void *opaque;
     QLIST_ENTRY(IOHandlerRecord) next;
 } IOHandlerRecord;
@@ -55,28 +56,26 @@ int qemu_set_fd_handler2(int fd,
 {
     IOHandlerRecord *ioh;
 
-    if (!fd_read && !fd_write) {
-        QLIST_FOREACH(ioh, &io_handlers, next) {
-            if (ioh->fd == fd) {
-                ioh->deleted = 1;
-                break;
-            }
-        }
-    } else {
-        QLIST_FOREACH(ioh, &io_handlers, next) {
-            if (ioh->fd == fd)
-                goto found;
+    //qemu_mutex_lock(&iohandler_lock);
+    QLIST_FOREACH(ioh, &io_handlers, next) {
+        if (ioh->fd == fd) {
+            break;
         }
+    }
+    if (ioh) {
+        QLIST_REMOVE(ioh, next);
+        call_rcu(&ioh->h, rcu_free);
+    }
+    if (fd_read || fd_write) {
         ioh = qemu_mallocz(sizeof(IOHandlerRecord));
-        QLIST_INSERT_HEAD(&io_handlers, ioh, next);
-    found:
         ioh->fd = fd;
         ioh->fd_read_poll = fd_read_poll;
         ioh->fd_read = fd_read;
         ioh->fd_write = fd_write;
         ioh->opaque = opaque;
-        ioh->deleted = 0;
+        QLIST_INSERT_HEAD(&io_handlers, ioh, next);
     }
+    //qemu_mutex_lock(&iohandler_unlock);
     return 0;
 }
 
@@ -92,9 +91,8 @@ void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set 
*writefds, fd_set *
 {
     IOHandlerRecord *ioh;
 
+    rcu_read_lock();
     QLIST_FOREACH(ioh, &io_handlers, next) {
-        if (ioh->deleted)
-            continue;
         if (ioh->fd_read &&
             (!ioh->fd_read_poll ||
              ioh->fd_read_poll(ioh->opaque) != 0)) {
@@ -108,6 +106,7 @@ void qemu_iohandler_fill(int *pnfds, fd_set *readfds, 
fd_set *writefds, fd_set *
                 *pnfds = ioh->fd;
         }
     }
+    rcu_read_unlock();
 }
 
 void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int 
ret)
@@ -115,20 +114,16 @@ void qemu_iohandler_poll(fd_set *readfds, fd_set 
*writefds, fd_set *xfds, int re
     if (ret > 0) {
         IOHandlerRecord *pioh, *ioh;
 
+        rcu_read_lock();
         QLIST_FOREACH_SAFE(ioh, &io_handlers, next, pioh) {
-            if (!ioh->deleted && ioh->fd_read && FD_ISSET(ioh->fd, readfds)) {
+            if (ioh->fd_read && FD_ISSET(ioh->fd, readfds)) {
                 ioh->fd_read(ioh->opaque);
             }
-            if (!ioh->deleted && ioh->fd_write && FD_ISSET(ioh->fd, writefds)) 
{
+            if (ioh->fd_write && FD_ISSET(ioh->fd, writefds)) {
                 ioh->fd_write(ioh->opaque);
             }
-
-            /* Do this last in case read/write handlers marked it for deletion 
*/
-            if (ioh->deleted) {
-                QLIST_REMOVE(ioh, next);
-                qemu_free(ioh);
-            }
         }
+        rcu_read_unlock();
     }
 }
 
-- 
1.7.6





reply via email to

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