diff options
| author | Tyge Løvset <[email protected]> | 2023-02-26 20:16:01 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-02-26 20:16:01 +0100 |
| commit | 1871ee8e9b4ca4edde387be973035c259fc9191f (patch) | |
| tree | 1efe5529a46099d61fd1ae7b89f15f08b78064bf | |
| parent | 00313bfa4f448253ac95640ed962130ec3d14b19 (diff) | |
| download | STC-modified-1871ee8e9b4ca4edde387be973035c259fc9191f.tar.gz STC-modified-1871ee8e9b4ca4edde387be973035c259fc9191f.zip | |
Addition to coroutine.h. Allow dynamic allocation of context.
| -rw-r--r-- | include/stc/algo/coroutine.h | 26 | ||||
| -rw-r--r-- | misc/examples/coread.c | 2 | ||||
| -rw-r--r-- | misc/examples/coroutines.c | 16 |
3 files changed, 29 insertions, 15 deletions
diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h index 4ba39e63..7ea53a0c 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/algo/coroutine.h @@ -61,14 +61,15 @@ int main(void) { #include <stc/ccommon.h> #define cco_begin(c) \ - int* _state = &(c)->cco_state; \ - switch (*_state) { \ + int *_state = &(c)->cco_state, _nodyn; \ + switch (*_state) { \ case 0: #define cco_end() \ *_state = 0; break; \ default: assert(!"missing cco_final: or illegal state"); \ - } *_state *= -1 + } \ + *_state *= -1; (void)_nodyn #define cco_yield(retval) \ do { \ @@ -84,7 +85,22 @@ int main(void) { } while (0) #define cco_final case -1 -#define cco_alive(c) ((c)->cco_state > 0) -#define cco_stop(c) ((c)->cco_state = cco_alive(c) ? -1 : -2, c) +#define cco_alive(c) ((c) && (c)->cco_state > 0) +#define cco_stop(c) ((c)->cco_state = (c)->cco_state ? -1 : -2, c) + +// --------------------------------------------------------------- + +#define cco_begin_dyn(cp) \ + if (!*(cp)) *(cp) = malloc(sizeof **(cp)), (*(cp))->cco_state = 0; \ + int* _state = &(*(cp))->cco_state, _dyn; \ + switch (*_state) { \ + case 0: + +#define cco_end_dyn(cp) \ + *_state = 0; break; \ + default: assert(!"missing cco_final: or illegal state"); \ + } \ + *_state *= -1; (void)_dyn; \ + free(*(cp)); *(cp) = NULL #endif diff --git a/misc/examples/coread.c b/misc/examples/coread.c index 89e06b71..3d49c5df 100644 --- a/misc/examples/coread.c +++ b/misc/examples/coread.c @@ -35,7 +35,7 @@ int main(void) { printf("%3d %s\n", ++n, cstr_str(&z.line)); // stop after 15 lines: - if (n == 15) cco_stop(&z); + if (n == 15) (void)cco_stop(&z); } printf("state %d\n", z.cco_state); } diff --git a/misc/examples/coroutines.c b/misc/examples/coroutines.c index 120f11b8..66a1275e 100644 --- a/misc/examples/coroutines.c +++ b/misc/examples/coroutines.c @@ -4,15 +4,13 @@ // Use coroutine to create a fibonacci sequence generator: -typedef long long intll_t; - struct fibonacci { int n; int cco_state; - intll_t a, b, idx; + int64_t a, b, idx; }; -intll_t fibonacci(struct fibonacci* F) { +int64_t fibonacci(struct fibonacci* F) { assert (F->n < 95); cco_begin(F); @@ -20,7 +18,7 @@ intll_t fibonacci(struct fibonacci* F) { F->b = 1; for (F->idx = 0; F->idx < F->n; F->idx++) { cco_yield(F->a); - intll_t sum = F->a + F->b; // NB! locals only lasts until next cco_yield! + int64_t sum = F->a + F->b; // NB! locals only lasts until next cco_yield! F->a = F->b; F->b = sum; } @@ -50,16 +48,16 @@ bool iterate(struct iterate* I, struct fibonacci* F) { } } cco_final: + puts("final"); cco_end(); return false; } int main(void) { - printf("Fibonacci numbers:\n"); struct fibonacci fib = {.n = 14}; - struct iterate iter = {3, 3}; + struct iterate it = {3, 3}; - while (iterate(&iter, &fib)) - printf("%d %d. Fib: %lld\n", iter.x, iter.y, fib.a); + while (iterate(&it, &fib)) + printf("Iter=(%d, %d). Fib=%lld\n", it.x, it.y, (long long)fib.a); } |
