summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-08-08 12:28:15 +0200
committerTyge Løvset <[email protected]>2023-08-08 15:57:25 +0200
commitc27c266b6c4ae0e5e535b18c3790ee97416412b9 (patch)
tree0b73c9cf644486abbc9213f98c1c308b7511c7dc
parent9e13d34c82abfeeadcc8697331f9fd3e5e7f2bca (diff)
downloadSTC-modified-c27c266b6c4ae0e5e535b18c3790ee97416412b9.tar.gz
STC-modified-c27c266b6c4ae0e5e535b18c3790ee97416412b9.zip
Reverted cco_cleanup => cco_final. (cco_cleanup deprecated).
Updated generator.c example. Misc internal refactoring.
-rw-r--r--docs/coroutine_api.md12
-rw-r--r--include/stc/cmap.h16
-rw-r--r--include/stc/coroutine.h5
-rw-r--r--include/stc/forward.h6
-rw-r--r--include/stc/priv/cqueue_hdr.h4
-rw-r--r--misc/examples/coroutines/coread.c2
-rw-r--r--misc/examples/coroutines/coroutines.c6
-rw-r--r--misc/examples/coroutines/cotasks1.c4
-rw-r--r--misc/examples/coroutines/cotasks2.c4
-rw-r--r--misc/examples/coroutines/dining_philosophers.c4
-rw-r--r--misc/examples/coroutines/filetask.c4
-rw-r--r--misc/examples/coroutines/generator.c28
-rw-r--r--misc/examples/coroutines/triples.c2
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;