summaryrefslogtreecommitdiffhomepage
path: root/misc/examples/coroutines/cotasks2.c
diff options
context:
space:
mode:
authortylov <[email protected]>2023-07-20 15:09:10 +0200
committertylov <[email protected]>2023-07-20 15:12:29 +0200
commit900295256d825fc323149cd223c49787f32a3696 (patch)
tree6c79cf4209e3975bb6865e2940b9cb56ea469c73 /misc/examples/coroutines/cotasks2.c
parent224a04f7fa7549ed94d2a1415eb25829e39a7cca (diff)
downloadSTC-modified-900295256d825fc323149cd223c49787f32a3696.tar.gz
STC-modified-900295256d825fc323149cd223c49787f32a3696.zip
Moved examples to sub-directories. Added cotask1.c cotask2.c examples.
Diffstat (limited to 'misc/examples/coroutines/cotasks2.c')
-rw-r--r--misc/examples/coroutines/cotasks2.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/misc/examples/coroutines/cotasks2.c b/misc/examples/coroutines/cotasks2.c
new file mode 100644
index 00000000..293583bc
--- /dev/null
+++ b/misc/examples/coroutines/cotasks2.c
@@ -0,0 +1,103 @@
+// https://mariusbancila.ro/blog/2020/06/22/a-cpp20-coroutine-example/
+
+#include <time.h>
+#include <stdio.h>
+#define i_static
+#include <stc/cstr.h>
+#include <stc/algo/coroutine.h>
+
+cco_task_struct (next_value,
+ int val;
+ cco_timer tm;
+);
+
+int next_value(struct next_value* co, cco_runtime* rt)
+{
+ cco_routine (co) {
+ while (true) {
+ cco_timer_await(&co->tm, 1 + rand() % 2);
+ co->val = rand();
+ cco_yield();
+ }
+ }
+ return 0;
+}
+
+void print_time()
+{
+ time_t now = time(NULL);
+ char mbstr[64];
+ strftime(mbstr, sizeof(mbstr), "[%H:%M:%S]", localtime(&now));
+ printf("%s ", mbstr);
+}
+
+// PRODUCER
+
+cco_task_struct (produce_items,
+ struct next_value next;
+ cstr str;
+);
+
+int produce_items(struct produce_items* p, cco_runtime* rt)
+{
+ cco_routine (p) {
+ p->str = cstr_null;
+ while (true)
+ {
+ // await for next CCO_YIELD in next_value()
+ cco_await_task(&p->next, rt, CCO_YIELD);
+ cstr_printf(&p->str, "item %d", p->next.val);
+ print_time();
+ printf("produced %s\n", cstr_str(&p->str));
+ cco_yield();
+ }
+ cco_cleanup:
+ cstr_drop(&p->str);
+ puts("done produce");
+ }
+ return 0;
+}
+
+// CONSUMER
+
+cco_task_struct (consume_items,
+ int n, i;
+ struct produce_items produce;
+);
+
+int consume_items(struct consume_items* c, cco_runtime* rt)
+{
+ cco_routine (c) {
+ for (c->i = 1; c->i <= c->n; ++c->i)
+ {
+ printf("consume #%d\n", c->i);
+ cco_await_task(&c->produce, rt, CCO_YIELD);
+ print_time();
+ printf("consumed %s\n", cstr_str(&c->produce.str));
+ }
+ cco_cleanup:
+ cco_stop(&c->produce);
+ cco_resume(&c->produce, rt);
+ puts("done consume");
+ }
+ return 0;
+}
+
+int main(void)
+{
+ struct consume_items consume = {
+ .n=5,
+ .cco_fn=consume_items,
+ .produce={.cco_fn=produce_items, .next={.cco_fn=next_value}},
+ };
+ int count = 0;
+
+ cco_block_task(&consume)
+ {
+ ++count;
+ //cco_sleep(0.001);
+ //if (consume.i == 3)
+ // cco_stop(&consume);
+ }
+ printf("count: %d\n", count);
+} \ No newline at end of file