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