diff options
author | Nicholas Noll <nnoll523@gmail.com> | 2021-10-23 11:17:25 -0700 |
---|---|---|
committer | Nicholas Noll <nnoll523@gmail.com> | 2021-10-26 11:11:57 -0700 |
commit | c8e1e71eb526475dd431443345262c2e5a627831 (patch) | |
tree | ea9f7bcbba18a13f7ba8b32fcb1433ac2f4dd8b4 /sys/base/coro.c | |
parent | 40f4c7305a041d4214df117491593898d04d0134 (diff) |
chore(rename): libn -> base
Diffstat (limited to 'sys/base/coro.c')
-rw-r--r-- | sys/base/coro.c | 66 |
1 files changed, 66 insertions, 0 deletions
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 <u.h> +#include <base.h> + +// ----------------------------------------------------------------------- +// 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); +} |