summaryrefslogtreecommitdiffhomepage
path: root/misc/examples
diff options
context:
space:
mode:
Diffstat (limited to 'misc/examples')
-rw-r--r--misc/examples/cointerleave.c60
-rw-r--r--misc/examples/coread.c14
-rw-r--r--misc/examples/coroutines.c20
-rw-r--r--misc/examples/scheduler.c76
-rw-r--r--misc/examples/triples.c8
5 files changed, 157 insertions, 21 deletions
diff --git a/misc/examples/cointerleave.c b/misc/examples/cointerleave.c
new file mode 100644
index 00000000..64473d96
--- /dev/null
+++ b/misc/examples/cointerleave.c
@@ -0,0 +1,60 @@
+// https://www.youtube.com/watch?v=8sEe-4tig_A
+#include <stc/calgo.h>
+#include <stdio.h>
+#define i_type IVec
+#define i_val int
+#include <stc/cvec.h>
+
+struct GenValue {
+ IVec *v;
+ IVec_iter it;
+ int cco_state;
+};
+
+static int next_value(struct GenValue* g)
+{
+ cco_begin(g);
+ for (g->it = IVec_begin(g->v); g->it.ref; IVec_next(&g->it))
+ cco_yield(*g->it.ref);
+ cco_final:
+ cco_end(0);
+}
+
+struct Generator {
+ struct GenValue x, y;
+ int cco_state;
+ int value;
+};
+
+bool interleaved(struct Generator* g)
+{
+ cco_begin(g);
+ while (cco_alive(&g->x) || cco_alive(&g->y))
+ {
+ g->value = next_value(&g->x);
+ if (cco_alive(&g->x)) cco_yield(false);
+
+ g->value = next_value(&g->y);
+ if (cco_alive(&g->y)) cco_yield(false);
+ }
+ cco_final:
+ cco_end(true);
+}
+
+void Use(void)
+{
+ IVec a = c_make(IVec, {2, 4, 6, 8, 10, 11});
+ IVec b = c_make(IVec, {3, 5, 7, 9});
+
+ struct Generator g = {{&a}, {&b}};
+
+ while (!interleaved(&g))
+ printf("%d\n", g.value);
+
+ c_drop(IVec, &a, &b);
+}
+
+int main()
+{
+ Use();
+}
diff --git a/misc/examples/coread.c b/misc/examples/coread.c
index 0a7f4816..d5385a87 100644
--- a/misc/examples/coread.c
+++ b/misc/examples/coread.c
@@ -4,36 +4,36 @@
// Read file line by line using coroutines:
-struct file_nextline {
+struct file_read {
const char* filename;
int cco_state;
FILE* fp;
cstr line;
};
-bool file_nextline(struct file_nextline* U)
+bool file_read(struct file_read* U)
{
cco_begin(U)
U->fp = fopen(U->filename, "r");
U->line = cstr_init();
while (cstr_getline(&U->line, U->fp))
- cco_yield(true);
+ cco_yield(false);
cco_final: // this label is required.
printf("finish\n");
cstr_drop(&U->line);
fclose(U->fp);
- cco_end(false);
+ cco_end(true);
}
int main(void)
{
- struct file_nextline it = {__FILE__};
+ struct file_read g = {__FILE__};
int n = 0;
- while (file_nextline(&it))
+ while (!file_read(&g))
{
- printf("%3d %s\n", ++n, cstr_str(&it.line));
+ printf("%3d %s\n", ++n, cstr_str(&g.line));
//if (n == 10) cco_stop(&it);
}
}
diff --git a/misc/examples/coroutines.c b/misc/examples/coroutines.c
index af9fef81..3fddf913 100644
--- a/misc/examples/coroutines.c
+++ b/misc/examples/coroutines.c
@@ -23,7 +23,7 @@ bool prime(struct prime* U) {
if (U->result == 2) {
if (U->count-- == 0) cco_return;
++U->idx;
- cco_yield(true);
+ cco_yield(false);
}
U->result += !(U->result & 1);
for (U->pos = U->result; U->count > 0; U->pos += 2) {
@@ -31,12 +31,12 @@ bool prime(struct prime* U) {
--U->count;
++U->idx;
U->result = U->pos;
- cco_yield(true);
+ cco_yield(false);
}
}
cco_final:
printf("final prm\n");
- cco_end(false);
+ cco_end(true);
}
@@ -63,11 +63,11 @@ bool fibonacci(struct fibonacci* F) {
F->result = F->b;
F->b = sum;
}
- cco_yield(true);
+ cco_yield(false);
}
cco_final:
printf("final fib\n");
- cco_end(false);
+ cco_end(true);
}
// Combine
@@ -81,23 +81,23 @@ struct combined {
bool combined(struct combined* C) {
cco_begin(C);
- cco_await(prime(&C->prm) == false);
- cco_await(fibonacci(&C->fib) == false);
+ cco_await(prime(&C->prm));
+ cco_await(fibonacci(&C->fib));
// Reuse the C->prm context and extend the count:
C->prm.count = 8; C->prm.result += 2;
cco_reset(&C->prm);
- cco_await(prime(&C->prm) == false);
+ cco_await(prime(&C->prm));
cco_final: puts("final comb");
- cco_end(false);
+ cco_end(true);
}
int main(void)
{
struct combined comb = {.prm={.count=8}, .fib={14}};
- while (combined(&comb))
+ 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);
diff --git a/misc/examples/scheduler.c b/misc/examples/scheduler.c
new file mode 100644
index 00000000..1809f2ec
--- /dev/null
+++ b/misc/examples/scheduler.c
@@ -0,0 +1,76 @@
+// https://www.youtube.com/watch?v=8sEe-4tig_A
+#include <stdio.h>
+#include <stc/calgo.h>
+
+struct Scheduler;
+struct Task {
+ bool (*resume)(struct Task*);
+ struct Scheduler* sched;
+ int cco_state;
+};
+
+#define i_type Scheduler
+#define i_val struct Task
+#define i_no_cmp
+#include <stc/clist.h>
+
+static bool schedule(Scheduler* sched)
+{
+ struct Task task = *Scheduler_front(sched);
+ Scheduler_pop_front(sched);
+
+ if (cco_alive(&task))
+ task.resume(&task);
+
+ return !Scheduler_empty(sched);
+}
+
+static bool resume_task(const struct Task* task)
+{
+ Scheduler_push_back(task->sched, *task);
+ return false;
+}
+
+
+static bool taskA(struct Task* task)
+{
+ cco_begin(task);
+ puts("Hello, from task A");
+ cco_yield(resume_task(task));
+ puts("A is back doing work");
+ cco_yield(resume_task(task));
+ puts("A is back doing more work");
+ cco_yield(resume_task(task));
+ puts("A is back doing even more work");
+ cco_final:
+ cco_end(true);
+}
+
+static bool taskB(struct Task* task)
+{
+ cco_begin(task);
+ puts("Hello, from task B");
+ cco_yield(resume_task(task));
+ puts("B is back doing work");
+ cco_yield(resume_task(task));
+ puts("B is back doing more work");
+ cco_final:
+ cco_end(true);
+}
+
+void Use(void)
+{
+ Scheduler scheduler = c_make(Scheduler, {
+ {taskA, &scheduler},
+ {taskB, &scheduler},
+ });
+
+ while (schedule(&scheduler)) {}
+
+ Scheduler_drop(&scheduler);
+}
+
+int main()
+{
+ Use();
+}
diff --git a/misc/examples/triples.c b/misc/examples/triples.c
index 520bf012..2e0211c3 100644
--- a/misc/examples/triples.c
+++ b/misc/examples/triples.c
@@ -23,13 +23,13 @@ struct triples {
int cco_state;
};
-bool triples_next(struct triples* I) {
+bool triples_coro(struct triples* I) {
cco_begin(I);
for (I->c = 5; I->n; ++I->c) {
for (I->a = 1; I->a < I->c; ++I->a) {
for (I->b = I->a + 1; I->b < I->c; ++I->b) {
if ((int64_t)I->a*I->a + (int64_t)I->b*I->b == (int64_t)I->c*I->c) {
- cco_yield(true);
+ cco_yield(false);
if (--I->n == 0) cco_return;
}
}
@@ -37,7 +37,7 @@ bool triples_next(struct triples* I) {
}
cco_final:
puts("done");
- cco_end(false);
+ cco_end(true);
}
int gcd(int a, int b) {
@@ -58,7 +58,7 @@ int main()
struct triples t = {INT32_MAX};
int n = 0;
- while (triples_next(&t)) {
+ while (!triples_coro(&t)) {
if (gcd(t.a, t.b) > 1)
continue;
if (t.c < 100)