From a58ed62a1677ab31de8ca63ba9cdb4694ae608fe Mon Sep 17 00:00:00 2001 From: theMackabu Date: Fri, 17 Apr 2026 12:19:12 -0700 Subject: [PATCH] migrate coro to a linked list --- include/sugar.h | 2 ++ src/modules/generator.c | 6 ++++++ src/silver/ops/async.h | 12 +++++++++--- src/sugar.c | 16 ++++++++++++++-- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/include/sugar.h b/include/sugar.h index 52e66ff..e969dcc 100644 --- a/include/sugar.h +++ b/include/sugar.h @@ -59,6 +59,8 @@ typedef struct coroutine { ant_value_t async_promise; struct coroutine *active_parent; + struct coroutine *active_prev; + struct coroutine *prev; struct coroutine *next; diff --git a/src/modules/generator.c b/src/modules/generator.c index ba3a467..a20574c 100644 --- a/src/modules/generator.c +++ b/src/modules/generator.c @@ -361,6 +361,9 @@ static ant_value_t generator_resume_kind( coroutine_t *saved_active = js->active_async_coro; coro->active_parent = saved_active; + coro->active_prev = NULL; + + if (saved_active) saved_active->active_prev = coro; js->active_async_coro = coro; coroutine_hold(coro, CORO_HOLD_ACTIVE); @@ -382,7 +385,10 @@ static ant_value_t generator_resume_kind( GC_ROOT_PIN(js, result); js->active_async_coro = saved_active; + if (saved_active) saved_active->active_prev = NULL; + coro->active_parent = NULL; + coro->active_prev = NULL; coroutine_unhold(coro, CORO_HOLD_ACTIVE); if (is_err(result)) { diff --git a/src/silver/ops/async.h b/src/silver/ops/async.h index 4e6f396..7369f36 100644 --- a/src/silver/ops/async.h +++ b/src/silver/ops/async.h @@ -103,14 +103,22 @@ typedef struct { static inline void sv_async_link_activation(ant_t *js, coroutine_t *coro) { if (!js || !coro) return; coro->active_parent = js->active_async_coro; + coro->active_prev = NULL; + + if (js->active_async_coro) js->active_async_coro->active_prev = coro; js->active_async_coro = coro; coroutine_hold(coro, CORO_HOLD_ACTIVE); } static inline void sv_async_unlink_activation(ant_t *js, coroutine_t *coro) { if (!js || !coro) return; - if (js->active_async_coro == coro) js->active_async_coro = coro->active_parent; + + if (coro->active_prev) coro->active_prev->active_parent = coro->active_parent; + else if (js->active_async_coro == coro) js->active_async_coro = coro->active_parent; + if (coro->active_parent) coro->active_parent->active_prev = coro->active_prev; + coro->active_parent = NULL; + coro->active_prev = NULL; coroutine_unhold(coro, CORO_HOLD_ACTIVE); } @@ -649,8 +657,6 @@ static inline ant_value_t sv_start_async_closure( return promise; } - - static inline sv_await_result_t sv_await_value(sv_vm_t *vm, ant_t *js, ant_value_t value) { sv_await_result_t out = { .state = SV_AWAIT_READY, diff --git a/src/sugar.c b/src/sugar.c index 1164b18..1306196 100644 --- a/src/sugar.c +++ b/src/sugar.c @@ -199,22 +199,34 @@ static void resume_coroutine_if_suspended(ant_t *js, coroutine_t *coro) { coro->sv_vm->suspended_resume_pending = true; coro->active_parent = js->active_async_coro; + coro->active_prev = NULL; + if (js->active_async_coro) js->active_async_coro->active_prev = coro; + js->active_async_coro = coro; coroutine_hold(coro, CORO_HOLD_ACTIVE); ant_value_t result = sv_resume_suspended(coro->sv_vm); coro->is_settled = false; if (coro->sv_vm->suspended) { - js->active_async_coro = coro->active_parent; + if (coro->active_prev) coro->active_prev->active_parent = coro->active_parent; + else if (js->active_async_coro == coro) js->active_async_coro = coro->active_parent; + if (coro->active_parent) coro->active_parent->active_prev = coro->active_prev; + coro->active_parent = NULL; + coro->active_prev = NULL; coroutine_unhold(coro, CORO_HOLD_ACTIVE); if (generator_resume_pending_request(js, coro, result)) return; coroutine_release(coro); + return; } - js->active_async_coro = coro->active_parent; + if (coro->active_prev) coro->active_prev->active_parent = coro->active_parent; + else if (js->active_async_coro == coro) js->active_async_coro = coro->active_parent; + if (coro->active_parent) coro->active_parent->active_prev = coro->active_prev; + coro->active_parent = NULL; + coro->active_prev = NULL; coroutine_unhold(coro, CORO_HOLD_ACTIVE); if (generator_resume_pending_request(js, coro, result)) { -- 2.51.2