summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--docs/ccommon_api.md15
-rw-r--r--include/stc/algo/coroutine.h16
-rw-r--r--misc/examples/coroutines.c24
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);
}