summaryrefslogtreecommitdiffhomepage
path: root/misc/examples
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-07-02 22:01:46 +0200
committerTyge Løvset <[email protected]>2023-07-02 23:18:10 +0200
commite25dec033773ab713a7593a923e2c83745be0b9a (patch)
tree174c9edfee09fb90b18ac17661cc9a8f291fa83c /misc/examples
parentfc43b14f706f22e3933b3d225819ea68f7ce2679 (diff)
downloadSTC-modified-e25dec033773ab713a7593a923e2c83745be0b9a.tar.gz
STC-modified-e25dec033773ab713a7593a923e2c83745be0b9a.zip
Update in coroutine API. cco_yield, cco_await, cco_await_on, cco_block_on has changed. cco_final: renamed => cco_cleanup:
Reverted i_retain template param back to => i_more.
Diffstat (limited to 'misc/examples')
-rw-r--r--misc/examples/cointerleave.c11
-rw-r--r--misc/examples/coread.c7
-rw-r--r--misc/examples/coroutines.c54
-rw-r--r--misc/examples/dining_philosophers.c16
-rw-r--r--misc/examples/generator.c5
-rw-r--r--misc/examples/scheduler.c34
-rw-r--r--misc/examples/triples.c10
7 files changed, 73 insertions, 64 deletions
diff --git a/misc/examples/cointerleave.c b/misc/examples/cointerleave.c
index 1ba7b861..61562a5f 100644
--- a/misc/examples/cointerleave.c
+++ b/misc/examples/cointerleave.c
@@ -15,7 +15,7 @@ static int get_value(struct GenValue* g)
{
cco_routine(g) {
for (g->it = IVec_begin(g->v); g->it.ref; IVec_next(&g->it))
- cco_yield(*g->it.ref);
+ cco_yield_v(*g->it.ref);
}
return -1;
}
@@ -26,10 +26,10 @@ struct Generator {
int value;
};
-void interleaved(struct Generator* g)
+cco_result interleaved(struct Generator* g)
{
cco_routine(g) {
- do {
+ while (!(cco_done(&g->x) & cco_done(&g->y))) {
g->value = get_value(&g->x);
if (!cco_done(&g->x))
cco_yield();
@@ -37,8 +37,9 @@ void interleaved(struct Generator* g)
g->value = get_value(&g->y);
if (!cco_done(&g->y))
cco_yield();
- } while (!(cco_done(&g->x) & cco_done(&g->y)));
+ }
}
+ return CCO_DONE;
}
void Use(void)
@@ -48,7 +49,7 @@ void Use(void)
struct Generator g = {{&a}, {&b}};
- cco_block_on(&g, interleaved) {
+ cco_block_on(interleaved(&g)) {
printf("%d ", g.value);
}
puts("");
diff --git a/misc/examples/coread.c b/misc/examples/coread.c
index 622228c0..a13f6be5 100644
--- a/misc/examples/coread.c
+++ b/misc/examples/coread.c
@@ -12,7 +12,7 @@ struct file_read {
cstr line;
};
-void file_read(struct file_read* g)
+int file_read(struct file_read* g)
{
cco_routine(g) {
g->fp = fopen(g->filename, "r");
@@ -21,18 +21,19 @@ void file_read(struct file_read* g)
cco_await(!cstr_getline(&g->line, g->fp));
- cco_final:
+ cco_cleanup:
printf("finish\n");
cstr_drop(&g->line);
if (g->fp) fclose(g->fp);
}
+ return 0;
}
int main(void)
{
struct file_read g = {__FILE__};
int n = 0;
- cco_block_on(&g, file_read)
+ cco_block_on(file_read(&g))
{
printf("%3d %s\n", ++n, cstr_str(&g.line));
//if (n == 10) cco_stop(&g);
diff --git a/misc/examples/coroutines.c b/misc/examples/coroutines.c
index 1e900fa1..b8dfaa13 100644
--- a/misc/examples/coroutines.c
+++ b/misc/examples/coroutines.c
@@ -4,27 +4,26 @@
// Demonstrate to call another coroutine from a coroutine:
// First create prime generator, then call fibonacci sequence:
-typedef long long llong;
-bool is_prime(int64_t i) {
- for (llong j=2; j*j <= i; ++j)
+bool is_prime(long long i) {
+ for (long long j=2; j*j <= i; ++j)
if (i % j == 0) return false;
return true;
}
struct prime {
int count, idx;
- llong result, pos;
+ long long result, pos;
int cco_state;
};
-bool prime(struct prime* g) {
+int prime(struct prime* g) {
cco_routine(g) {
if (g->result < 2) g->result = 2;
if (g->result == 2) {
if (g->count-- == 0) cco_return;
++g->idx;
- cco_yield(false);
+ cco_yield();
}
g->result += !(g->result & 1);
for (g->pos = g->result; g->count > 0; g->pos += 2) {
@@ -32,13 +31,13 @@ bool prime(struct prime* g) {
--g->count;
++g->idx;
g->result = g->pos;
- cco_yield(false);
+ cco_yield();
}
}
- cco_final:
+ cco_cleanup:
printf("final prm\n");
}
- return true;
+ return 0;
}
@@ -46,13 +45,14 @@ bool prime(struct prime* g) {
struct fibonacci {
int count, idx;
- llong result, b;
+ long long result, b;
int cco_state;
};
-bool fibonacci(struct fibonacci* g) {
+int fibonacci(struct fibonacci* g) {
assert(g->count < 94);
+ long long sum;
cco_routine(g) {
g->idx = 0;
g->result = 0;
@@ -61,17 +61,17 @@ bool fibonacci(struct fibonacci* g) {
if (g->count-- == 0)
cco_return;
if (++g->idx > 1) {
- // NB! locals lasts only until next cco_yield/cco_await!
- llong sum = g->result + g->b;
+ // NB! locals lasts only until next yield/await!
+ sum = g->result + g->b;
g->result = g->b;
g->b = sum;
}
- cco_yield(false);
+ cco_yield();
}
- cco_final:
+ cco_cleanup:
printf("final fib\n");
}
- return true;
+ return 0;
}
// Combine
@@ -82,29 +82,31 @@ struct combined {
int cco_state;
};
-
-void combined(struct combined* g) {
+int combined(struct combined* g) {
cco_routine(g) {
- cco_await(prime(&g->prm));
- cco_await(fibonacci(&g->fib));
+ cco_await_on(prime(&g->prm));
+ cco_await_on(fibonacci(&g->fib));
// Reuse the g->prm context and extend the count:
g->prm.count = 8, g->prm.result += 2;
cco_reset(&g->prm);
- cco_await(prime(&g->prm));
+ cco_await_on(prime(&g->prm));
- cco_final:
+ cco_cleanup:
puts("final combined");
}
+ return 0;
}
int main(void)
{
struct combined c = {.prm={.count=8}, .fib={14}};
+ int res;
- cco_block_on(&c, combined) {
- printf("Prime(%d)=%lld, Fib(%d)=%lld\n",
- c.prm.idx, c.prm.result,
- c.fib.idx, c.fib.result);
+ cco_block_on(combined(&c), &res) {
+ if (res == CCO_YIELD)
+ printf("Prime(%d)=%lld, Fib(%d)=%lld\n",
+ c.prm.idx, c.prm.result,
+ c.fib.idx, c.fib.result);
}
}
diff --git a/misc/examples/dining_philosophers.c b/misc/examples/dining_philosophers.c
index e13eb055..61fe67fb 100644
--- a/misc/examples/dining_philosophers.c
+++ b/misc/examples/dining_philosophers.c
@@ -27,7 +27,7 @@ struct Dining {
// Philosopher coroutine
-void philosopher(struct Philosopher* p)
+int philosopher(struct Philosopher* p)
{
double duration;
cco_routine(p) {
@@ -48,14 +48,15 @@ void philosopher(struct Philosopher* p)
cco_sem_release(p->right_fork);
}
- cco_final:
+ cco_cleanup:
printf("Philosopher %d finished\n", p->id);
}
+ return 0;
}
// Dining coroutine
-void dining(struct Dining* d)
+int dining(struct Dining* d)
{
cco_routine(d) {
for (int i = 0; i < num_forks; ++i)
@@ -68,20 +69,21 @@ void dining(struct Dining* d)
}
while (1) {
- // per-"frame" logic update of all philosophers states
+ // per-"frame" logic resume each philosopher
for (int i = 0; i < num_philosophers; ++i) {
philosopher(&d->ph[i]);
}
cco_yield(); // suspend, return control back to main
}
- cco_final:
+ cco_cleanup:
for (int i = 0; i < num_philosophers; ++i) {
cco_stop(&d->ph[i]);
philosopher(&d->ph[i]);
}
puts("Dining finished");
}
+ return 0;
}
int main()
@@ -89,13 +91,13 @@ int main()
struct Dining dine;
cco_reset(&dine);
int n=0;
- cco_timer tm = cco_timer_from(10.0); // seconds
+ cco_timer tm = cco_timer_from(15.0); // seconds
csrand((uint64_t)time(NULL));
while (!cco_done(&dine)) {
if (cco_timer_expired(&tm))
cco_stop(&dine);
- dining(&dine);
+ dining(&dine); // resume
cco_sleep(0.001);
++n;
}
diff --git a/misc/examples/generator.c b/misc/examples/generator.c
index 6b4b8407..3ff7a645 100644
--- a/misc/examples/generator.c
+++ b/misc/examples/generator.c
@@ -14,7 +14,7 @@ typedef struct {
int cco_state;
} Triple_iter;
-void Triple_next(Triple_iter* it) {
+int Triple_next(Triple_iter* it) {
Triple_value* g = it->ref;
cco_routine(it)
{
@@ -29,9 +29,10 @@ void Triple_next(Triple_iter* it) {
}
}
}
- cco_final:
+ cco_cleanup:
it->ref = NULL;
}
+ return 0;
}
Triple_iter Triple_begin(Triple* g) {
diff --git a/misc/examples/scheduler.c b/misc/examples/scheduler.c
index 04f7ba4a..c1168850 100644
--- a/misc/examples/scheduler.c
+++ b/misc/examples/scheduler.c
@@ -2,9 +2,11 @@
#include <stdio.h>
#include <stc/calgo.h>
-cco_closure(bool, Task,
+struct Task {
+ int (*fn)(struct Task*);
+ int cco_state;
struct Scheduler* sched;
-);
+};
#define i_type Scheduler
#define i_val struct Task
@@ -16,49 +18,49 @@ static bool schedule(Scheduler* sched)
Scheduler_pop(sched);
if (!cco_done(&task))
- cco_resume(&task);
+ task.fn(&task);
return !Scheduler_empty(sched);
}
-static bool push_task(const struct Task* task)
+static int push_task(const struct Task* task)
{
Scheduler_push(task->sched, *task);
- return false;
+ return CCO_YIELD;
}
-static bool taskA(struct Task* task)
+static int taskA(struct Task* task)
{
cco_routine(task) {
puts("Hello, from task A");
- cco_yield(push_task(task));
+ cco_yield_v(push_task(task));
puts("A is back doing work");
- cco_yield(push_task(task));
+ cco_yield_v(push_task(task));
puts("A is back doing more work");
- cco_yield(push_task(task));
+ cco_yield_v(push_task(task));
puts("A is back doing even more work");
}
- return true;
+ return 0;
}
-static bool taskB(struct Task* task)
+static int taskB(struct Task* task)
{
cco_routine(task) {
puts("Hello, from task B");
- cco_yield(push_task(task));
+ cco_yield_v(push_task(task));
puts("B is back doing work");
- cco_yield(push_task(task));
+ cco_yield_v(push_task(task));
puts("B is back doing more work");
}
- return true;
+ return 0;
}
void Use(void)
{
Scheduler scheduler = c_init(Scheduler, {
- {.cco_fn=taskA, .sched=&scheduler},
- {.cco_fn=taskB, .sched=&scheduler},
+ {.fn=taskA, .sched=&scheduler},
+ {.fn=taskB, .sched=&scheduler},
});
while (schedule(&scheduler)) {}
diff --git a/misc/examples/triples.c b/misc/examples/triples.c
index 17e3d40b..a8ca6b47 100644
--- a/misc/examples/triples.c
+++ b/misc/examples/triples.c
@@ -32,7 +32,7 @@ struct triples {
int cco_state;
};
-void triples_coro(struct triples* t) {
+int triples_coro(struct triples* t) {
cco_routine(t) {
t->count = 0;
for (t->c = 5; t->size; ++t->c) {
@@ -46,9 +46,10 @@ void triples_coro(struct triples* t) {
}
}
}
- cco_final:
+ cco_cleanup:
puts("done");
}
+ return 0;
}
int main()
@@ -57,11 +58,10 @@ int main()
triples_vanilla(5);
puts("\nCoroutine triples:");
- struct triples t = {INT32_MAX};
+ struct triples t = {.size=INT32_MAX};
int n = 0;
- while (!cco_done(&t)) {
- triples_coro(&t);
+ while (triples_coro(&t)) {
if (gcd(t.a, t.b) > 1)
continue;
if (t.c < 100)