]> git.ozlabs.org Git - ccan/blob - ccan/coroutine/test/api-2.c
coroutine: Stack allocation
[ccan] / ccan / coroutine / test / api-2.c
1 #include <stdlib.h>
2
3 #include <ccan/coroutine/coroutine.h>
4 #include <ccan/tap/tap.h>
5
6 struct state {
7         struct coroutine_state c1, c2;
8         struct coroutine_state master;
9         int val;
10 };
11
12 static void f1(void *p)
13 {
14         struct state *state = (struct state *)p;
15
16         coroutine_switch(&state->c1, &state->c2);
17
18         ok(state->val == 17, "state->val == %d [expected 17]", state->val);
19         state->val = 23;
20
21         coroutine_switch(&state->c1, &state->c2);
22
23         ok(state->val == 24, "state->val == %d [expected 24]", state->val);
24
25         coroutine_switch(&state->c1, &state->c2);
26
27         ok(state->val == 26, "state->val == %d [expected 26]", state->val);
28
29         coroutine_switch(&state->c1, &state->c2);
30
31         ok(state->val == 29, "state->val == %d [expected 29]", state->val);
32
33         coroutine_switch(&state->c1, &state->c2);
34 }
35
36 static void f2(void *p)
37 {
38         struct state *state = (struct state *)p;
39
40         state->val = 17;
41
42         coroutine_switch(&state->c2, &state->c1);
43
44         ok(state->val == 23, "state->val == %d [expected 23]", state->val);
45         state->val += 1;
46
47         coroutine_switch(&state->c2, &state->c1);
48
49         state->val += 2;
50
51         coroutine_switch(&state->c2, &state->c1);
52
53         state->val += 3;
54
55         coroutine_switch(&state->c2, &state->c1);
56
57         coroutine_jump(&state->master);
58 }
59
60 static void test1(size_t bufsz)
61 {
62         struct coroutine_stack *stack1, *stack2;
63
64         stack1 = coroutine_stack_alloc(bufsz, 0);
65         ok1(coroutine_stack_check(stack1, NULL) == stack1);
66         ok1(coroutine_stack_size(stack1) == bufsz - COROUTINE_STK_OVERHEAD);
67
68         stack2 = coroutine_stack_alloc(bufsz, 0);
69         ok1(coroutine_stack_check(stack2, NULL) == stack2);
70         ok1(coroutine_stack_size(stack2) == bufsz - COROUTINE_STK_OVERHEAD);
71
72         if (COROUTINE_AVAILABLE) {
73                 struct state s;
74
75                 coroutine_init(&s.c1, f1, &s, stack1);
76                 coroutine_init(&s.c2, f2, &s, stack2);
77
78                 coroutine_switch(&s.master, &s.c1);
79         } else {
80                 skip(5, "Coroutines not available");
81         }
82
83         ok(1, "Completed test1");
84
85         coroutine_stack_release(stack1, 0);
86         coroutine_stack_release(stack2, 0);
87 }
88
89
90 int main(void)
91 {
92         /* This is how many tests you plan to run */
93         plan_tests(10);
94
95         test1(8192);
96
97         /* This exits depending on whether all tests passed */
98         return exit_status();
99 }