]> git.proxmox.com Git - mirror_qemu.git/blobdiff - coroutine-win32.c
block/parallels: create bat_entry_off helper
[mirror_qemu.git] / coroutine-win32.c
index 0e29448473f37010c6ab9ffb910a83ad256513a0..17ace37deeb33a19d100f64e86c9ac780e4cd8bc 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "qemu-common.h"
-#include "qemu-coroutine-int.h"
+#include "block/coroutine_int.h"
 
 typedef struct
 {
@@ -36,8 +36,17 @@ typedef struct
 static __thread CoroutineWin32 leader;
 static __thread Coroutine *current;
 
-CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
-                                      CoroutineAction action)
+/* This function is marked noinline to prevent GCC from inlining it
+ * into coroutine_trampoline(). If we allow it to do that 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.
+ */
+CoroutineAction __attribute__((noinline))
+qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
+                      CoroutineAction action)
 {
     CoroutineWin32 *from = DO_UPCAST(CoroutineWin32, base, from_);
     CoroutineWin32 *to = DO_UPCAST(CoroutineWin32, base, to_);
@@ -64,7 +73,7 @@ Coroutine *qemu_coroutine_new(void)
     const size_t stack_size = 1 << 20;
     CoroutineWin32 *co;
 
-    co = qemu_mallocz(sizeof(*co));
+    co = g_malloc0(sizeof(*co));
     co->fiber = CreateFiber(stack_size, coroutine_trampoline, &co->base);
     return &co->base;
 }
@@ -74,7 +83,7 @@ void qemu_coroutine_delete(Coroutine *co_)
     CoroutineWin32 *co = DO_UPCAST(CoroutineWin32, base, co_);
 
     DeleteFiber(co->fiber);
-    qemu_free(co);
+    g_free(co);
 }
 
 Coroutine *qemu_coroutine_self(void)