coroutine: introduce coroutines

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 <[email protected]> but it has been
significantly rewritten by Kevin Wolf <[email protected]> to use
setjmp()/longjmp() instead of the more expensive swapcontext() and by
Paolo Bonzini <[email protected]> for Windows Fibers support.

Signed-off-by: Kevin Wolf <[email protected]>
Signed-off-by: Stefan Hajnoczi <[email protected]>
7 files changed
tree: acc1d17a272a1a3494125d96ff22bb638566f076
  1. audio/
  2. block/
  3. bsd-user/
  4. darwin-user/
  5. default-configs/
  6. docs/
  7. fpu/
  8. fsdev/
  9. gdb-xml/
  10. hw/
  11. libcacard/
  12. linux-headers/
  13. linux-user/
  14. net/
  15. pc-bios/
  16. qapi/
  17. qga/
  18. QMP/
  19. roms/
  20. scripts/
  21. slirp/
  22. sysconfigs/
  23. target-alpha/
  24. target-arm/
  25. target-cris/
  26. target-i386/
  27. target-lm32/
  28. target-m68k/
  29. target-microblaze/
  30. target-mips/
  31. target-ppc/
  32. target-s390x/
  33. target-sh4/
  34. target-sparc/
  35. target-unicore32/
  36. tcg/
  37. tests/
  38. ui/
  39. .gitignore
  40. .gitmodules
  41. a.out.h
  42. acl.c
  43. acl.h
  44. aes.c
  45. aes.h
  46. aio.c
  47. alpha-dis.c
  48. alpha.ld
  49. arch_init.c
  50. arch_init.h
  51. arm-dis.c
  52. arm-semi.c
  53. arm.ld
  54. async.c
  55. balloon.c
  56. balloon.h
  57. bitmap.c
  58. bitmap.h
  59. bitops.c
  60. bitops.h
  61. block-migration.c
  62. block-migration.h
  63. block.c
  64. block.h
  65. block_int.h
  66. blockdev.c
  67. blockdev.h
  68. bswap.h
  69. bt-host.c
  70. bt-host.h
  71. bt-vhci.c
  72. buffered_file.c
  73. buffered_file.h
  74. cache-utils.c
  75. cache-utils.h
  76. Changelog
  77. check-qdict.c
  78. check-qfloat.c
  79. check-qint.c
  80. check-qjson.c
  81. check-qlist.c
  82. check-qstring.c
  83. cmd.c
  84. cmd.h
  85. CODING_STYLE
  86. compatfd.c
  87. compatfd.h
  88. compiler.h
  89. config.h
  90. configure
  91. console.c
  92. console.h
  93. COPYING
  94. COPYING.LIB
  95. coroutine-ucontext.c
  96. coroutine-win32.c
  97. cpu-all.h
  98. cpu-common.h
  99. cpu-defs.h
  100. cpu-exec.c
  101. cpus.c
  102. cpus.h
  103. cris-dis.c
  104. cursor.c
  105. cursor_hidden.xpm
  106. cursor_left_ptr.xpm
  107. cutils.c
  108. def-helper.h
  109. device_tree.c
  110. device_tree.h
  111. dis-asm.h
  112. disas.c
  113. disas.h
  114. dma-helpers.c
  115. dma.h
  116. dyngen-exec.h
  117. elf.h
  118. envlist.c
  119. envlist.h
  120. error.c
  121. error.h
  122. error_int.h
  123. exec-all.h
  124. exec-memory.h
  125. exec.c
  126. gdbstub.c
  127. gdbstub.h
  128. gen-icount.h
  129. HACKING
  130. hmp-commands.hx
  131. host-utils.c
  132. host-utils.h
  133. hpet.h
  134. hppa-dis.c
  135. hppa.ld
  136. i386-dis.c
  137. i386.ld
  138. ia64-dis.c
  139. ia64.ld
  140. input.c
  141. iohandler.c
  142. ioport-user.c
  143. ioport.c
  144. ioport.h
  145. iorange.h
  146. iov.c
  147. iov.h
  148. json-lexer.c
  149. json-lexer.h
  150. json-parser.c
  151. json-parser.h
  152. json-streamer.c
  153. json-streamer.h
  154. kvm-all.c
  155. kvm-stub.c
  156. kvm.h
  157. libfdt_env.h
  158. LICENSE
  159. linux-aio.c
  160. m68k-dis.c
  161. m68k-semi.c
  162. m68k.ld
  163. MAINTAINERS
  164. Makefile
  165. Makefile.dis
  166. Makefile.hw
  167. Makefile.objs
  168. Makefile.target
  169. Makefile.user
  170. memory.c
  171. memory.h
  172. microblaze-dis.c
  173. migration-exec.c
  174. migration-fd.c
  175. migration-tcp.c
  176. migration-unix.c
  177. migration.c
  178. migration.h
  179. mips-dis.c
  180. mips.ld
  181. module.c
  182. module.h
  183. monitor.c
  184. monitor.h
  185. nbd.c
  186. nbd.h
  187. net.c
  188. net.h
  189. notify.c
  190. notify.h
  191. os-posix.c
  192. os-win32.c
  193. osdep.c
  194. osdep.h
  195. oslib-posix.c
  196. oslib-win32.c
  197. path.c
  198. pci-ids.txt
  199. pflib.c
  200. pflib.h
  201. poison.h
  202. posix-aio-compat.c
  203. ppc-dis.c
  204. ppc.ld
  205. ppc64.ld
  206. qapi-schema-guest.json
  207. qapi-schema-test.json
  208. qbool.c
  209. qbool.h
  210. qdict-test-data.txt
  211. qdict.c
  212. qdict.h
  213. qemu-aio.h
  214. qemu-barrier.h
  215. qemu-char.c
  216. qemu-char.h
  217. qemu-common.h
  218. qemu-config.c
  219. qemu-config.h
  220. qemu-coroutine-int.h
  221. qemu-coroutine.c
  222. qemu-coroutine.h
  223. qemu-doc.texi
  224. qemu-error.c
  225. qemu-error.h
  226. qemu-ga.c
  227. qemu-img-cmds.hx
  228. qemu-img.c
  229. qemu-img.texi
  230. qemu-io.c
  231. qemu-lock.h
  232. qemu-log.h
  233. qemu-malloc.c
  234. qemu-nbd.c
  235. qemu-nbd.texi
  236. qemu-objects.h
  237. qemu-option.c
  238. qemu-option.h
  239. qemu-options.h
  240. qemu-options.hx
  241. qemu-os-posix.h
  242. qemu-os-win32.h
  243. qemu-progress.c
  244. qemu-queue.h
  245. qemu-sockets.c
  246. qemu-tech.texi
  247. qemu-thread-posix.c
  248. qemu-thread-posix.h
  249. qemu-thread-win32.c
  250. qemu-thread-win32.h
  251. qemu-thread.h
  252. qemu-timer-common.c
  253. qemu-timer.c
  254. qemu-timer.h
  255. qemu-tool.c
  256. qemu-x509.h
  257. qemu.sasl
  258. qemu_socket.h
  259. qerror.c
  260. qerror.h
  261. qfloat.c
  262. qfloat.h
  263. qint.c
  264. qint.h
  265. qjson.c
  266. qjson.h
  267. qlist.c
  268. qlist.h
  269. qmp-commands.hx
  270. qobject.h
  271. qstring.c
  272. qstring.h
  273. range.h
  274. readline.c
  275. readline.h
  276. README
  277. rules.mak
  278. rwhandler.c
  279. rwhandler.h
  280. s390-dis.c
  281. s390.ld
  282. savevm.c
  283. sh4-dis.c
  284. simpletrace.c
  285. simpletrace.h
  286. softmmu-semi.h
  287. softmmu_defs.h
  288. softmmu_exec.h
  289. softmmu_header.h
  290. softmmu_template.h
  291. sparc-dis.c
  292. sparc.ld
  293. sparc64.ld
  294. spice-qemu-char.c
  295. sysemu.h
  296. targphys.h
  297. tcg-runtime.c
  298. test-qmp-commands.c
  299. test-visitor.c
  300. thunk.c
  301. thunk.h
  302. TODO
  303. trace-events
  304. translate-all.c
  305. uboot_image.h
  306. usb-bsd.c
  307. usb-linux.c
  308. usb-redir.c
  309. usb-stub.c
  310. user-exec.c
  311. VERSION
  312. version.rc
  313. vgafont.h
  314. vl.c
  315. x86_64.ld
  316. xen-all.c
  317. xen-mapcache.c
  318. xen-mapcache.h
  319. xen-stub.c