From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LkJpQ-0007xD-5t for qemu-devel@nongnu.org; Thu, 19 Mar 2009 11:06:40 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LkJpL-0007ud-AF for qemu-devel@nongnu.org; Thu, 19 Mar 2009 11:06:39 -0400 Received: from [199.232.76.173] (port=51971 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LkJpK-0007uW-Nn for qemu-devel@nongnu.org; Thu, 19 Mar 2009 11:06:34 -0400 Received: from mx2.redhat.com ([66.187.237.31]:36021) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LkJpK-0005x0-4h for qemu-devel@nongnu.org; Thu, 19 Mar 2009 11:06:34 -0400 Message-Id: <20090319150538.436435857@localhost.localdomain> References: <20090319145705.988576615@localhost.localdomain> Date: Thu, 19 Mar 2009 11:57:12 -0300 From: mtosatti@redhat.com Content-Disposition: inline; filename=iothread-fd Subject: [Qemu-devel] [patch 7/7] qemu: use pipe to wakeup io thread Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This avoids a wakeup being lost, in case the iothread handles the signal before select(). Copied and possibly damaged from kvm-userspace. Index: qemu/vl.c =================================================================== --- qemu.orig/vl.c +++ qemu/vl.c @@ -155,8 +155,6 @@ //#define DEBUG_NET //#define DEBUG_SLIRP -#define SIG_IPI (SIGRTMIN+4) - #ifdef DEBUG_IOPORT # define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__) #else @@ -273,6 +271,8 @@ QemuThread cpus_thread; QemuCond qemu_pause_cond; +static int io_thread_fd = -1; + static void pause_all_vcpus(void); static void resume_all_vcpus(void); @@ -3723,7 +3723,6 @@ static void block_io_signals(void) sigaddset(&set, SIGUSR2); sigaddset(&set, SIGIO); sigaddset(&set, SIGALRM); - sigaddset(&set, SIG_IPI); pthread_sigmask(SIG_BLOCK, &set, NULL); sigemptyset(&set); @@ -3735,30 +3734,19 @@ static void block_io_signals(void) sigaction(SIGUSR1, &sigact, NULL); } -/* used to wake up the io thread */ -static void sig_ipi_handler(int sig) -{ -} - static void unblock_io_signals(void) { sigset_t set; - struct sigaction sigact; sigemptyset(&set); sigaddset(&set, SIGUSR2); sigaddset(&set, SIGIO); sigaddset(&set, SIGALRM); - sigaddset(&set, SIG_IPI); pthread_sigmask(SIG_UNBLOCK, &set, NULL); sigemptyset(&set); sigaddset(&set, SIGUSR1); pthread_sigmask(SIG_BLOCK, &set, NULL); - - memset(&sigact, 0, sizeof(sigact)); - sigact.sa_handler = sig_ipi_handler; - sigaction(SIG_IPI, &sigact, NULL); } int qemu_notify_event(void *cpu_env) @@ -3774,11 +3762,51 @@ int qemu_notify_event(void *cpu_env) void main_loop_break(void) { - QemuThread me; - qemu_thread_self(&me); - if (qemu_thread_equal(&io_thread, &me)) + uint64_t value = 1; + char buffer[8]; + size_t offset = 0; + + if (io_thread_fd == -1) return; - qemu_thread_signal(&io_thread, SIG_IPI); + + memcpy(buffer, &value, sizeof(value)); + + while (offset < 8) { + ssize_t len; + + len = write(io_thread_fd, buffer + offset, 8 - offset); + if (len == -1 && errno == EINTR) + continue; + + if (len <= 0) + break; + + offset += len; + } + + if (offset != 8) + fprintf(stderr, "failed to notify io thread\n"); +} + +/* Used to break IO thread out of select */ +static void io_thread_wakeup(void *opaque) +{ + int fd = (unsigned long)opaque; + char buffer[8]; + size_t offset = 0; + + while (offset < 8) { + ssize_t len; + + len = read(fd, buffer + offset, 8 - offset); + if (len == -1 && errno == EINTR) + continue; + + if (len <= 0) + break; + + offset += len; + } } static void qemu_signal_lock(unsigned int msecs) @@ -4086,6 +4114,20 @@ static void resume_all_vcpus(void) } } +static void setup_iothread_fd(void) +{ + int fds[2]; + + if (pipe(fds) == -1) { + fprintf(stderr, "failed to create iothread pipe"); + exit(0); + } + + qemu_set_fd_handler2(fds[0], NULL, io_thread_wakeup, NULL, + (void *)(unsigned long)fds[0]); + io_thread_fd = fds[1]; +} + static void main_loop(void) { int r; @@ -4096,6 +4138,7 @@ static void main_loop(void) qemu_cond_init(&qemu_pause_cond); qemu_thread_self(&io_thread); + setup_iothread_fd(); unblock_io_signals(); --