128 lines3.5 KB
Newer
Older
-
+
commited
{line.log.rev}
on
11 months ago
37
1
#include <stdio.h>
2
#include <stddef.h>
3
#include "coroutine.h"
4
#include "generator.h"
5
#include "asleep.h"
6
#include "task.h"
7
8
#include <dirent.h>
9
#include <string.h>
10
#include <stdlib.h>
11
#include <time.h>
Last month
12
#include <assert.h>
11 months ago
37
13
8 months ago
14
#define DEMO_STACK_SIZE (8192*sizeof(void *))
11 months ago
37
15
16
void *chaindeeper(void *param){
17
// enough headroom for printf on an Intel Mac - your system may be different
18
if (Coroutine_GetStackHeadroom() < 2000){
8 months ago
19
void *result;
2 months ago
20
bool fail = Coroutine_Chain(DEMO_STACK_SIZE, 0, chaindeeper, param, &result);
8 months ago
21
return fail ? NULL : result;
11 months ago
37
22
}
10 months ago
23
printf("%ld %ld\n", (long)param, Coroutine_GetStackHeadroom());
2 months ago
24
bool domore = Generator_Yield(param);
25
if (domore){
26
long depth = (long)param;
27
if (depth > 1000){
28
return NULL;
29
}
30
return chaindeeper((void *)(depth + 1));
11 months ago
37
31
}
2 months ago
32
return NULL;
11 months ago
37
33
}
34
35
36
void *chaintest(
37
void *param
38
){
39
(void)param;
40
2 months ago
41
// Need to run two coroutines so that at least one of their stacks is limited, and so
42
// needs to chain
43
Generator gen1;
44
Generator_ctor(&gen1, DEMO_STACK_SIZE, 0, chaindeeper, 0);
45
Generator gen2;
46
Generator_ctor(&gen2, DEMO_STACK_SIZE, 0, chaindeeper, 0);
47
void *param1;
48
void *param2;
49
while(Generator_Next(&gen1, &param1) && Generator_Next(&gen2, &param2)){
50
}
51
Generator_dtor(&gen2);
52
Generator_dtor(&gen1);
53
6 months ago
54
Coroutine_Report report = Coroutine_GetReport();
55
printf("%d routines using a pool of %d, min headroom %zu\n", report.coroutines_created, report.coroutines_pool_size, report.lowest_headroom);
11 months ago
37
56
57
return param;
58
}
59
Last month
60
void on_yield(void *param){
61
(void)param;
62
}
11 months ago
37
63
Last month
64
void *chaintest2_inner(
65
void *param
66
){
67
Coroutine *root = param;
68
Coroutine_Continue(root, NULL, true);
69
Coroutine_Yield((void *)456, on_yield, NULL);
70
assert(Coroutine_GetValue(root) == (void *)3);
71
return NULL;
72
}
73
74
void *chaintest2_outer(
75
void *param
76
){
77
Coroutine *root = param;
78
assert(Coroutine_GetValue(root) == (void *)1);
79
Coroutine_Continue(root, NULL, true);
80
Coroutine_Yield((void *)123, on_yield, NULL);
81
assert(Coroutine_GetValue(root) == (void *)2);
82
Coroutine_Chain(DEMO_STACK_SIZE, 0, chaintest2_inner, root, NULL);
83
Coroutine_Continue(root, NULL, true);
84
return (void *)789;
85
}
86
87
// This test checks the function of chaining:
88
// * Yielding inside a chained coroutine stores the value with
89
// the outermost/root coroutine of the chain.
90
// * Continuing the root coroutine of a chain continues the chain
91
// tip coroutine (ie the one which had yielded last)
92
void *chaintest2(
93
void *param
94
){
95
(void)param;
96
Coroutine *me = Coroutine_GetActive();
97
Coroutine *cor = Coroutine_New(DEMO_STACK_SIZE, 0, chaintest2_outer);
98
99
Coroutine_Continue(cor, me, true);
100
Coroutine_Yield((void *)1, on_yield, NULL);
101
assert(Coroutine_IsRunning(cor));
102
assert(Coroutine_GetValue(cor) == (void *)123);
103
104
Coroutine_Continue(cor, me, true);
105
Coroutine_Yield((void *)2, on_yield, NULL);
106
assert(Coroutine_IsRunning(cor));
107
assert(Coroutine_GetValue(cor) == (void *)456);
108
109
Coroutine_Continue(cor, me, true);
110
Coroutine_Yield((void *)3, on_yield, NULL);
111
assert(!Coroutine_IsRunning(cor));
112
assert(Coroutine_GetValue(cor) == (void *)789);
113
114
Coroutine_Delete(cor);
115
return NULL;
116
}
117
118
11 months ago
37
119
int main(int argc, char *argv[]) {
120
(void)argc;
121
(void)argv;
122
2 months ago
123
Coroutine_Run(DEMO_STACK_SIZE, 0, chaintest, NULL, NULL);
Last month
124
Coroutine_Run(DEMO_STACK_SIZE, 0, chaintest2, NULL, NULL);
11 months ago
37
125
6 months ago
126
return 0;
11 months ago
37
127
}
128