summaryrefslogtreecommitdiffhomepage
path: root/misc/examples/coroutines/cotasks2.c
diff options
context:
space:
mode:
author_Tradam <[email protected]>2023-09-08 01:29:47 +0000
committerGitHub <[email protected]>2023-09-08 01:29:47 +0000
commit3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd (patch)
treeafbe4b540967223911f7c5de36559b82154f02f3 /misc/examples/coroutines/cotasks2.c
parent0841165881871ee01b782129be681209aeed2423 (diff)
parent1a72205fe05c2375cfd380dd8381a8460d9ed8d1 (diff)
downloadSTC-modified-3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd.tar.gz
STC-modified-3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd.zip
Merge branch 'stclib:master' into modifiedHEADmodified
Diffstat (limited to 'misc/examples/coroutines/cotasks2.c')
-rw-r--r--misc/examples/coroutines/cotasks2.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/misc/examples/coroutines/cotasks2.c b/misc/examples/coroutines/cotasks2.c
new file mode 100644
index 00000000..558df118
--- /dev/null
+++ b/misc/examples/coroutines/cotasks2.c
@@ -0,0 +1,98 @@
+// 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/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_await_timer(&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 text;
+);
+
+int produce_items(struct produce_items* p, cco_runtime* rt)
+{
+ cco_routine (p) {
+ p->text = cstr_init();
+ p->next.cco_func = next_value;
+ while (true)
+ {
+ // await for next CCO_YIELD (or CCO_DONE) in next_value
+ cco_await_task(&p->next, rt, CCO_YIELD);
+ cstr_printf(&p->text, "item %d", p->next.val);
+ print_time();
+ printf("produced %s\n", cstr_str(&p->text));
+ cco_yield();
+ }
+
+ cco_final:
+ cstr_drop(&p->text);
+ 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) {
+ c->produce.cco_func = produce_items;
+
+ 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.text));
+ }
+
+ cco_final:
+ cco_stop(&c->produce);
+ cco_resume_task(&c->produce, rt);
+ puts("done consume");
+ }
+ return 0;
+}
+
+int main(void)
+{
+ struct consume_items consume = {
+ .cco_func = consume_items,
+ .n = 5,
+ };
+ cco_blocking_task(&consume);
+}