diff options
| -rw-r--r-- | docs/coroutine_api.md | 12 | ||||
| -rw-r--r-- | include/stc/cmap.h | 16 | ||||
| -rw-r--r-- | include/stc/coroutine.h | 5 | ||||
| -rw-r--r-- | include/stc/forward.h | 6 | ||||
| -rw-r--r-- | include/stc/priv/cqueue_hdr.h | 4 | ||||
| -rw-r--r-- | misc/examples/coroutines/coread.c | 2 | ||||
| -rw-r--r-- | misc/examples/coroutines/coroutines.c | 6 | ||||
| -rw-r--r-- | misc/examples/coroutines/cotasks1.c | 4 | ||||
| -rw-r--r-- | misc/examples/coroutines/cotasks2.c | 4 | ||||
| -rw-r--r-- | misc/examples/coroutines/dining_philosophers.c | 4 | ||||
| -rw-r--r-- | misc/examples/coroutines/filetask.c | 4 | ||||
| -rw-r--r-- | misc/examples/coroutines/generator.c | 28 | ||||
| -rw-r--r-- | misc/examples/coroutines/triples.c | 2 |
13 files changed, 54 insertions, 43 deletions
diff --git a/docs/coroutine_api.md b/docs/coroutine_api.md index b356dcf0..6bd558f2 100644 --- a/docs/coroutine_api.md +++ b/docs/coroutine_api.md @@ -16,7 +16,7 @@ NB! ***cco_yield\*()*** / ***cco_await\*()*** may not be called from within a `s | | Function / operator | Description | |:----------|:-------------------------------------|:----------------------------------------| |`cco_result` | `CCO_DONE`, `CCO_AWAIT`, `CCO_YIELD` | Default set of return values from coroutines | -| | `cco_cleanup:` | Label for cleanup position in coroutine | +| | `cco_final:` | Label for cleanup position in coroutine | | `bool` | `cco_done(co)` | Is coroutine done? | | | `cco_routine(co) {}` | The coroutine scope | | | `cco_yield();` | Yield/suspend execution (return CCO_YIELD)| @@ -101,13 +101,13 @@ int triples(struct triples* i) { (int64_t)i->c * i->c) { if (i->c > i->max_c) - cco_return; // "jump" to cco_cleanup if defined, else exit scope. + cco_return; // "jump" to cco_final if defined, else exit scope. cco_yield(); } } } } - cco_cleanup: + cco_final: puts("done"); } return 0; // CCO_DONE @@ -160,7 +160,7 @@ int gcd1_triples(struct gcd1_triples* i) else cco_yield(); } - cco_cleanup: + cco_final: cco_stop(&i->tri); // to cleanup state if still active triples(&i->tri); // do cleanup (or no-op if done) } @@ -248,7 +248,7 @@ int produce_items(struct produce_items* p, cco_runtime* rt) printf("produced %s\n", cstr_str(&p->str)); cco_yield(); } - cco_cleanup: + cco_final: cstr_drop(&p->str); puts("done produce"); } @@ -273,7 +273,7 @@ int consume_items(struct consume_items* c, cco_runtime* rt) print_time(); printf("consumed %s\n", cstr_str(&c->produce.str)); } - cco_cleanup: + cco_final: cco_stop(&c->produce); cco_resume_task(&c->produce, rt); puts("done consume"); diff --git a/include/stc/cmap.h b/include/stc/cmap.h index cd7430ba..e0134964 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -306,7 +306,7 @@ STC_INLINE void _cx_MEMB(_wipe_)(_cx_Self* self) { if (self->size == 0) return; _cx_value* d = self->data, *_end = d + self->bucket_count; - chash_slot* s = self->slot; + struct chash_slot* s = self->slot; for (; d != _end; ++d) if ((s++)->hashx) _cx_MEMB(_value_drop)(d); @@ -321,7 +321,7 @@ STC_DEF void _cx_MEMB(_drop)(_cx_Self* self) { STC_DEF void _cx_MEMB(_clear)(_cx_Self* self) { _cx_MEMB(_wipe_)(self); self->size = 0; - c_memset(self->slot, 0, c_sizeof(chash_slot)*self->bucket_count); + c_memset(self->slot, 0, c_sizeof(struct chash_slot)*self->bucket_count); } #ifdef _i_ismap @@ -359,7 +359,7 @@ _cx_MEMB(_bucket_)(const _cx_Self* self, const _cx_keyraw* rkeyptr) { intptr_t _cap = self->bucket_count; intptr_t _idx = fastrange_2(_hash, _cap); _cx_result b = {NULL, true, (uint8_t)(_hash | 0x80)}; - const chash_slot* s = self->slot; + const struct chash_slot* s = self->slot; while (s[_idx].hashx) { if (s[_idx].hashx == b.hashx) { const _cx_keyraw _raw = i_keyto(_i_keyref(self->data + _idx)); @@ -394,8 +394,8 @@ _cx_MEMB(_clone)(_cx_Self m) { if (m.data) { _cx_value *d = (_cx_value *)i_malloc(c_sizeof(_cx_value)*m.bucket_count), *_dst = d, *_end = m.data + m.bucket_count; - const intptr_t _mem = c_sizeof(chash_slot)*(m.bucket_count + 1); - chash_slot *s = (chash_slot *)c_memcpy(i_malloc(_mem), m.slot, _mem); + const intptr_t _mem = c_sizeof(struct chash_slot)*(m.bucket_count + 1); + struct chash_slot *s = (struct chash_slot *)c_memcpy(i_malloc(_mem), m.slot, _mem); if (!(d && s)) { i_free(d), i_free(s), d = 0, s = 0, m.bucket_count = 0; } else @@ -417,14 +417,14 @@ _cx_MEMB(_reserve)(_cx_Self* self, const intptr_t _newcap) { _newbucks = cnextpow2(_newbucks); _cx_Self m = { (_cx_value *)i_malloc(_newbucks*c_sizeof(_cx_value)), - (chash_slot *)i_calloc(_newbucks + 1, sizeof(chash_slot)), + (struct chash_slot *)i_calloc(_newbucks + 1, sizeof(struct chash_slot)), self->size, _newbucks }; bool ok = m.data && m.slot; if (ok) { // Rehash: m.slot[_newbucks].hashx = 0xff; const _cx_value* d = self->data; - const chash_slot* s = self->slot; + const struct chash_slot* s = self->slot; for (intptr_t i = 0; i < _oldbucks; ++i, ++d) if ((s++)->hashx) { _cx_keyraw r = i_keyto(_i_keyref(d)); _cx_result b = _cx_MEMB(_bucket_)(&m, &r); @@ -441,7 +441,7 @@ _cx_MEMB(_reserve)(_cx_Self* self, const intptr_t _newcap) { STC_DEF void _cx_MEMB(_erase_entry)(_cx_Self* self, _cx_value* _val) { _cx_value* d = self->data; - chash_slot* s = self->slot; + struct chash_slot* s = self->slot; intptr_t i = _val - d, j = i, k; const intptr_t _cap = self->bucket_count; _cx_MEMB(_value_drop)(_val); diff --git a/include/stc/coroutine.h b/include/stc/coroutine.h index 0e592bae..cecd4002 100644 --- a/include/stc/coroutine.h +++ b/include/stc/coroutine.h @@ -38,7 +38,7 @@ int iterpair(struct iterpair* I) { for (I->y = 0; I->y < I->max_y; I->y++) cco_yield(); - cco_cleanup: // required if there is cleanup code + cco_final: // required if there is cleanup code puts("final"); } return 0; // CCO_DONE @@ -103,7 +103,8 @@ typedef enum { /* cco_blocking_call(): assumes coroutine returns a cco_result value (int) */ #define cco_blocking_call(corocall) while ((corocall) != CCO_DONE) -#define cco_cleanup \ +#define cco_cleanup cco_final // [deprecated] +#define cco_final \ *_state = CCO_STATE_CLEANUP; case CCO_STATE_CLEANUP #define cco_return \ diff --git a/include/stc/forward.h b/include/stc/forward.h index 085205cf..572a319f 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -107,8 +107,6 @@ typedef union { SELF##_node *last; \ } SELF -typedef struct chash_slot chash_slot; - #define _c_chash_types(SELF, KEY, VAL, MAP_ONLY, SET_ONLY) \ typedef KEY SELF##_key; \ typedef VAL SELF##_mapped; \ @@ -125,12 +123,12 @@ typedef struct chash_slot chash_slot; \ typedef struct { \ SELF##_value *ref, *_end; \ - chash_slot* sref; \ + struct chash_slot* sref; \ } SELF##_iter; \ \ typedef struct SELF { \ SELF##_value* data; \ - chash_slot* slot; \ + struct chash_slot* slot; \ intptr_t size, bucket_count; \ } SELF diff --git a/include/stc/priv/cqueue_hdr.h b/include/stc/priv/cqueue_hdr.h index 90539f36..1cad8684 100644 --- a/include/stc/priv/cqueue_hdr.h +++ b/include/stc/priv/cqueue_hdr.h @@ -96,8 +96,8 @@ STC_INLINE void _cx_MEMB(_copy)(_cx_Self* self, const _cx_Self* other) { STC_INLINE _cx_iter _cx_MEMB(_begin)(const _cx_Self* self) { return c_LITERAL(_cx_iter){ - _cx_MEMB(_empty)(self) ? NULL : self->data + self->start, - self->start, self + .ref=_cx_MEMB(_empty)(self) ? NULL : self->data + self->start, + .pos=self->start, ._s=self }; } diff --git a/misc/examples/coroutines/coread.c b/misc/examples/coroutines/coread.c index 359ca85d..6d3acdd7 100644 --- a/misc/examples/coroutines/coread.c +++ b/misc/examples/coroutines/coread.c @@ -21,7 +21,7 @@ int file_read(struct file_read* g) cco_await(!cstr_getline(&g->line, g->fp)); - cco_cleanup: + cco_final: printf("finish\n"); cstr_drop(&g->line); if (g->fp) fclose(g->fp); diff --git a/misc/examples/coroutines/coroutines.c b/misc/examples/coroutines/coroutines.c index faeb71f6..802a976a 100644 --- a/misc/examples/coroutines/coroutines.c +++ b/misc/examples/coroutines/coroutines.c @@ -34,7 +34,7 @@ int prime(struct prime* g) { cco_yield(); } } - cco_cleanup: + cco_final: printf("final prm\n"); } return 0; @@ -68,7 +68,7 @@ int fibonacci(struct fibonacci* g) { } cco_yield(); } - cco_cleanup: + cco_final: printf("final fib\n"); } return 0; @@ -92,7 +92,7 @@ int combined(struct combined* g) { cco_reset(&g->prm); cco_await_call(prime(&g->prm)); - cco_cleanup: + cco_final: puts("final combined"); } return 0; diff --git a/misc/examples/coroutines/cotasks1.c b/misc/examples/coroutines/cotasks1.c index 230bd62b..7df4eb34 100644 --- a/misc/examples/coroutines/cotasks1.c +++ b/misc/examples/coroutines/cotasks1.c @@ -52,7 +52,7 @@ int produce_items(struct produce_items* p) printf("produced %s\n", cstr_str(&p->str)); cco_yield(); } - cco_cleanup: + cco_final: cstr_drop(&p->str); puts("done produce"); } @@ -76,7 +76,7 @@ int consume_items(struct consume_items* c, struct produce_items* p) print_time(); printf("consumed %s\n", cstr_str(&p->str)); } - cco_cleanup: + cco_final: puts("done consume"); } return 0; diff --git a/misc/examples/coroutines/cotasks2.c b/misc/examples/coroutines/cotasks2.c index d77a28bc..f6257a7e 100644 --- a/misc/examples/coroutines/cotasks2.c +++ b/misc/examples/coroutines/cotasks2.c @@ -53,7 +53,7 @@ int produce_items(struct produce_items* p, cco_runtime* rt) cco_yield(); } - cco_cleanup: + cco_final: cstr_drop(&p->str); puts("done produce"); } @@ -80,7 +80,7 @@ int consume_items(struct consume_items* c, cco_runtime* rt) printf("consumed %s\n", cstr_str(&c->produce.str)); } - cco_cleanup: + cco_final: cco_stop(&c->produce); cco_resume_task(&c->produce, rt); puts("done consume"); diff --git a/misc/examples/coroutines/dining_philosophers.c b/misc/examples/coroutines/dining_philosophers.c index e917c303..d353b3b9 100644 --- a/misc/examples/coroutines/dining_philosophers.c +++ b/misc/examples/coroutines/dining_philosophers.c @@ -48,7 +48,7 @@ int philosopher(struct Philosopher* p) cco_sem_release(p->right_fork); } - cco_cleanup: + cco_final: printf("Philosopher %d finished\n", p->id); } return 0; @@ -76,7 +76,7 @@ int dining(struct Dining* d) cco_yield(); // suspend, return control back to main } - cco_cleanup: + cco_final: for (int i = 0; i < num_philosophers; ++i) { cco_stop(&d->ph[i]); philosopher(&d->ph[i]); diff --git a/misc/examples/coroutines/filetask.c b/misc/examples/coroutines/filetask.c index 0607442d..74388359 100644 --- a/misc/examples/coroutines/filetask.c +++ b/misc/examples/coroutines/filetask.c @@ -28,7 +28,7 @@ int file_read(struct file_read* co, cco_runtime* rt) cco_yield(); } - cco_cleanup: + cco_final: fclose(co->fp); cstr_drop(&co->line); puts("done file_read"); @@ -56,7 +56,7 @@ int count_line(struct count_line* co, cco_runtime* rt) cco_yield(); } - cco_cleanup: + cco_final: cstr_drop(&co->path); puts("done count_line"); } diff --git a/misc/examples/coroutines/generator.c b/misc/examples/coroutines/generator.c index 3f51ce9c..96498498 100644 --- a/misc/examples/coroutines/generator.c +++ b/misc/examples/coroutines/generator.c @@ -2,12 +2,15 @@ #include <stdio.h> #include <stc/coroutine.h> +#include <stc/algorithm.h> typedef struct { - int size; + int max_triples; int a, b, c; } Triple; +// Create an iterable generator over Triple with count items. +// Requires coroutine Triple_next() and function Triple_begin() to be defined. cco_iter_struct(Triple, int count; ); @@ -20,16 +23,15 @@ int Triple_next(Triple_iter* it) { for (g->a = 1; g->a < g->c; ++g->a) { for (g->b = g->a; g->b < g->c; ++g->b) { if (g->a*g->a + g->b*g->b == g->c*g->c) { - if (it->count++ == g->size) + if (it->count++ == g->max_triples) cco_return; cco_yield(); } } } } - cco_cleanup: - it->ref = NULL; - puts("done"); + cco_final: + it->ref = NULL; // stop the iterator } return 0; } @@ -43,12 +45,22 @@ Triple_iter Triple_begin(Triple* g) { int main(void) { - puts("Pythagorean triples; stops at 100 triples or c >= 100:"); - Triple triple = {.size=100}; + puts("Pythagorean triples.\nGet max 200 triples with c < 50:"); + Triple triple = {.max_triples=200}; + c_foreach (i, Triple, triple) { - if (i.ref->c < 100) + if (i.ref->c < 50) printf("%u: (%d, %d, %d)\n", i.count, i.ref->a, i.ref->b, i.ref->c); else cco_stop(&i); } + + puts("\nGet the 10 first triples with odd a's and a <= 20:"); + c_forfilter (i, Triple, triple, + i.ref->a <= 20 && + (i.ref->a & 1) && + c_flt_take(i, 10) + ){ + printf("%d: (%d, %d, %d)\n", c_flt_getcount(i), i.ref->a, i.ref->b, i.ref->c); + } } diff --git a/misc/examples/coroutines/triples.c b/misc/examples/coroutines/triples.c index 22914c2b..d6ce2791 100644 --- a/misc/examples/coroutines/triples.c +++ b/misc/examples/coroutines/triples.c @@ -40,7 +40,7 @@ int triples_coro(struct triples* t) { } } } - cco_cleanup: + cco_final: puts("done"); } return 0; |
