You need to sign in or sign up before continuing.
  1. 23 8月, 2013 1 次提交
  2. 29 7月, 2013 1 次提交
  3. 27 6月, 2013 1 次提交
  4. 15 3月, 2013 1 次提交
    • S
      coroutine: use AioContext for CoQueue BH · 28f08246
      Stefan Hajnoczi 提交于
      CoQueue uses a BH to awake coroutines that were made ready to run again
      using qemu_co_queue_next() or qemu_co_queue_restart_all().  The BH
      currently runs in the iothread AioContext and would break coroutines
      that run in a different AioContext.
      
      This is a slightly tricky problem because the lifetime of the BH exceeds
      that of the CoQueue.  This means coroutines can be awoken after CoQueue
      itself has been freed.  Also, there is no qemu_co_queue_destroy()
      function which we could use to handle freeing resources.
      
      Introducing qemu_co_queue_destroy() has a ripple effect of requiring us
      to also add qemu_co_mutex_destroy() and qemu_co_rwlock_destroy(), as
      well as updating all callers.  Avoid doing that.
      
      We also cannot switch from BH to GIdle function because aio_poll() does
      not dispatch GIdle functions.  (GIdle functions make memory management
      slightly easier because they free themselves.)
      
      Finally, I don't want to move unlock_queue and unlock_bh into
      AioContext.  That would break encapsulation - AioContext isn't supposed
      to know about CoQueue.
      
      This patch implements a different solution: each qemu_co_queue_next() or
      qemu_co_queue_restart_all() call creates a new BH and list of coroutines
      to wake up.  Callers tend to invoke qemu_co_queue_next() and
      qemu_co_queue_restart_all() occasionally after blocking I/O, so creating
      a new BH for each call shouldn't be massively inefficient.
      
      Note that this patch does not add an interface for specifying the
      AioContext.  That is left to future patches which will convert CoQueue,
      CoMutex, and CoRwlock to expose AioContext.
      Signed-off-by: NStefan Hajnoczi <stefanha@redhat.com>
      Reviewed-by: NPaolo Bonzini <pbonzini@redhat.com>
      28f08246
  5. 19 12月, 2012 2 次提交
  6. 26 1月, 2012 1 次提交
  7. 05 12月, 2011 2 次提交
  8. 23 8月, 2011 1 次提交
  9. 02 8月, 2011 1 次提交
  10. 01 8月, 2011 1 次提交
    • K
      coroutine: introduce coroutines · 00dccaf1
      Kevin Wolf 提交于
      Asynchronous code is becoming very complex.  At the same time
      synchronous code is growing because it is convenient to write.
      Sometimes duplicate code paths are even added, one synchronous and the
      other asynchronous.  This patch introduces coroutines which allow code
      that looks synchronous but is asynchronous under the covers.
      
      A coroutine has its own stack and is therefore able to preserve state
      across blocking operations, which traditionally require callback
      functions and manual marshalling of parameters.
      
      Creating and starting a coroutine is easy:
      
        coroutine = qemu_coroutine_create(my_coroutine);
        qemu_coroutine_enter(coroutine, my_data);
      
      The coroutine then executes until it returns or yields:
      
        void coroutine_fn my_coroutine(void *opaque) {
            MyData *my_data = opaque;
      
            /* do some work */
      
            qemu_coroutine_yield();
      
            /* do some more work */
        }
      
      Yielding switches control back to the caller of qemu_coroutine_enter().
      This is typically used to switch back to the main thread's event loop
      after issuing an asynchronous I/O request.  The request callback will
      then invoke qemu_coroutine_enter() once more to switch back to the
      coroutine.
      
      Note that if coroutines are used only from threads which hold the global
      mutex they will never execute concurrently.  This makes programming with
      coroutines easier than with threads.  Race conditions cannot occur since
      only one coroutine may be active at any time.  Other coroutines can only
      run across yield.
      
      This coroutines implementation is based on the gtk-vnc implementation
      written by Anthony Liguori <anthony@codemonkey.ws> but it has been
      significantly rewritten by Kevin Wolf <kwolf@redhat.com> to use
      setjmp()/longjmp() instead of the more expensive swapcontext() and by
      Paolo Bonzini <pbonzini@redhat.com> for Windows Fibers support.
      Signed-off-by: NKevin Wolf <kwolf@redhat.com>
      Signed-off-by: NStefan Hajnoczi <stefanha@linux.vnet.ibm.com>
      00dccaf1