Skip to content
Snippets Groups Projects
  1. May 18, 2023
  2. May 04, 2022
    • Stefan Hajnoczi's avatar
      coroutine-win32: use QEMU_DEFINE_STATIC_CO_TLS() · c1fe6943
      Stefan Hajnoczi authored
      
      Thread-Local Storage variables cannot be used directly from coroutine
      code because the compiler may optimize TLS variable accesses across
      qemu_coroutine_yield() calls. When the coroutine is re-entered from
      another thread the TLS variables from the old thread must no longer be
      used.
      
      Use QEMU_DEFINE_STATIC_CO_TLS() for the current and leader variables.
      
      I think coroutine-win32.c could get away with __thread because the
      variables are only used in situations where either the stale value is
      correct (current) or outside coroutine context (loading leader when
      current is NULL). Due to the difficulty of being sure that this is
      really safe in all scenarios it seems worth converting it anyway.
      
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
      Message-Id: <20220307153853.602859-4-stefanha@redhat.com>
      Reviewed-by: default avatarPhilippe Mathieu-Daudé <f4bug@amsat.org>
      Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
      c1fe6943
  3. Apr 06, 2022
  4. Sep 29, 2016
  5. Feb 04, 2016
  6. Oct 20, 2015
    • Daniel P. Berrangé's avatar
      coroutine: move into libqemuutil.a library · 10817bf0
      Daniel P. Berrangé authored
      
      The coroutine files are currently referenced by the block-obj-y
      variable. The coroutine functionality though is already used by
      more than just the block code. eg migration code uses coroutine
      yield. In the future the I/O channel code will also use the
      coroutine yield functionality. Since the coroutine code is nicely
      self-contained it can be easily built as part of the libqemuutil.a
      library, making it widely available.
      
      The headers are also moved into include/qemu, instead of the
      include/block directory, since they are now part of the util
      codebase, and the impl was never in the block/ directory
      either.
      
      Signed-off-by: default avatarDaniel P. Berrange <berrange@redhat.com>
      10817bf0
  7. Jun 26, 2014
    • Peter Maydell's avatar
      coroutine-win32.c: Add noinline attribute to work around gcc bug · ff4873cb
      Peter Maydell authored
      
      A gcc codegen bug in x86_64-w64-mingw32-gcc (GCC) 4.6.3 means that
      non-debug builds of QEMU for Windows tend to assert when using
      coroutines. Work around this by marking qemu_coroutine_switch
      as noinline.
      
      If we allow gcc to inline qemu_coroutine_switch into
      coroutine_trampoline, then it hoists the code to get the
      address of the TLS variable "current" out of the while() loop.
      This is an invalid transformation because the SwitchToFiber()
      call may be called when running thread A but return in thread B,
      and so we might be in a different thread context each time
      round the loop. This can happen quite often.  Typically.
      a coroutine is started when a VCPU thread does bdrv_aio_readv:
      
           VCPU thread
      
           main VCPU thread coroutine      I/O coroutine
              bdrv_aio_readv ----->
                                           start I/O operation
                                             thread_pool_submit_co
                             <------------ yields
              back to emulation
      
      Then I/O finishes and the thread-pool.c event notifier triggers in
      the I/O thread.  event_notifier_ready calls thread_pool_co_cb, and
      the I/O coroutine now restarts *in another thread*:
      
           iothread
      
           main iothread coroutine         I/O coroutine (formerly in VCPU thread)
              event_notifier_ready
                thread_pool_co_cb ----->   current = I/O coroutine;
                                           call AIO callback
      
      But on Win32, because of the bug, the "current" being set here the
      current coroutine of the VCPU thread, not the iothread.
      
      noinline is a good-enough workaround, and quite unlikely to break in
      the future.
      
      (Thanks to Paolo Bonzini for assistance in diagnosing the problem
      and providing the detailed example/ascii art quoted above.)
      
      Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
      Message-id: 1403535303-14939-1-git-send-email-peter.maydell@linaro.org
      Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
      Reviewed-by: default avatarRichard Henderson <rth@twiddle.net>
      ff4873cb
  8. Dec 19, 2012
  9. Aug 21, 2011
  10. Aug 01, 2011
    • Kevin Wolf's avatar
      coroutine: introduce coroutines · 00dccaf1
      Kevin Wolf authored
      
      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: default avatarKevin Wolf <kwolf@redhat.com>
      Signed-off-by: default avatarStefan Hajnoczi <stefanha@linux.vnet.ibm.com>
      00dccaf1
Loading