1 contributor
123 lines4.3 KB
Newer
Older
-
+
commited
{line.log.rev}
on
8 months ago
1
#ifndef COROUTINE_H
2
#define COROUTINE_H
3
9 months ago
2
4
#include <stdbool.h>
5
8 months ago
6
///////////////////////////////////////////////////////////////////////////////
7
// Coroutine
8
//
9
// Coroutines for C, based on setjmp/longjmp.
10
// Thread safe - each thread has its own coroutine system
11
// Coroutines are cooperatively scheduled
12
// Coroutines have their own stack (currently 16K each)
13
// A coroutine can be continued, queried, or deleted on a different thread.
14
//
15
// Usage:
16
// Coroutine_StartSystem(); // call once per thread before using coroutines
17
// Coroutine *co = Coroutine_New(start_function);
18
// void *result = Coroutine_Run(co, initial_value);
19
// Coroutine_Delete(co);
20
// Coroutine_StopSystem(); // call once per thread when done with coroutines
21
//
22
// Inside the coroutine function:
23
// void *value = Coroutine_Yield(yield_value, on_yield, this);
24
// ...
25
// return return_value;
26
//
27
// To create a coroutine:
28
// Coroutine *co = Coroutine_New(start_function);
29
// To start or continue a coroutine:
30
// void *result = Coroutine_Continue(co, value, early);
31
// // early=true puts the coroutine at the head of the run queue
32
// // early=false puts the coroutine at the tail of the run queue
33
// To yield from inside a coroutine:
34
// void *value = Coroutine_Yield(yield_value, on_yield, this);
35
// // on_yield is called before the next coroutine is run
36
// // 'this' is passed to on_yield as its parameter
37
// // value is the value passed to Coroutine_Continue
38
// To delete a coroutine:
39
// Coroutine_Delete(co);
40
// To get the value yielded from, or returned by a corotuine:
41
// void *value = Coroutine_GetValue(co);
42
// To get the currently running coroutine (NULL if none):
43
// Coroutine *co = Coroutine_GetActive();
44
// To check if a coroutine is currently running:
45
// bool running = Coroutine_IsRunning(co);
46
//
47
// Notes:
48
// Coroutine is not expected to be used directly, but as a foundation for
49
// higher level constructs such as Generators, Async, etc.
50
//
51
///////////////////////////////////////////////////////////////////////////////
52
53
54
// The stack is used as follows:
55
// +------------------+ <- stack top
56
// | coroutine header | <- more claimed as needed in Coroutine_New
57
// +------------------+ <-
58
// | coroutine stack | <-
59
// +------------------+ <-
60
// | coroutine header |
61
// +------------------+
62
// | coroutine stack |
63
// +------------------+
64
// | coroutine header |
65
// +------------------+
66
// | coroutine stack |
67
// +------------------+
68
// | coroutine header |
69
// +------------------+
70
// | coroutine stack |
71
// +------------------+
72
// | coroutine header |
73
// +------------------+
74
// | startup space | <- set aside by Coroutine_StartSystem
75
// +------------------+
76
// | caller | <- This calls Coroutine_StartSystem etc
77
// +------------------+
78
// | used stack |
79
// +------------------+ <- stack bottom
80
81
// Each coroutine has this much stack:
8 months ago
82
#ifndef COROUTINE_STACK_SIZE
83
#define COROUTINE_STACK_SIZE 65536
84
#endif
8 months ago
85
8 months ago
86
// When Coroutine is started, an amount of stack is set aside to give
8 months ago
87
// the caller of Coroutine_StartSystem a bit of room to work before calling
88
// Coroutine_Run(), that is this amount:
8 months ago
89
#ifndef COROUTINE_STARTUP_STACK_SIZE
90
#define COROUTINE_STARTUP_STACK_SIZE 4096
91
#endif
8 months ago
92
8 months ago
93
// Returned by Coroutine_StopSystem(), this summarises the coroutine session
94
typedef struct Coroutine_Report {
95
unsigned coroutines_created;
96
unsigned coroutines_pool_size;
97
unsigned lowest_headroom;
98
} Coroutine_Report;
99
9 months ago
2
100
typedef struct Coroutine Coroutine;
101
8 months ago
102
typedef void (*Coroutine_YieldCallback)(void *me);
9 months ago
2
103
typedef void *(*Coroutine_Start)(void *);
104
105
void Coroutine_StartSystem();
8 months ago
106
Coroutine_Report Coroutine_StopSystem();
8 months ago
107
Coroutine *Coroutine_New(Coroutine_Start start);
8 months ago
108
void Coroutine_Run_Coroutine(Coroutine *cor, void *value);
8 months ago
109
void *Coroutine_Run(Coroutine_Start start, void *value);
9 months ago
2
110
void Coroutine_Delete(Coroutine *cor);
111
void Coroutine_Continue(Coroutine *cor, void *value, bool early);
8 months ago
112
void *Coroutine_Yield(void *value, Coroutine_YieldCallback on_yield, void *me);
9 months ago
2
113
void *Coroutine_GetValue(Coroutine *cor);
114
Coroutine *Coroutine_GetActive();
8 months ago
115
int Coroutine_GetStackHeadroom();
116
bool Coroutine_HasCoroutinesInFreePool();
117
void *Coroutine_GetCStackTop();
118
void *Coroutine_Chain(Coroutine_Start start, void *value);
8 months ago
119
bool Coroutine_IsStarted();
9 months ago
2
120
bool Coroutine_IsRunning(Coroutine *cor);
8 months ago
121
122
#endif
123