From c8e1e71eb526475dd431443345262c2e5a627831 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Sat, 23 Oct 2021 11:17:25 -0700 Subject: chore(rename): libn -> base --- sys/base/coro.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 sys/base/coro.c (limited to 'sys/base/coro.c') diff --git a/sys/base/coro.c b/sys/base/coro.c new file mode 100644 index 0000000..953dee0 --- /dev/null +++ b/sys/base/coro.c @@ -0,0 +1,66 @@ +#include +#include + +// ----------------------------------------------------------------------- +// Assembly routines + +extern void _newcoro(Coro *co, uintptr (*func)(Coro*, uintptr), void *stk); +extern uintptr _coroyield(Coro *co, uintptr arg); + +// ----------------------------------------------------------------------- +// Globals + +// static thread_local coro *CONTEXT; + +// ----------------------------------------------------------------------- +// C interface + +/* Co-routine context */ +struct Coro +{ + void* sp; + void* bp; + uintptr size; + void* user; +}; + +Coro* +coro·make(uintptr stk, uintptr (*func)(Coro*, uintptr)) +{ + if (!func) return nil; + if (stk == 0) stk = 8192; + + byte *block = malloc(stk); + Coro *co = (Coro*)&block[stk - sizeof(Coro)]; + co->bp = block; + co->size = stk; + + _newcoro(co, func, co); + return co; +} + +error +coro·free(Coro *co) +{ + enum + { + NIL, + GOOD, + EMPTY, + LOST, + }; + + if (!co) return NIL; + if (!co->bp) return LOST; + if (co->size == 0) return EMPTY; + + free(co->bp); + + return GOOD; +} + +uintptr +coro·yield(Coro *c, uintptr arg) +{ + return _coroyield(c, arg); +} -- cgit v1.2.1