diff options
| author | Tyge Løvset <[email protected]> | 2023-05-01 23:11:45 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-05-01 23:11:45 +0200 |
| commit | 399eb8d0e1de2839d826a9e0cf123d90d00b0018 (patch) | |
| tree | a8731f86aa779af8412ba77e4d27fa5e66b94cab | |
| parent | f916573e2b3652d9b3f6fb82aadd5f2cfb3ce2fe (diff) | |
| download | STC-modified-399eb8d0e1de2839d826a9e0cf123d90d00b0018.tar.gz STC-modified-399eb8d0e1de2839d826a9e0cf123d90d00b0018.zip | |
Replaced cco_yield(corocall, ctx, retval) with cco_await(cond) and cco_await_while(cond).
| -rw-r--r-- | docs/ccommon_api.md | 15 | ||||
| -rw-r--r-- | include/stc/algo/coroutine.h | 16 | ||||
| -rw-r--r-- | misc/examples/coroutines.c | 24 |
3 files changed, 25 insertions, 30 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 7a3c3196..549eff4e 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -355,15 +355,16 @@ To resume the coroutine from where it was suspended with *cco_yield()*, simply c | | `cco_final:` | Obligatory label in coroutine | | | `cco_return;` | Early return from the coroutine | | `bool` | `cco_alive(ctx)` | Is coroutine in initial or suspended state? | +| `bool` | `cco_done(ctx)` | Is coroutine not alive? | | `bool` | `cco_suspended(ctx)` | Is coroutine in suspended state? | | `void` | `cco_begin(ctx)` | Begin coroutine block | -| `rettype` | `cco_end(retval)` | End coroutine block with return value | -| `void` | `cco_end()` | End coroutine block | -| `rettype` | `cco_yield(retval)` | Suspend execution and return a value | -| `void` | `cco_yield()` | Suspend execution | -| `rettype` | `cco_yield(corocall2, ctx2, retval)` | Yield from another coroutine and return val | -| `void` | `cco_yield(corocall2, ctx2)` | Yield from another coroutine | -| | From the caller side: | | +| `rettype` | `cco_end(retval)` | End coroutine block and return retval | +| `void` | `cco_end()` | End coroutine block (return void) | +| `rettype` | `cco_yield(retval)` | Suspend execution and return retval | +| `void` | `cco_yield()` | Suspend execution (return void) | +| `rettype` | `cco_await_while(cond, retval)` | If cond, suspend execution and return retval | +| `bool` | `cco_await(cond)` | If not cond, suspend execution and return true | +| | From caller side: | | | `void` | `cco_stop(ctx)` | Next call of coroutine returns `cco_end()` | | `void` | `cco_reset(ctx)` | Reset state to initial (for reuse) | diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h index b0ecd6b7..6c1d7d28 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/algo/coroutine.h @@ -64,6 +64,7 @@ enum { #define cco_suspended(ctx) ((ctx)->cco_state > 0) #define cco_alive(ctx) ((ctx)->cco_state != cco_state_done) +#define cco_done(ctx) ((ctx)->cco_state == cco_state_done) #define cco_begin(ctx) \ int *_state = &(ctx)->cco_state; \ @@ -76,25 +77,20 @@ enum { } \ return retval -#define cco_yield(...) c_MACRO_OVERLOAD(cco_yield, __VA_ARGS__) -#define cco_yield_1(retval) \ +#define cco_yield(retval) \ do { \ *_state = __LINE__; return retval; \ case __LINE__:; \ } while (0) -#define cco_yield_2(corocall2, ctx2) \ - cco_yield_3(corocall2, ctx2, ) - -#define cco_yield_3(corocall2, ctx2, retval) \ +#define cco_await_while(cond, retval) \ do { \ *_state = __LINE__; \ - do { \ - corocall2; if (cco_suspended(ctx2)) return retval; \ - case __LINE__:; \ - } while (cco_alive(ctx2)); \ + case __LINE__: if (cond) return retval; \ } while (0) +#define cco_await(cond) cco_await_while(!(cond), true) + #define cco_final \ case cco_state_final: \ _cco_final_ diff --git a/misc/examples/coroutines.c b/misc/examples/coroutines.c index b11b8532..af9fef81 100644 --- a/misc/examples/coroutines.c +++ b/misc/examples/coroutines.c @@ -78,29 +78,27 @@ struct combined { int cco_state; }; + bool combined(struct combined* C) { cco_begin(C); - cco_yield(prime(&C->prm), &C->prm, true); - cco_yield(fibonacci(&C->fib), &C->fib, true); + cco_await(prime(&C->prm) == false); + cco_await(fibonacci(&C->fib) == false); // Reuse the C->prm context and extend the count: C->prm.count = 8; C->prm.result += 2; cco_reset(&C->prm); - cco_yield(prime(&C->prm), &C->prm, true); + cco_await(prime(&C->prm) == false); cco_final: puts("final comb"); cco_end(false); } -int main(void) { +int main(void) +{ struct combined comb = {.prm={.count=8}, .fib={14}}; - if (true) - while (combined(&comb)) - printf("Prime(%d)=%lld, Fib(%d)=%lld\n", - comb.prm.idx, (long long)comb.prm.result, - comb.fib.idx, (long long)comb.fib.result); - else - while (prime(&comb.prm)) - printf("Prime(%d)=%lld\n", - comb.prm.idx, (long long)comb.prm.result); + + while (combined(&comb)) + printf("Prime(%d)=%lld, Fib(%d)=%lld\n", + comb.prm.idx, (long long)comb.prm.result, + comb.fib.idx, (long long)comb.fib.result); } |
