summaryrefslogtreecommitdiff
path: root/coroutine.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2024-09-18 01:12:07 -0600
committerLuke T. Shumaker <lukeshu@lukeshu.com>2024-09-18 01:12:07 -0600
commit05ce08877ff420ca9fc77599dd947ff610d02cb0 (patch)
tree52ee0fbcd5ada2bb4725fce5c57f29863e17f7c9 /coroutine.c
parent52eb34af7be585c411a9a9ab39f0bea1d19e7d32 (diff)
fixes
Diffstat (limited to 'coroutine.c')
-rw-r--r--coroutine.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/coroutine.c b/coroutine.c
index 9e0920d..6219883 100644
--- a/coroutine.c
+++ b/coroutine.c
@@ -109,20 +109,26 @@ void coroutine_main(void) {
for (coroutine_running = 1;; coroutine_running = (coroutine_running%COROUTINE_NUM)+1) {
if (coroutine_running == 1)
ran = false;
- if (coroutine_table[coroutine_running-1].state == CR_RUNNABLE) {
- printf("running %zu...\n", coroutine_running);
+ struct coroutine *cr = &coroutine_table[coroutine_running-1];
+ if (cr->state == CR_RUNNABLE) {
ran = true;
- coroutine_table[coroutine_running-1].state = CR_RUNNING;
+ cr->state = CR_RUNNING;
if (!setjmp(coroutine_main_env)) { /* point=b */
- longjmp(coroutine_table[coroutine_running-1].env, 1); /* jump to point=c */
+ longjmp(cr->env, 1); /* jump to point=c */
assert(false); /* should cr_exit() instead of returning */
}
- if (coroutine_table[coroutine_running-1].state == CR_NONE) {
- free(coroutine_table[coroutine_running-1].stack);
+ if (cr->state == CR_NONE) {
+#if DEBUG
+ size_t stack_used = cr->stack_size;
+ while (stack_used > 0 && ((uint8_t*)cr->stack)[STACK_GROWS_DOWNWARD ? cr->stack_size - stack_used : stack_used - 1] == 0)
+ stack_used--;
+ printf("info: coroutine %zu exited having used %zu B stack space\n", coroutine_running, stack_used);
+#endif
+ free(cr->stack);
coroutine_table[coroutine_running-1] = (struct coroutine){0};
}
}
- if (coroutine_running == COROUTINE_NUM+1 && !ran) {
+ if (coroutine_running == COROUTINE_NUM && !ran) {
fprintf(stderr, "error: no runnable coroutines\n");
return;
}
@@ -136,17 +142,22 @@ bool cr_begin(void) {
longjmp(coroutine_add_env, 1); /* jump to point=a */
}
-static inline void _cr_transition(enum coroutine_state state) {
+static inline __attribute__ ((no_split_stack)) void _cr_transition(enum coroutine_state state) {
assert(coroutine_table[coroutine_running-1].state == CR_RUNNING);
coroutine_table[coroutine_running-1].state = state;
- if (state == CR_NONE || !setjmp(coroutine_table[coroutine_running-1].env)) /* point=c2 */
+ if (!setjmp(coroutine_table[coroutine_running-1].env)) /* point=c2 */
longjmp(coroutine_main_env, 1); /* jump to point=b */
}
-void cr_exit(void) { _cr_transition(CR_NONE); }
void cr_yield(void) { _cr_transition(CR_RUNNABLE); }
void cr_pause_and_yield(void) { _cr_transition(CR_PAUSED); }
+void cr_exit(void) {
+ assert(coroutine_table[coroutine_running-1].state == CR_RUNNING);
+ coroutine_table[coroutine_running-1].state = CR_NONE;
+ longjmp(coroutine_main_env, 1); /* jump to point=b */
+}
+
void cr_unpause(cid_t cid) {
assert(coroutine_table[cid-1].state == CR_PAUSED);
coroutine_table[cid-1].state = CR_RUNNABLE;