All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jamie Lokier <jamie@shareable.org>
To: qemu-devel@nongnu.org
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Subject: Re: [Qemu-devel] [patch 04/10] qemu: introduce main_loop_break
Date: Thu, 26 Mar 2009 12:27:17 +0000	[thread overview]
Message-ID: <20090326122717.GB20866@shareable.org> (raw)
In-Reply-To: <20090325225438.990466524@amt.cnet>

Marcelo Tosatti wrote:
> Use a pipe to signal pending work for the iothread.

> +void main_loop_break(void)
> +{
> +    uint64_t value = 1;
> +    char buffer[8];
> +    size_t offset = 0;
> +
> +    if (io_thread_fd == -1)
> +        return;
> +
> +    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");

1: Why do you write 8 bytes instead of 1 byte?  If you're thinking of
   passing a value at some point, you could change it later when it's
   needed.  But beware that requiring the pipe to hold all values
   written is what made Netscape 4 lock up on too-new Linux kernels
   some 10 years ago :-)

2: Do you know that writes <= PIPE_BUF are atomic so you don't need
   the offset calculation?

> +/* 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;
> +    }
> +}

You should read until the pipe is empty, in case more than one signal
was raised and called main_loop_break() between calls to
io_thread_wait().

Since reads <= PIPE_BUF are atomic too, the easiest way to do that is
try to read at least one more byte than you wrote per
main_loop_break() call, and if you don't get that many, you've emptied
the pipe.

> +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];
> +}

To avoid deadlock in perverse conditions where lots of signals call
main_loop_break() enough to fill the pipe before it's read, set the
write side non-blocking.

To use the trick of reading more bytes than you expect to detect EOF
without an extra read, set the read side non-blocking too.

-- Jamie

  parent reply	other threads:[~2009-03-26 12:27 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-25 22:47 [Qemu-devel] [patch 00/10] iothread (candidate for inclusion) Marcelo Tosatti
2009-03-25 22:47 ` [Qemu-devel] [patch 01/10] qemu: create helper for event notification Marcelo Tosatti
2009-03-25 23:18   ` Glauber Costa
2009-03-25 23:27     ` Marcelo Tosatti
2009-03-25 22:47 ` [Qemu-devel] [patch 02/10] qemu: mutex/thread/cond wrappers Marcelo Tosatti
2009-03-25 23:24   ` Glauber Costa
2009-03-25 23:29     ` Marcelo Tosatti
2009-03-26 11:01   ` malc
2009-03-25 22:47 ` [Qemu-devel] [patch 03/10] qemu: per-arch cpu_has_work Marcelo Tosatti
2009-03-25 23:26   ` Glauber Costa
2009-03-28 18:14   ` Blue Swirl
2009-03-29 20:13     ` Blue Swirl
2009-04-02 23:42       ` Marcelo Tosatti
2009-03-25 22:47 ` [Qemu-devel] [patch 04/10] qemu: introduce main_loop_break Marcelo Tosatti
2009-03-26  1:24   ` Glauber Costa
2009-03-26 12:27   ` Jamie Lokier [this message]
2009-04-02 23:36     ` Marcelo Tosatti
2009-04-02 23:52       ` Anthony Liguori
2009-04-03 14:08         ` Markus Armbruster
2009-04-07  3:23         ` Jamie Lokier
2009-03-25 22:47 ` [Qemu-devel] [patch 05/10] qemu: separate thread for io Marcelo Tosatti
2009-03-25 22:47 ` [Qemu-devel] [patch 06/10] qemu: per-cpu thread information Marcelo Tosatti
2009-03-26  1:35   ` Glauber Costa
2009-03-26  2:10     ` Marcelo Tosatti
2009-03-26  2:26       ` Glauber Costa
2009-03-26  2:41         ` Marcelo Tosatti
2009-03-25 22:47 ` [Qemu-devel] [patch 07/10] qemu: handle reset/poweroff/shutdown in iothread Marcelo Tosatti
2009-03-25 22:47 ` [Qemu-devel] [patch 08/10] qemu: pause and resume cpu threads Marcelo Tosatti
2009-03-25 22:47 ` [Qemu-devel] [patch 09/10] qemu: handle vmstop from cpu context Marcelo Tosatti
2009-03-25 22:47 ` [Qemu-devel] [patch 10/10] qemu: basic kvm iothread support Marcelo Tosatti
2009-03-29 20:16 ` [Qemu-devel] [patch 00/10] iothread (candidate for inclusion) Blue Swirl

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=20090326122717.GB20866@shareable.org \
    --to=jamie@shareable.org \
    --cc=mtosatti@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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.