qemu-coroutine.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * QEMU coroutines
  3. *
  4. * Copyright IBM, Corp. 2011
  5. *
  6. * Authors:
  7. * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
  8. * Kevin Wolf <kwolf@redhat.com>
  9. *
  10. * This work is licensed under the terms of the GNU LGPL, version 2 or later.
  11. * See the COPYING.LIB file in the top-level directory.
  12. *
  13. */
  14. #include "trace.h"
  15. #include "qemu-common.h"
  16. #include "block/coroutine.h"
  17. #include "block/coroutine_int.h"
  18. Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
  19. {
  20. Coroutine *co = qemu_coroutine_new();
  21. co->entry = entry;
  22. return co;
  23. }
  24. static void coroutine_swap(Coroutine *from, Coroutine *to)
  25. {
  26. CoroutineAction ret;
  27. ret = qemu_coroutine_switch(from, to, COROUTINE_YIELD);
  28. switch (ret) {
  29. case COROUTINE_YIELD:
  30. return;
  31. case COROUTINE_TERMINATE:
  32. trace_qemu_coroutine_terminate(to);
  33. qemu_coroutine_delete(to);
  34. return;
  35. default:
  36. abort();
  37. }
  38. }
  39. void qemu_coroutine_enter(Coroutine *co, void *opaque)
  40. {
  41. Coroutine *self = qemu_coroutine_self();
  42. trace_qemu_coroutine_enter(self, co, opaque);
  43. if (co->caller) {
  44. fprintf(stderr, "Co-routine re-entered recursively\n");
  45. abort();
  46. }
  47. co->caller = self;
  48. co->entry_arg = opaque;
  49. coroutine_swap(self, co);
  50. }
  51. void coroutine_fn qemu_coroutine_yield(void)
  52. {
  53. Coroutine *self = qemu_coroutine_self();
  54. Coroutine *to = self->caller;
  55. trace_qemu_coroutine_yield(self, to);
  56. if (!to) {
  57. fprintf(stderr, "Co-routine is yielding to no one\n");
  58. abort();
  59. }
  60. self->caller = NULL;
  61. coroutine_swap(self, to);
  62. }