#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); }