1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
#include <u.h>
#include <libn.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);
}
|