lco.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /* lco: a coroutine library for C that minimalises stack usage
  2. Copyright (C) 2018 Ariadne Devos
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /* This library allows you to use coroutines in C, without the possibility of
  15. stack overflow.
  16. Symbol interposition and indirect calls are not (yet) supported. The former
  17. causes breakage, the latter error messages from lco-coroutine.
  18. */
  19. struct lco_position
  20. {
  21. /* Internal; the stack pointer is saved here. */
  22. void *_sp;
  23. };
  24. struct lco_coroutine;
  25. typedef void lco_coroutine_entry(struct lco_coroutine *);
  26. /* Do not reorder this structure! Assembly code depends on its layout. */
  27. struct lco_coroutine
  28. {
  29. /* The coroutine starts with this function. */
  30. lco_coroutine_entry *entry;
  31. /* The size stack_array must have. */
  32. size_t stack_size;
  33. /* May be used by entry. */
  34. void *data_for_entry;
  35. char *stack_array;
  36. struct lco_position pos;
  37. void *_padding[3];
  38. };
  39. /* You cannot directly define a struct lco_coroutine, because you cannot
  40. know the required stack size within C. You need to use a tool for this.
  41. lco-stackbounds a.o b.o ... | lco-coroutine --init coroutines_init --extern lcl_puts input=f parse=g ... - > coroutines.c
  42. Declaration must be of form struct lco_coroutine input.
  43. Often, there is a dependency on an external library, whose stack bounds may
  44. change over time. If so, an argument --init f is required, which will create
  45. a function to set the stack bounds to agree with the library. This f must
  46. be called *after* the library's initialisation code has been called.
  47. Functions defined elsewhere, e.g. in an external library, must be declared
  48. with --extern f.
  49. To make the stack bounds of a function available for initialisation
  50. functions, e.g. in case of a shared library, add an argument --export f.
  51. --export f will create a symbol size_t f_SB.
  52. --extern f may create a reference to size_t f_SB.
  53. */
  54. #if defined(__x86_64)
  55. # define LCO_STACK_ALIGNMENT 16
  56. #else
  57. # error Do not know the stack aligment for your architecture!
  58. #endif
  59. /* An unprepared coroutine without a stack may be copied with memcpy. */
  60. /* Allocate a stack for co. There must be no stack when it is called.
  61. Returns co if successful, 0 in case of a memory allocation failure.
  62. To deallocate, pair with lco_free_stack(co).
  63. You may also use your own allocation functions.
  64. */
  65. _Bool
  66. lco_alloc_stack(struct lco_coroutine *co);
  67. /* Free the stack of co. co must be inactive and will need a new stack.
  68. The stack must have been allocated with lco_alloc_stack(co).
  69. Double frees are not allowed. The stack is set to NULL.
  70. You may also use your own allocation functions.
  71. */
  72. void
  73. lco_free_stack(struct lco_coroutine *co);
  74. /* Prepare co for starting for the first time. It must have a stack. */
  75. void
  76. lco_init(struct lco_coroutine *co);
  77. /* The OS might not like coroutines migrating from one thread to another.
  78. Even if it is allowed, memory consistency has not been though out.
  79. Summary: multithreading is allowed, but keep coroutines local to a thread,
  80. or make changes to this library (documentation and code) such that it is
  81. well-defined (patches are welcome).
  82. */
  83. /* By default, the OS (at least, the Linux kernel) lets the application handle
  84. signals on the current stack. That is incompatible with the limited stack
  85. size of lco coroutines. You need to set an alternate signal stack if signals
  86. might be delivered.
  87. You can use coroutines from within the signal handler, but these must be
  88. local to the current invocation of the signal handler, as if it were a
  89. thread.
  90. This function configures a signal stack, if applicable, for the current
  91. thread. You can also use sigaltstack.
  92. Array must be aligned to LCO_STACK_ALIGNMENT.
  93. */
  94. void
  95. lco_auto_sigaltstack(size_t size, char *array);
  96. /* If all you need is setting some flags or writing a few bytes to a pipe,
  97. this should be plenty. This constant will not decrease.
  98. TODO: figure out how to automate selecting a minimal sigalt stack size.
  99. Might require working around the C library.
  100. */
  101. #define LCO_PROPOSED_SIGALTSTACK 4096
  102. /* co must be inactive. Let it start, and pause the current coroutine.
  103. co->position is modified.
  104. current->position is modified.
  105. flags must be zero.
  106. */
  107. void
  108. lco_continue(struct lco_coroutine *co, struct lco_coroutine *current, unsigned long flags);
  109. /* co must be inactive. Let it start within the current OS thread.
  110. co->position is modified.
  111. *thread is modified.
  112. The coroutine can return to this function with lco_pause(co, thread, 0), but
  113. it doesn't have to.
  114. flags must be zero.
  115. */
  116. void
  117. lco_resume(struct lco_coroutine *co, struct lco_position *thread, unsigned long flags);
  118. /* Pause current and exit the call to lco_resume(current, thread, 0).
  119. current->position is modified.
  120. *thread is modified.
  121. flags must be zero.
  122. */
  123. void
  124. lco_pause(struct lco_coroutine *current, struct lco_position *thread, unsigned long flags);
  125. /* Overview:
  126. active a, inactive b -> inactive a, active b: lco_continue(a, b, 0).
  127. inactive co, active t -> active co, inactive t: lco_resume(co, t, 0).
  128. active co, inactive t -> inactive co, active t: lco_pause(co, t, 0).
  129. */