diff options
author | Nicholas Noll <nbnoll@eml.cc> | 2020-04-17 18:31:34 -0700 |
---|---|---|
committer | Nicholas Noll <nbnoll@eml.cc> | 2020-04-17 18:31:34 -0700 |
commit | b7b3dece056794d7b840b71c25ad5ca5846cf231 (patch) | |
tree | 2871c90ccbce6c861c1835d4a79fe4672b4e1229 /src/coro.c | |
parent | dca72268ae6bcbd411aa8660604451226f76b4eb (diff) |
feat: added co-routines
Diffstat (limited to 'src/coro.c')
-rw-r--r-- | src/coro.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/coro.c b/src/coro.c new file mode 100644 index 0000000..4e651d3 --- /dev/null +++ b/src/coro.c @@ -0,0 +1,56 @@ +#include <u.h> + +// ----------------------------------------------------------------------- +// Assembly routines. + +extern void _newcoro(coro *co, uintptr (*func)(coro*, uintptr), void *stk); +extern uintptr _coroyield(coro *co, uintptr arg); + +struct coro +{ + void* sp; + void* bp; + uintptr size; + void* user; +}; + +coro* +coro·New(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 + { + GOOD, + NIL, + 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); +} |